diff --git a/site/site.go b/site/site.go index 1766904..ea16367 100644 --- a/site/site.go +++ b/site/site.go @@ -40,7 +40,7 @@ func Load(config config.Config) (*Site, error) { Config: config, tags: make(map[string][]map[string]interface{}), data: make(map[string]interface{}), - templateEngine: templates.NewEngine(config.SiteUrl), + templateEngine: templates.NewEngine(config.SiteUrl, config.IncludesDir), } if err := site.loadDataFiles(); err != nil { diff --git a/templates/filters.go b/templates/filters.go index 975c152..d08651a 100644 --- a/templates/filters.go +++ b/templates/filters.go @@ -5,8 +5,10 @@ import ( "fmt" "log" "net/url" + "path/filepath" "reflect" "regexp" + "strings" "encoding/xml" "time" @@ -16,12 +18,14 @@ import ( "github.com/osteele/liquid/evaluator" "github.com/osteele/liquid/expressions" "github.com/yuin/goldmark" + + "github.com/osteele/liquid/render" ) // a lot of the filters and tags available at jekyll aren't default liquid manually adding them here // copied from https://github.com/osteele/gojekyll/blob/f1794a874890bfb601cae767a0cce15d672e9058/filters/filters.go // MIT License: https://github.com/osteele/gojekyll/blob/f1794a874890bfb601cae767a0cce15d672e9058/LICENSE -func loadJekyllFilters(e *liquid.Engine, siteUrl string) { +func loadJekyllFilters(e *liquid.Engine, siteUrl string, includesDir string) { e.RegisterFilter("filter", filter) e.RegisterFilter("group_by", groupByFilter) e.RegisterFilter("group_by_exp", groupByExpFilter) @@ -69,6 +73,10 @@ func loadJekyllFilters(e *liquid.Engine, siteUrl string) { return date.Format("2006-01-02T15:04:05-07:00") // Out: 2008-11-07T13:07:54-08:00 }) + + e.RegisterTag("include", func(rc render.Context) (string, error) { + return includeFromDir(includesDir, rc) + }) } func filter(values []map[string]interface{}, key string) []interface{} { @@ -185,3 +193,20 @@ func whereFilter(array []map[string]interface{}, key string, value interface{}) } return result } + +func includeFromDir(dir string, rc render.Context) (string, error) { + argsline, err := rc.ExpandTagArg() + if err != nil { + return "", err + } + args := strings.Split(argsline, " ") + if err != nil { + return "", err + } + if len(args) != 1 { + return "", fmt.Errorf("parse error") + } + + filename := filepath.Join(dir, args[0]) + return rc.RenderFile(filename, map[string]interface{}{}) +} diff --git a/templates/templates.go b/templates/templates.go index 125cdad..dbcb057 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -27,9 +27,9 @@ type Template struct { // Create a new template engine, with custom liquid filters. // The `siteUrl` is necessary to provide context for the absolute_url filter. -func NewEngine(siteUrl string) *Engine { +func NewEngine(siteUrl string, includesDir string) *Engine { e := liquid.NewEngine() - loadJekyllFilters(e, siteUrl) + loadJekyllFilters(e, siteUrl, includesDir) return e } diff --git a/templates/templates_test.go b/templates/templates_test.go index 9ff7d01..223e12b 100644 --- a/templates/templates_test.go +++ b/templates/templates_test.go @@ -18,7 +18,7 @@ tags: ["software", "web"] file := newFile("test*.html", input) defer os.Remove(file.Name()) - templ, err := Parse(NewEngine("https://olano.dev"), file.Name()) + templ, err := Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assertEqual(t, err, nil) assertEqual(t, templ.Metadata["title"], "my new post") @@ -42,7 +42,7 @@ subtitle: a blog post file := newFile("test*.html", input) defer os.Remove(file.Name()) - _, err := Parse(NewEngine("https://olano.dev"), file.Name()) + _, err := Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assertEqual(t, err, nil) // not first thing in file, leaving as is @@ -57,7 +57,7 @@ tags: ["software", "web"] file = newFile("test*.html", input) defer os.Remove(file.Name()) - _, err = Parse(NewEngine("https://olano.dev"), file.Name()) + _, err = Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assertEqual(t, err, nil) } @@ -69,7 +69,7 @@ tags: ["software", "web"] ` file := newFile("test*.html", input) defer os.Remove(file.Name()) - _, err := Parse(NewEngine("https://olano.dev"), file.Name()) + _, err := Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assertEqual(t, err.Error(), "front matter not closed") @@ -81,7 +81,7 @@ tags: ["software", "web"] file = newFile("test*.html", input) defer os.Remove(file.Name()) - _, err = Parse(NewEngine("https://olano.dev"), file.Name()) + _, err = Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assert(t, strings.Contains(err.Error(), "invalid yaml")) } @@ -100,7 +100,7 @@ tags: ["software", "web"] file := newFile("test*.html", input) defer os.Remove(file.Name()) - templ, err := Parse(NewEngine("https://olano.dev"), file.Name()) + templ, err := Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assertEqual(t, err, nil) ctx := map[string]interface{}{"page": templ.Metadata} content, err := templ.Render(ctx) @@ -130,7 +130,7 @@ tags: ["software", "web"] file := newFile("test*.org", input) defer os.Remove(file.Name()) - templ, err := Parse(NewEngine("https://olano.dev"), file.Name()) + templ, err := Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assertEqual(t, err, nil) content, err := templ.Render(nil) @@ -172,7 +172,7 @@ tags: ["software", "web"] file := newFile("test*.md", input) defer os.Remove(file.Name()) - templ, err := Parse(NewEngine("https://olano.dev"), file.Name()) + templ, err := Parse(NewEngine("https://olano.dev", "includes"), file.Name()) assertEqual(t, err, nil) content, err := templ.Render(nil)