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&#39;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&#39;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&#39;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&#39;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 = "/"