From 6fd4c6c1dc24d5cddc6b97f378af5bff07aca212 Mon Sep 17 00:00:00 2001
From: Robert Lillack <rob@lillack.net>
Date: Thu, 6 Jan 2022 15:21:53 +0100
Subject: [PATCH 1/2] Add support for rendering extra files.

---
 core/page.go | 50 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 11 deletions(-)

diff --git a/core/page.go b/core/page.go
index c6d0d7e..7d70931 100644
--- a/core/page.go
+++ b/core/page.go
@@ -259,17 +259,19 @@ func (p *Page) Generate() error {
 
 	destDir := filepath.Join(append([]string{p.Tacker.BaseDir, TargetDir}, p.TargetDir()...)...)
 
-	p.Tacker.Debug("Generating %s", p.Slug)
-	par := "-"
-	if p.Parent != nil {
-		par = p.Parent.DiskPath
+	if p.DiskPath != "" {
+		p.Tacker.Debug("Generating %s", p.Slug)
+		par := "-"
+		if p.Parent != nil {
+			par = p.Parent.DiskPath
+		}
+		p.Tacker.Debug(" - disk path: %s", p.DiskPath)
+		p.Tacker.Debug(" - parent: %s", par)
+		p.Tacker.Debug(" - permalink: %s", p.Permalink())
+		p.Tacker.Debug(" - destdir: %s", destDir)
+		p.Tacker.Debug(" - ancestors: %s", strings.Join(a, " << "))
+		p.Tacker.Debug(" - siblings: %s", strings.Join(s, ", "))
 	}
-	p.Tacker.Debug(" - disk path: %s", p.DiskPath)
-	p.Tacker.Debug(" - parent: %s", par)
-	p.Tacker.Debug(" - permalink: %s", p.Permalink())
-	p.Tacker.Debug(" - destdir: %s", destDir)
-	p.Tacker.Debug(" - ancestors: %s", strings.Join(a, " << "))
-	p.Tacker.Debug(" - siblings: %s", strings.Join(s, ", "))
 
 	if err := os.MkdirAll(destDir, 0755); err != nil {
 		return err
@@ -291,7 +293,7 @@ func (p *Page) Generate() error {
 	}
 
 	for i := range p.Assets {
-		p.Tacker.Debug("Copying ...%s", i)
+		p.Tacker.Debug(" - copying %s", i)
 		if err := os.MkdirAll(filepath.Dir(filepath.Join(destDir, i)), 0755); err != nil {
 			return err
 		}
@@ -300,5 +302,31 @@ func (p *Page) Generate() error {
 		}
 	}
 
+	if dict, ok := p.Variables["extra_files"].(map[interface{}]interface{}); ok {
+		for k, v := range dict {
+			fn := k.(string)
+			templateName := v.(string)
+			if fn == "" || templateName == "" {
+				continue
+			}
+
+			p.Tacker.Log(" - rendering %s", fn)
+			tpl, err := p.Tacker.FindTemplate(templateName)
+			if err != nil {
+				return fmt.Errorf("unable to load template '%s' for extra file '%s' when rendering '%s': %s", s, fn, p.Permalink(), err)
+			}
+
+			f, err := os.OpenFile(filepath.Join(destDir, fn), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
+			if err != nil {
+				return err
+			}
+			defer f.Close()
+
+			if err := tpl.Render(p, f); err != nil {
+				return fmt.Errorf("unable to render template '%s' for extra file '%s' when rendering '%s': %s", s, fn, p.Permalink(), err)
+			}
+		}
+	}
+
 	return nil
 }

From 4a9f517307142189b2a53d2f5a26aaf092b8a948 Mon Sep 17 00:00:00 2001
From: Robert Lillack <rob@lillack.net>
Date: Thu, 6 Jan 2022 15:22:08 +0100
Subject: [PATCH 2/2] Add more date options to rendering.

---
 core/page.go     | 2 +-
 core/tacker.go   | 4 +++-
 core/template.go | 8 ++++++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/core/page.go b/core/page.go
index 7d70931..60a6955 100644
--- a/core/page.go
+++ b/core/page.go
@@ -310,7 +310,7 @@ func (p *Page) Generate() error {
 				continue
 			}
 
-			p.Tacker.Log(" - rendering %s", fn)
+			p.Tacker.Debug(" - rendering %s", fn)
 			tpl, err := p.Tacker.FindTemplate(templateName)
 			if err != nil {
 				return fmt.Errorf("unable to load template '%s' for extra file '%s' when rendering '%s': %s", s, fn, p.Permalink(), err)
diff --git a/core/tacker.go b/core/tacker.go
index b5649e2..0a64e8e 100644
--- a/core/tacker.go
+++ b/core/tacker.go
@@ -10,6 +10,7 @@ import (
 	"path/filepath"
 	"sort"
 	"strings"
+	"time"
 
 	"github.com/cbroglie/mustache"
 	"gopkg.in/yaml.v2"
@@ -35,6 +36,7 @@ type Tacker struct {
 	TagIndex    *Page
 	Logger      *log.Logger
 	DebugLogger *log.Logger
+	BuildTime   time.Time
 }
 
 func NewTacker(dir string) (*Tacker, error) {
@@ -162,6 +164,7 @@ func (t *Tacker) Debug(format string, args ...interface{}) {
 }
 
 func (t *Tacker) Tack() error {
+	t.BuildTime = time.Now()
 	t.Log("Tacking up %s (%d pages)", t.BaseDir, len(t.Pages))
 
 	if _, err := os.Stat(filepath.Join(t.BaseDir, TargetDir)); err != nil && !errors.Is(err, os.ErrNotExist) {
@@ -173,7 +176,6 @@ func (t *Tacker) Tack() error {
 	}
 
 	for _, page := range t.Pages {
-		t.Debug("%s => %s (template: %s)", page.Permalink(), page.Slug, page.Template)
 		if err := page.Generate(); err != nil {
 			return err
 		}
diff --git a/core/template.go b/core/template.go
index 2f47266..7433b18 100644
--- a/core/template.go
+++ b/core/template.go
@@ -4,10 +4,13 @@ import (
 	"io"
 	"sort"
 	"strings"
+	"time"
 
 	"github.com/cbroglie/mustache"
 )
 
+const RFC822 string = "02 Jan 2006 15:04:05 -0700"
+
 type Template struct {
 	*mustache.Template
 }
@@ -32,6 +35,8 @@ func PageValues(p *Page, ctx *Page) map[string]interface{} {
 	data["root"] = p.Root()
 	if p.Post() {
 		data["date"] = p.Date.Format("2006-01-02")
+		data["date_rfc822"] = p.Date.Format(RFC822)
+		data["date_rfc3339"] = p.Date.Format(time.RFC3339)
 		data["year"] = p.Date.Format("2006")
 		data["month"] = p.Date.Format("January")
 	}
@@ -137,6 +142,9 @@ func (t *Template) Render(page *Page, w io.Writer) error {
 		ctx["posts"] = PageListValues(limitPageList(posts, page, "posts_limit"), page)
 	}
 
+	ctx["TACK_BUILD_DATE"] = page.Tacker.BuildTime.Local().Format(time.RFC3339)
+	ctx["TACK_BUILD_DATE_RFC822"] = page.Tacker.BuildTime.Local().Format(RFC822)
+
 	return t.Template.FRender(w, ctx)
 }