templates: Fix base template block customization

Previously, kiln would error out if any blocks defined in the base
template were not defined in page or index templates. Instead, make
customizing base template blocks optional. This also allows base
template blocks to have a default value.
This commit is contained in:
Adnan Maolood 2022-09-27 08:13:11 -04:00
parent 3a3ec83e0f
commit 299cb5e1d1

View file

@ -9,50 +9,69 @@ import (
pathpkg "path"
"strings"
"text/template"
"text/template/parse"
)
// Template represents a template.
type Template interface {
AddParseTree(*parse.Tree) error
Clone() (Template, error)
AddTemplates(Template) error
Execute(io.Writer, interface{}) error
Tree() *parse.Tree
}
type textTemplate struct {
tmpl *template.Template
}
func (t textTemplate) AddParseTree(tree *parse.Tree) error {
_, err := t.tmpl.AddParseTree(t.tmpl.Name(), tree)
return err
func (t textTemplate) Clone() (Template, error) {
clone, err := t.tmpl.Clone()
return textTemplate{clone}, err
}
func (t textTemplate) AddTemplates(other Template) error {
otherTmpl := other.(textTemplate).tmpl
for _, def := range otherTmpl.Templates() {
if def.Name() == otherTmpl.Name() {
continue
}
_, err := t.tmpl.AddParseTree(def.Name(), def.Tree)
if err != nil {
return err
}
}
return nil
}
func (t textTemplate) Execute(w io.Writer, data interface{}) error {
return t.tmpl.Execute(w, data)
}
func (t textTemplate) Tree() *parse.Tree {
return t.tmpl.Tree
}
type htmlTemplate struct {
tmpl *htemplate.Template
}
func (t htmlTemplate) AddParseTree(tree *parse.Tree) error {
_, err := t.tmpl.AddParseTree(t.tmpl.Name(), tree)
return err
func (t htmlTemplate) Clone() (Template, error) {
clone, err := t.tmpl.Clone()
return htmlTemplate{clone}, err
}
func (t htmlTemplate) AddTemplates(other Template) error {
otherTmpl := other.(htmlTemplate).tmpl
for _, def := range otherTmpl.Templates() {
if def.Name() == otherTmpl.Name() {
continue
}
_, err := t.tmpl.AddParseTree(def.Name(), def.Tree)
if err != nil {
return err
}
}
return nil
}
func (t htmlTemplate) Execute(w io.Writer, data interface{}) error {
return t.tmpl.Execute(w, data)
}
func (t htmlTemplate) Tree() *parse.Tree {
return t.tmpl.Tree
}
// Templates contains site templates.
type Templates struct {
tmpls map[string]Template
@ -129,12 +148,20 @@ func (t *Templates) Load(dir string, exts []string) error {
if _, ok := extsMap[ext]; !ok {
continue
}
base := pathpkg.Join(pathpkg.Dir(path), "base"+ext)
if tmpl, ok := t.tmpls[base]; ok {
err := t.tmpls[path].AddParseTree(tmpl.Tree())
basePath := pathpkg.Join(pathpkg.Dir(path), "base"+ext)
if path == basePath {
continue
}
if base, ok := t.tmpls[basePath]; ok {
tmpl, err := base.Clone()
if err != nil {
return err
}
// Load customized template definitions
if err := tmpl.AddTemplates(t.tmpls[path]); err != nil {
return err
}
t.tmpls[path] = tmpl
}
}
return nil