Repos / s4g / ed3c27d1b6
commit ed3c27d1b69726e3643a5ba3fe95b2c48b843c13
Author: Nhân <hi@imnhan.com>
Date: Mon Jul 3 16:56:11 2023 +0700
templates for home and post
Transplanted from https://github.com/nhanb/bloghead
diff --git a/Makefile b/Makefile
index 784b3e7..2e4ac8e 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ build:
go build -o dist/
watch:
- find . -name '*.go' -or -name '*.js' | entr -rc go run .
+ find . -name '*.go' -or -name '*.js' -or -name '*.tmpl' | entr -rc go run .
# Cheating a little because the djot.js repo on github does not provide builds
update-djot:
diff --git a/main.go b/main.go
index 4f86a92..694f7e3 100644
--- a/main.go
+++ b/main.go
@@ -1,12 +1,15 @@
package main
import (
+ "bytes"
"flag"
"fmt"
+ "html/template"
"io/fs"
"net/http"
"path/filepath"
"strings"
+ "time"
"github.com/BurntSushi/toml"
"go.imnhan.com/webmaker2000/djot"
@@ -24,16 +27,18 @@ func main() {
}
fsys := WriteDirFS(absolutePath)
- meta := readSiteMetadata(fsys)
- fmt.Println("Found site:", meta)
+ site := readSiteMetadata(fsys)
+ fmt.Println("Found site:", site)
articles := findArticles(fsys)
fmt.Printf("Found %d articles:\n", len(articles))
for _, a := range articles {
fmt.Println(">", a.Path, "-", a.Meta.Title)
- a.WriteHtmlFile()
+ a.WriteHtmlFile(&site)
}
+ WriteHomePage(fsys, site, articles)
+
println("Serving local website at http://localhost:" + port)
http.Handle("/", http.FileServer(http.FS(fsys)))
err = http.ListenAndServe("127.0.0.1:"+port, nil)
@@ -43,8 +48,9 @@ func main() {
}
type SiteMetadata struct {
- Name string
- Tagline string
+ Name string
+ Tagline string
+ HomePath string
}
func readSiteMetadata(fsys WritableFS) (sm SiteMetadata) {
@@ -60,22 +66,78 @@ func readSiteMetadata(fsys WritableFS) (sm SiteMetadata) {
type Article struct {
Fs WritableFS
Path string
+ WebPath string
DjotBody string
Meta ArticleMetadata
}
-func (a *Article) WriteHtmlFile() {
- html := djot.ToHtml(a.DjotBody)
- path := strings.TrimSuffix(a.Path, DJOT_EXT) + ".html"
- err := a.Fs.WriteFile(path, html)
+type ArticleMetadata struct {
+ Title string
+ IsPage bool
+ IsDraft bool
+ CreatedAt time.Time
+}
+
+func (a *Article) WriteHtmlFile(site *SiteMetadata) {
+ // First generate the main content in html
+ contentHtml := djot.ToHtml(a.DjotBody)
+
+ // Then insert that content into the main template
+ var buf bytes.Buffer
+ tmpl := template.Must(
+ template.ParseFS(
+ a.Fs,
+ "_theme/base.tmpl",
+ "_theme/post.tmpl",
+ ),
+ )
+ err := tmpl.Execute(&buf, struct {
+ Site *SiteMetadata
+ Content template.HTML
+ Title string
+ Post *Article
+ }{
+ Site: site,
+ Content: template.HTML(contentHtml),
+ Title: a.Meta.Title,
+ Post: a,
+ })
+ if err != nil {
+ fmt.Println("Error in WriteHtmlFile:", err)
+ return
+ }
+ fullHtml := buf.String()
+
+ // Now write into an html with the same name as the original djot file
+ err = a.Fs.WriteFile(a.WebPath, fullHtml)
if err != nil {
panic(err)
}
}
-type ArticleMetadata struct {
- Title string
- IsPage bool
+func WriteHomePage(fsys WritableFS, site SiteMetadata, articles []Article) {
+ var buf bytes.Buffer
+ tmpl := template.Must(
+ template.ParseFS(
+ fsys,
+ "_theme/base.tmpl",
+ "_theme/home.tmpl",
+ ),
+ )
+ err := tmpl.Execute(&buf, struct {
+ Site *SiteMetadata
+ Title string
+ Posts []Article
+ }{
+ Site: &site,
+ Title: fmt.Sprintf("%s - %s", site.Name, site.Tagline),
+ Posts: articles,
+ })
+ if err != nil {
+ fmt.Println("Error in WriteHtmlFile:", err)
+ return
+ }
+ fsys.WriteFile("index.html", buf.String())
}
func findArticles(fsys WritableFS) (articles []Article) {
@@ -108,11 +170,11 @@ func findArticles(fsys WritableFS) (articles []Article) {
article := Article{
Fs: fsys,
Path: path,
+ WebPath: strings.TrimSuffix(path, DJOT_EXT) + ".html",
DjotBody: bodyText,
Meta: meta,
}
articles = append(articles, article)
- fmt.Printf("Found article %s - %s\n", article.Path, article.Meta.Title)
return nil
})
return articles
diff --git a/www/_theme/base.tmpl b/www/_theme/base.tmpl
new file mode 100644
index 0000000..352eca0
--- /dev/null
+++ b/www/_theme/base.tmpl
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>{{if .Title}}{{.Title}} - {{.Site.Name}}{{else}}{{.Site.Name}}{{end}}</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+ <style>
+ /* Global look and feel */
+ * {
+ box-sizing: border-box;
+ }
+ input,
+ textarea {
+ font-family: inherit;
+ font-size: inherit;
+ padding: 0.3rem;
+ }
+
+ html {
+ font-size: 100%;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ Oxygen-Sans, Cantarell, "Helvetica Neue", sans-serif;
+ max-width: 800px;
+ margin: 1rem auto;
+ }
+
+ blockquote {
+ border-left: 6px solid darkgrey;
+ background-color: #eaeaea;
+ margin: 1rem 0 1rem 5rem;
+ padding: 0.7rem 1rem;
+ }
+ blockquote p {
+ margin: 0;
+ }
+ blockquote p + p {
+ margin-top: 1rem;
+ }
+
+ pre {
+ border: 1px solid;
+ border-radius: 4px;
+ padding: 1rem;
+ overflow-x: scroll;
+ }
+
+ content > p {
+ margin: 1.7rem 0;
+ }
+
+ header h1 {
+ margin: 0;
+ }
+ header .tagline {
+ margin-top: 0;
+ }
+ header {
+ border-bottom: 2px solid black;
+ }
+ header a {
+ text-decoration: none;
+ }
+ </style>
+ </head>
+
+ <body>
+
+ <header>
+ <h1><a href="{{.Site.HomePath}}">{{.Site.Name}}</a></h1>
+ <p class="tagline">{{.Site.Tagline}}</p>
+ </header>
+
+ <main>
+ {{template "body" .}}
+ </main>
+
+ </body>
+</html>
diff --git a/www/_theme/home.tmpl b/www/_theme/home.tmpl
new file mode 100644
index 0000000..20749ec
--- /dev/null
+++ b/www/_theme/home.tmpl
@@ -0,0 +1,26 @@
+{{define "body"}}
+<p>All posts, newest first:</p>
+
+<ul>
+ {{range .Posts}}
+ {{if not .Meta.IsDraft}}
+ <li>
+ {{.Meta.CreatedAt.Local.Format "2006-01-02"}}
+ — <a href="{{.WebPath}}">{{.Meta.Title}}</a>
+ </li>
+ {{end}}
+ {{end}}
+</ul>
+
+<style>
+ ul a {
+ text-decoration: none;
+ }
+
+ ul {
+ padding: 0;
+ list-style-type: none;
+ font-size: 1.1rem;
+ }
+</style>
+{{end}}
diff --git a/www/_theme/post.tmpl b/www/_theme/post.tmpl
new file mode 100644
index 0000000..1013b00
--- /dev/null
+++ b/www/_theme/post.tmpl
@@ -0,0 +1,26 @@
+{{define "body"}}
+<h1 class="post-title">{{.Post.Meta.Title}}</h1>
+<time class="post-time" datetime="{{.Post.Meta.CreatedAt.Local.Format "2006-01-02"}}">
+ {{.Post.Meta.CreatedAt.Local.Format "Monday, 02 Jan 2006"}}
+</time>
+<content>
+{{.Content}}
+</content>
+
+<style>
+.post-title {
+ text-align: center;
+ font-size: 2rem;
+ margin-bottom: 0;
+}
+.post-time {
+ display: block;
+ text-align: center;
+}
+
+content img,
+content video {
+ max-width: 100%;
+}
+</style>
+{{end}}
diff --git a/www/about/index.html b/www/about/index.html
index c84b188..07dc9af 100644
--- a/www/about/index.html
+++ b/www/about/index.html
@@ -1,3 +1,83 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>About - My Site</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+ <style>
+
+ * {
+ box-sizing: border-box;
+ }
+ input,
+ textarea {
+ font-family: inherit;
+ font-size: inherit;
+ padding: 0.3rem;
+ }
+
+ html {
+ font-size: 100%;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ Oxygen-Sans, Cantarell, "Helvetica Neue", sans-serif;
+ max-width: 800px;
+ margin: 1rem auto;
+ }
+
+ blockquote {
+ border-left: 6px solid darkgrey;
+ background-color: #eaeaea;
+ margin: 1rem 0 1rem 5rem;
+ padding: 0.7rem 1rem;
+ }
+ blockquote p {
+ margin: 0;
+ }
+ blockquote p + p {
+ margin-top: 1rem;
+ }
+
+ pre {
+ border: 1px solid;
+ border-radius: 4px;
+ padding: 1rem;
+ overflow-x: scroll;
+ }
+
+ content > p {
+ margin: 1.7rem 0;
+ }
+
+ header h1 {
+ margin: 0;
+ }
+ header .tagline {
+ margin-top: 0;
+ }
+ header {
+ border-bottom: 2px solid black;
+ }
+ header a {
+ text-decoration: none;
+ }
+ </style>
+ </head>
+
+ <body>
+
+ <header>
+ <h1><a href="/">My Site</a></h1>
+ <p class="tagline">And it's fine.</p>
+ </header>
+
+ <main>
+
+<h1 class="post-title">About</h1>
+<time class="post-time" datetime="0001-01-01">
+ Monday, 01 Jan 0001
+</time>
+<content>
<section id="About-this-site">
<h2>About this site</h2>
<p>It’s a website.</p>
@@ -7,3 +87,27 @@ <h2>No really</h2>
<p>It really <em>is</em> a full-blown
<a href="https://motherfuckingwebsite.com/">mf-ing website</a>.</p>
</section>
+
+</content>
+
+<style>
+.post-title {
+ text-align: center;
+ font-size: 2rem;
+ margin-bottom: 0;
+}
+.post-time {
+ display: block;
+ text-align: center;
+}
+
+content img,
+content video {
+ max-width: 100%;
+}
+</style>
+
+ </main>
+
+ </body>
+</html>
diff --git a/www/hello/index.html b/www/hello/index.html
index 3217db9..363ec7d 100644
--- a/www/hello/index.html
+++ b/www/hello/index.html
@@ -1 +1,105 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>Hello - My Site</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+ <style>
+
+ * {
+ box-sizing: border-box;
+ }
+ input,
+ textarea {
+ font-family: inherit;
+ font-size: inherit;
+ padding: 0.3rem;
+ }
+
+ html {
+ font-size: 100%;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ Oxygen-Sans, Cantarell, "Helvetica Neue", sans-serif;
+ max-width: 800px;
+ margin: 1rem auto;
+ }
+
+ blockquote {
+ border-left: 6px solid darkgrey;
+ background-color: #eaeaea;
+ margin: 1rem 0 1rem 5rem;
+ padding: 0.7rem 1rem;
+ }
+ blockquote p {
+ margin: 0;
+ }
+ blockquote p + p {
+ margin-top: 1rem;
+ }
+
+ pre {
+ border: 1px solid;
+ border-radius: 4px;
+ padding: 1rem;
+ overflow-x: scroll;
+ }
+
+ content > p {
+ margin: 1.7rem 0;
+ }
+
+ header h1 {
+ margin: 0;
+ }
+ header .tagline {
+ margin-top: 0;
+ }
+ header {
+ border-bottom: 2px solid black;
+ }
+ header a {
+ text-decoration: none;
+ }
+ </style>
+ </head>
+
+ <body>
+
+ <header>
+ <h1><a href="/">My Site</a></h1>
+ <p class="tagline">And it's fine.</p>
+ </header>
+
+ <main>
+
+<h1 class="post-title">Hello</h1>
+<time class="post-time" datetime="0001-01-01">
+ Monday, 01 Jan 0001
+</time>
+<content>
<p>Hello world.</p>
+
+</content>
+
+<style>
+.post-title {
+ text-align: center;
+ font-size: 2rem;
+ margin-bottom: 0;
+}
+.post-time {
+ display: block;
+ text-align: center;
+}
+
+content img,
+content video {
+ max-width: 100%;
+}
+</style>
+
+ </main>
+
+ </body>
+</html>
diff --git a/www/index.html b/www/index.html
new file mode 100644
index 0000000..8a62061
--- /dev/null
+++ b/www/index.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <title>My Site - And it's fine. - My Site</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
+ <style>
+
+ * {
+ box-sizing: border-box;
+ }
+ input,
+ textarea {
+ font-family: inherit;
+ font-size: inherit;
+ padding: 0.3rem;
+ }
+
+ html {
+ font-size: 100%;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
+ Oxygen-Sans, Cantarell, "Helvetica Neue", sans-serif;
+ max-width: 800px;
+ margin: 1rem auto;
+ }
+
+ blockquote {
+ border-left: 6px solid darkgrey;
+ background-color: #eaeaea;
+ margin: 1rem 0 1rem 5rem;
+ padding: 0.7rem 1rem;
+ }
+ blockquote p {
+ margin: 0;
+ }
+ blockquote p + p {
+ margin-top: 1rem;
+ }
+
+ pre {
+ border: 1px solid;
+ border-radius: 4px;
+ padding: 1rem;
+ overflow-x: scroll;
+ }
+
+ content > p {
+ margin: 1.7rem 0;
+ }
+
+ header h1 {
+ margin: 0;
+ }
+ header .tagline {
+ margin-top: 0;
+ }
+ header {
+ border-bottom: 2px solid black;
+ }
+ header a {
+ text-decoration: none;
+ }
+ </style>
+ </head>
+
+ <body>
+
+ <header>
+ <h1><a href="/">My Site</a></h1>
+ <p class="tagline">And it's fine.</p>
+ </header>
+
+ <main>
+
+<p>All posts, newest first:</p>
+
+<ul>
+
+
+ <li>
+ 0001-01-01
+ — <a href="about/index.html">About</a>
+ </li>
+
+
+
+ <li>
+ 0001-01-01
+ — <a href="hello/index.html">Hello</a>
+ </li>
+
+
+</ul>
+
+<style>
+ ul a {
+ text-decoration: none;
+ }
+
+ ul {
+ padding: 0;
+ list-style-type: none;
+ font-size: 1.1rem;
+ }
+</style>
+
+ </main>
+
+ </body>
+</html>
diff --git a/www/website.toml b/www/website.toml
index 0b0fc98..22d4218 100644
--- a/www/website.toml
+++ b/www/website.toml
@@ -1,2 +1,3 @@
Name = "My Site"
Tagline = "And it's fine."
+HomePath = "/"