summaryrefslogtreecommitdiffstats
path: root/hugolib
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-04-02 14:20:34 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-04-02 14:20:34 +0200
commit7eb71ee06419f9ceedfd701ab2a27513ef448829 (patch)
tree254ba6c75575e067df76b4abe4e566936619adcb /hugolib
parentc97dae40d9cd24c467f5b8cfbe2ac06f3cdef1d2 (diff)
Revert "tpl: Rework to handle both text and HTML templates"
Will have to take another stab at this ... This reverts commit 5c5efa03d2512749950b0d05a7d4bde35ecbdc37. Closes #3260
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/alias.go27
-rw-r--r--hugolib/embedded_shortcodes_test.go8
-rw-r--r--hugolib/hugo_sites.go8
-rw-r--r--hugolib/page.go3
-rw-r--r--hugolib/page_output.go24
-rw-r--r--hugolib/shortcode.go16
-rw-r--r--hugolib/shortcode_test.go103
-rw-r--r--hugolib/site.go33
-rw-r--r--hugolib/site_output_test.go16
-rw-r--r--hugolib/site_test.go18
-rw-r--r--hugolib/sitemap_test.go2
-rw-r--r--hugolib/testhelpers_test.go4
12 files changed, 124 insertions, 138 deletions
diff --git a/hugolib/alias.go b/hugolib/alias.go
index 454744d9b..d5eb35777 100644
--- a/hugolib/alias.go
+++ b/hugolib/alias.go
@@ -22,8 +22,6 @@ import (
"runtime"
"strings"
- "github.com/spf13/hugo/tpl"
-
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/hugo/helpers"
@@ -37,19 +35,18 @@ const (
var defaultAliasTemplates *template.Template
func init() {
- //TODO(bep) consolidate
defaultAliasTemplates = template.New("")
template.Must(defaultAliasTemplates.New("alias").Parse(alias))
template.Must(defaultAliasTemplates.New("alias-xhtml").Parse(aliasXHtml))
}
type aliasHandler struct {
- t tpl.TemplateHandler
+ Templates *template.Template
log *jww.Notepad
allowRoot bool
}
-func newAliasHandler(t tpl.TemplateHandler, l *jww.Notepad, allowRoot bool) aliasHandler {
+func newAliasHandler(t *template.Template, l *jww.Notepad, allowRoot bool) aliasHandler {
return aliasHandler{t, l, allowRoot}
}
@@ -59,19 +56,12 @@ func (a aliasHandler) renderAlias(isXHTML bool, permalink string, page *Page) (i
t = "alias-xhtml"
}
- var templ *tpl.TemplateAdapter
-
- if a.t != nil {
- templ = a.t.Lookup("alias.html")
+ template := defaultAliasTemplates
+ if a.Templates != nil {
+ template = a.Templates
+ t = "alias.html"
}
- if templ == nil {
- def := defaultAliasTemplates.Lookup(t)
- if def != nil {
- templ = &tpl.TemplateAdapter{def}
- }
-
- }
data := struct {
Permalink string
Page *Page
@@ -81,7 +71,7 @@ func (a aliasHandler) renderAlias(isXHTML bool, permalink string, page *Page) (i
}
buffer := new(bytes.Buffer)
- err := templ.Execute(buffer, data)
+ err := template.ExecuteTemplate(buffer, t, data)
if err != nil {
return nil, err
}
@@ -93,7 +83,8 @@ func (s *Site) writeDestAlias(path, permalink string, p *Page) (err error) {
}
func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, p *Page) (err error) {
- handler := newAliasHandler(s.Tmpl, s.Log, allowRoot)
+
+ handler := newAliasHandler(s.Tmpl.Lookup("alias.html"), s.Log, allowRoot)
isXHTML := strings.HasSuffix(path, ".xhtml")
diff --git a/hugolib/embedded_shortcodes_test.go b/hugolib/embedded_shortcodes_test.go
index 45de0bf09..92821d0ef 100644
--- a/hugolib/embedded_shortcodes_test.go
+++ b/hugolib/embedded_shortcodes_test.go
@@ -335,8 +335,8 @@ func TestShortcodeTweet(t *testing.T) {
th = testHelper{cfg, fs, t}
)
- withTemplate := func(templ tpl.TemplateHandler) error {
- templ.(tpl.TemplateTestMocker).SetFuncs(tweetFuncMap)
+ withTemplate := func(templ tpl.Template) error {
+ templ.Funcs(tweetFuncMap)
return nil
}
@@ -390,8 +390,8 @@ func TestShortcodeInstagram(t *testing.T) {
th = testHelper{cfg, fs, t}
)
- withTemplate := func(templ tpl.TemplateHandler) error {
- templ.(tpl.TemplateTestMocker).SetFuncs(instagramFuncMap)
+ withTemplate := func(templ tpl.Template) error {
+ templ.Funcs(instagramFuncMap)
return nil
}
diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go
index 1f090cf5e..6c737f65a 100644
--- a/hugolib/hugo_sites.go
+++ b/hugolib/hugo_sites.go
@@ -127,11 +127,11 @@ func NewHugoSites(cfg deps.DepsCfg) (*HugoSites, error) {
return newHugoSites(cfg, sites...)
}
-func (s *Site) withSiteTemplates(withTemplates ...func(templ tpl.TemplateHandler) error) func(templ tpl.TemplateHandler) error {
- return func(templ tpl.TemplateHandler) error {
- templ.LoadTemplates(s.PathSpec.GetLayoutDirPath(), "")
+func (s *Site) withSiteTemplates(withTemplates ...func(templ tpl.Template) error) func(templ tpl.Template) error {
+ return func(templ tpl.Template) error {
+ templ.LoadTemplates(s.PathSpec.GetLayoutDirPath())
if s.PathSpec.ThemeSet() {
- templ.LoadTemplates(s.PathSpec.GetThemeDir()+"/layouts", "theme")
+ templ.LoadTemplatesWithPrefix(s.PathSpec.GetThemeDir()+"/layouts", "theme")
}
for _, wt := range withTemplates {
diff --git a/hugolib/page.go b/hugolib/page.go
index 5a04c6ce7..fa9f40922 100644
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -1384,14 +1384,13 @@ func (p *Page) prepareLayouts() error {
if p.Kind == KindPage {
if !p.IsRenderable() {
self := "__" + p.UniqueID()
- err := p.s.Tmpl.AddLateTemplate(self, string(p.Content))
+ _, err := p.s.Tmpl.GetClone().New(self).Parse(string(p.Content))
if err != nil {
return err
}
p.selfLayout = self
}
}
-
return nil
}
diff --git a/hugolib/page_output.go b/hugolib/page_output.go
index 58d09d688..f47343cb5 100644
--- a/hugolib/page_output.go
+++ b/hugolib/page_output.go
@@ -110,29 +110,9 @@ func (p *PageOutput) Render(layout ...string) template.HTML {
l, err := p.layouts(layout...)
if err != nil {
helpers.DistinctErrorLog.Printf("in .Render: Failed to resolve layout %q for page %q", layout, p.pathOrTitle())
- return ""
+ return template.HTML("")
}
-
- for _, layout := range l {
- templ := p.s.Tmpl.Lookup(layout)
- if templ == nil {
- // This is legacy from when we had only one output format and
- // HTML templates only. Some have references to layouts without suffix.
- // We default to good old HTML.
- templ = p.s.Tmpl.Lookup(layout + ".html")
- }
- if templ != nil {
- res, err := templ.ExecuteToString(p)
- if err != nil {
- helpers.DistinctErrorLog.Printf("in .Render: Failed to execute template %q for page %q", layout, p.pathOrTitle())
- return template.HTML("")
- }
- return template.HTML(res)
- }
- }
-
- return ""
-
+ return p.s.Tmpl.ExecuteTemplateToHTML(p, l...)
}
func (p *Page) Render(layout ...string) template.HTML {
diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go
index d72a96faa..d165c778b 100644
--- a/hugolib/shortcode.go
+++ b/hugolib/shortcode.go
@@ -177,7 +177,7 @@ var isInnerShortcodeCache = struct {
// to avoid potential costly look-aheads for closing tags we look inside the template itself
// we could change the syntax to self-closing tags, but that would make users cry
// the value found is cached
-func isInnerShortcode(t tpl.TemplateExecutor) (bool, error) {
+func isInnerShortcode(t *template.Template) (bool, error) {
isInnerShortcodeCache.RLock()
m, ok := isInnerShortcodeCache.m[t.Name()]
isInnerShortcodeCache.RUnlock()
@@ -188,7 +188,10 @@ func isInnerShortcode(t tpl.TemplateExecutor) (bool, error) {
isInnerShortcodeCache.Lock()
defer isInnerShortcodeCache.Unlock()
- match, _ := regexp.MatchString("{{.*?\\.Inner.*?}}", t.Tree())
+ if t.Tree == nil {
+ return false, errors.New("Template failed to compile")
+ }
+ match, _ := regexp.MatchString("{{.*?\\.Inner.*?}}", t.Tree.Root.String())
isInnerShortcodeCache.m[t.Name()] = match
return match, nil
@@ -395,6 +398,8 @@ Loop:
case tScName:
sc.name = currItem.val
tmpl := getShortcodeTemplate(sc.name, p.s.Tmpl)
+ {
+ }
if tmpl == nil {
return sc, fmt.Errorf("Unable to locate template for shortcode %q in page %q", sc.name, p.Path())
}
@@ -565,10 +570,7 @@ func replaceShortcodeTokens(source []byte, prefix string, replacements map[strin
return source, nil
}
-func getShortcodeTemplate(name string, t tpl.TemplateHandler) *tpl.TemplateAdapter {
- isInnerShortcodeCache.RLock()
- defer isInnerShortcodeCache.RUnlock()
-
+func getShortcodeTemplate(name string, t tpl.Template) *template.Template {
if x := t.Lookup("shortcodes/" + name + ".html"); x != nil {
return x
}
@@ -578,7 +580,7 @@ func getShortcodeTemplate(name string, t tpl.TemplateHandler) *tpl.TemplateAdapt
return t.Lookup("_internal/shortcodes/" + name + ".html")
}
-func renderShortcodeWithPage(tmpl tpl.Template, data *ShortcodeWithPage) string {
+func renderShortcodeWithPage(tmpl *template.Template, data *ShortcodeWithPage) string {
buffer := bp.GetBuffer()
defer bp.PutBuffer(buffer)
diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go
index 3d1922462..28b03aa9b 100644
--- a/hugolib/shortcode_test.go
+++ b/hugolib/shortcode_test.go
@@ -30,7 +30,7 @@ import (
)
// TODO(bep) remove
-func pageFromString(in, filename string, withTemplate ...func(templ tpl.TemplateHandler) error) (*Page, error) {
+func pageFromString(in, filename string, withTemplate ...func(templ tpl.Template) error) (*Page, error) {
s := newTestSite(nil)
if len(withTemplate) > 0 {
// Have to create a new site
@@ -47,11 +47,11 @@ func pageFromString(in, filename string, withTemplate ...func(templ tpl.Template
return s.NewPageFrom(strings.NewReader(in), filename)
}
-func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.TemplateHandler) error) {
+func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.Template) error) {
CheckShortCodeMatchAndError(t, input, expected, withTemplate, false)
}
-func CheckShortCodeMatchAndError(t *testing.T, input, expected string, withTemplate func(templ tpl.TemplateHandler) error, expectError bool) {
+func CheckShortCodeMatchAndError(t *testing.T, input, expected string, withTemplate func(templ tpl.Template) error, expectError bool) {
cfg, fs := newTestCfg()
@@ -100,9 +100,8 @@ func TestNonSC(t *testing.T) {
// Issue #929
func TestHyphenatedSC(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
-
- tem.AddTemplate("_internal/shortcodes/hyphenated-video.html", `Playing Video {{ .Get 0 }}`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("hyphenated-video.html", `Playing Video {{ .Get 0 }}`)
return nil
}
@@ -112,8 +111,8 @@ func TestHyphenatedSC(t *testing.T) {
// Issue #1753
func TestNoTrailingNewline(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/a.html", `{{ .Get 0 }}`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("a.html", `{{ .Get 0 }}`)
return nil
}
@@ -122,8 +121,8 @@ func TestNoTrailingNewline(t *testing.T) {
func TestPositionalParamSC(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/video.html", `Playing Video {{ .Get 0 }}`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 0 }}`)
return nil
}
@@ -136,8 +135,8 @@ func TestPositionalParamSC(t *testing.T) {
func TestPositionalParamIndexOutOfBounds(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/video.html", `Playing Video {{ .Get 1 }}`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 1 }}`)
return nil
}
CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video error: index out of range for positional param at position 1", wt)
@@ -147,8 +146,8 @@ func TestPositionalParamIndexOutOfBounds(t *testing.T) {
func TestNamedParamSC(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/img.html", `<img{{ with .Get "src" }} src="{{.}}"{{end}}{{with .Get "class"}} class="{{.}}"{{end}}>`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("img.html", `<img{{ with .Get "src" }} src="{{.}}"{{end}}{{with .Get "class"}} class="{{.}}"{{end}}>`)
return nil
}
CheckShortCodeMatch(t, `{{< img src="one" >}}`, `<img src="one">`, wt)
@@ -162,10 +161,10 @@ func TestNamedParamSC(t *testing.T) {
// Issue #2294
func TestNestedNamedMissingParam(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/acc.html", `<div class="acc">{{ .Inner }}</div>`)
- tem.AddTemplate("_internal/shortcodes/div.html", `<div {{with .Get "class"}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`)
- tem.AddTemplate("_internal/shortcodes/div2.html", `<div {{with .Get 0}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("acc.html", `<div class="acc">{{ .Inner }}</div>`)
+ tem.AddInternalShortcode("div.html", `<div {{with .Get "class"}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`)
+ tem.AddInternalShortcode("div2.html", `<div {{with .Get 0}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`)
return nil
}
CheckShortCodeMatch(t,
@@ -175,10 +174,10 @@ func TestNestedNamedMissingParam(t *testing.T) {
func TestIsNamedParamsSC(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/byposition.html", `<div id="{{ .Get 0 }}">`)
- tem.AddTemplate("_internal/shortcodes/byname.html", `<div id="{{ .Get "id" }}">`)
- tem.AddTemplate("_internal/shortcodes/ifnamedparams.html", `<div id="{{ if .IsNamedParams }}{{ .Get "id" }}{{ else }}{{ .Get 0 }}{{end}}">`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("byposition.html", `<div id="{{ .Get 0 }}">`)
+ tem.AddInternalShortcode("byname.html", `<div id="{{ .Get "id" }}">`)
+ tem.AddInternalShortcode("ifnamedparams.html", `<div id="{{ if .IsNamedParams }}{{ .Get "id" }}{{ else }}{{ .Get 0 }}{{end}}">`)
return nil
}
CheckShortCodeMatch(t, `{{< ifnamedparams id="name" >}}`, `<div id="name">`, wt)
@@ -191,8 +190,8 @@ func TestIsNamedParamsSC(t *testing.T) {
func TestInnerSC(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
return nil
}
CheckShortCodeMatch(t, `{{< inside class="aspen" >}}`, `<div class="aspen"></div>`, wt)
@@ -202,8 +201,8 @@ func TestInnerSC(t *testing.T) {
func TestInnerSCWithMarkdown(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
return nil
}
CheckShortCodeMatch(t, `{{% inside %}}
@@ -216,8 +215,8 @@ func TestInnerSCWithMarkdown(t *testing.T) {
func TestInnerSCWithAndWithoutMarkdown(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
return nil
}
CheckShortCodeMatch(t, `{{% inside %}}
@@ -247,9 +246,9 @@ func TestEmbeddedSC(t *testing.T) {
func TestNestedSC(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/scn1.html", `<div>Outer, inner is {{ .Inner }}</div>`)
- tem.AddTemplate("_internal/shortcodes/scn2.html", `<div>SC2</div>`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("scn1.html", `<div>Outer, inner is {{ .Inner }}</div>`)
+ tem.AddInternalShortcode("scn2.html", `<div>SC2</div>`)
return nil
}
CheckShortCodeMatch(t, `{{% scn1 %}}{{% scn2 %}}{{% /scn1 %}}`, "<div>Outer, inner is <div>SC2</div>\n</div>", wt)
@@ -259,10 +258,10 @@ func TestNestedSC(t *testing.T) {
func TestNestedComplexSC(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/row.html", `-row-{{ .Inner}}-rowStop-`)
- tem.AddTemplate("_internal/shortcodes/column.html", `-col-{{.Inner }}-colStop-`)
- tem.AddTemplate("_internal/shortcodes/aside.html", `-aside-{{ .Inner }}-asideStop-`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("row.html", `-row-{{ .Inner}}-rowStop-`)
+ tem.AddInternalShortcode("column.html", `-col-{{.Inner }}-colStop-`)
+ tem.AddInternalShortcode("aside.html", `-aside-{{ .Inner }}-asideStop-`)
return nil
}
CheckShortCodeMatch(t, `{{< row >}}1-s{{% column %}}2-**s**{{< aside >}}3-**s**{{< /aside >}}4-s{{% /column %}}5-s{{< /row >}}6-s`,
@@ -275,10 +274,10 @@ func TestNestedComplexSC(t *testing.T) {
func TestParentShortcode(t *testing.T) {
t.Parallel()
- wt := func(tem tpl.TemplateHandler) error {
- tem.AddTemplate("_internal/shortcodes/r1.html", `1: {{ .Get "pr1" }} {{ .Inner }}`)
- tem.AddTemplate("_internal/shortcodes/r2.html", `2: {{ .Parent.Get "pr1" }}{{ .Get "pr2" }} {{ .Inner }}`)
- tem.AddTemplate("_internal/shortcodes/r3.html", `3: {{ .Parent.Parent.Get "pr1" }}{{ .Parent.Get "pr2" }}{{ .Get "pr3" }} {{ .Inner }}`)
+ wt := func(tem tpl.Template) error {
+ tem.AddInternalShortcode("r1.html", `1: {{ .Get "pr1" }} {{ .Inner }}`)
+ tem.AddInternalShortcode("r2.html", `2: {{ .Parent.Get "pr1" }}{{ .Get "pr2" }} {{ .Inner }}`)
+ tem.AddInternalShortcode("r3.html", `3: {{ .Parent.Parent.Get "pr1" }}{{ .Parent.Get "pr2" }}{{ .Get "pr3" }} {{ .Inner }}`)
return nil
}
CheckShortCodeMatch(t, `{{< r1 pr1="p1" >}}1: {{< r2 pr2="p2" >}}2: {{< r3 pr3="p3" >}}{{< /r3 >}}{{< /r2 >}}{{< /r1 >}}`,
@@ -343,13 +342,13 @@ func TestExtractShortcodes(t *testing.T) {
fmt.Sprintf("Hello %sworld%s. And that's it.", testScPlaceholderRegexp, testScPlaceholderRegexp), ""},
} {
- p, _ := pageFromString(simplePage, "simple.md", func(templ tpl.TemplateHandler) error {
- templ.AddTemplate("_internal/shortcodes/tag.html", `tag`)
- templ.AddTemplate("_internal/shortcodes/sc1.html", `sc1`)
- templ.AddTemplate("_internal/shortcodes/sc2.html", `sc2`)
- templ.AddTemplate("_internal/shortcodes/inner.html", `{{with .Inner }}{{ . }}{{ end }}`)
- templ.AddTemplate("_internal/shortcodes/inner2.html", `{{.Inner}}`)
- templ.AddTemplate("_internal/shortcodes/inner3.html", `{{.Inner}}`)
+ p, _ := pageFromString(simplePage, "simple.md", func(templ tpl.Template) error {
+ templ.AddInternalShortcode("tag.html", `tag`)
+ templ.AddInternalShortcode("sc1.html", `sc1`)
+ templ.AddInternalShortcode("sc2.html", `sc2`)
+ templ.AddInternalShortcode("inner.html", `{{with .Inner }}{{ . }}{{ end }}`)
+ templ.AddInternalShortcode("inner2.html", `{{.Inner}}`)
+ templ.AddInternalShortcode("inner3.html", `{{.Inner}}`)
return nil
})
@@ -518,14 +517,14 @@ tags:
sources[i] = source.ByteSource{Name: filepath.FromSlash(test.contentPath), Content: []byte(test.content)}
}
- addTemplates := func(templ tpl.TemplateHandler) error {
+ addTemplates := func(templ tpl.Template) error {
templ.AddTemplate("_default/single.html", "{{.Content}}")
- templ.AddTemplate("_internal/shortcodes/b.html", `b`)
- templ.AddTemplate("_internal/shortcodes/c.html", `c`)
- templ.AddTemplate("_internal/shortcodes/d.html", `d`)
- templ.AddTemplate("_internal/shortcodes/menu.html", `{{ len (index .Page.Menus "main").Children }}`)
- templ.AddTemplate("_internal/shortcodes/tags.html", `{{ len .Page.Site.Taxonomies.tags }}`)
+ templ.AddInternalShortcode("b.html", `b`)
+ templ.AddInternalShortcode("c.html", `c`)
+ templ.AddInternalShortcode("d.html", `d`)
+ templ.AddInternalShortcode("menu.html", `{{ len (index .Page.Menus "main").Children }}`)
+ templ.AddInternalShortcode("tags.html", `{{ len .Page.Site.Taxonomies.tags }}`)
return nil
diff --git a/hugolib/site.go b/hugolib/site.go
index 613485864..c42b938e8 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -188,7 +188,7 @@ func NewSite(cfg deps.DepsCfg) (*Site, error) {
// NewSiteDefaultLang creates a new site in the default language.
// The site will have a template system loaded and ready to use.
// Note: This is mainly used in single site tests.
-func NewSiteDefaultLang(withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
+func NewSiteDefaultLang(withTemplate ...func(templ tpl.Template) error) (*Site, error) {
v := viper.New()
loadDefaultSettingsFor(v)
return newSiteForLang(helpers.NewDefaultLanguage(v), withTemplate...)
@@ -197,15 +197,15 @@ func NewSiteDefaultLang(withTemplate ...func(templ tpl.TemplateHandler) error) (
// NewEnglishSite creates a new site in English language.
// The site will have a template system loaded and ready to use.
// Note: This is mainly used in single site tests.
-func NewEnglishSite(withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
+func NewEnglishSite(withTemplate ...func(templ tpl.Template) error) (*Site, error) {
v := viper.New()
loadDefaultSettingsFor(v)
return newSiteForLang(helpers.NewLanguage("en", v), withTemplate...)
}
// newSiteForLang creates a new site in the given language.
-func newSiteForLang(lang *helpers.Language, withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
- withTemplates := func(templ tpl.TemplateHandler) error {
+func newSiteForLang(lang *helpers.Language, withTemplate ...func(templ tpl.Template) error) (*Site, error) {
+ withTemplates := func(templ tpl.Template) error {
for _, wt := range withTemplate {
if err := wt(templ); err != nil {
return err
@@ -1906,14 +1906,13 @@ Your rendered home page is blank: /index.html is zero-length
}
func (s *Site) renderForLayouts(name string, d interface{}, w io.Writer, layouts ...string) error {
- templ := s.findFirstTemplate(layouts...)
- if templ == nil {
+ layout, found := s.findFirstLayout(layouts...)
+ if !found {
helpers.DistinctWarnLog.Printf("[%s] Unable to locate layout for %s: %s\n", s.Language.Lang, name, layouts)
-
return nil
}
- if err := templ.Execute(w, d); err != nil {
+ if err := s.renderThing(d, layout, w); err != nil {
// Behavior here should be dependent on if running in server or watch mode.
helpers.DistinctErrorLog.Printf("Error while rendering %q: %s", name, err)
@@ -1928,13 +1927,23 @@ func (s *Site) renderForLayouts(name string, d interface{}, w io.Writer, layouts
return nil
}
-func (s *Site) findFirstTemplate(layouts ...string) tpl.Template {
+func (s *Site) findFirstLayout(layouts ...string) (string, bool) {
for _, layout := range layouts {
- if templ := s.Tmpl.Lookup(layout); templ != nil {
- return templ
+ if s.Tmpl.Lookup(layout) != nil {
+ return layout, true
}
}
- return nil
+ return "", false
+}
+
+func (s *Site) renderThing(d interface{}, layout string, w io.Writer) error {
+
+ // If the template doesn't exist, then return, but leave the Writer open
+ if templ := s.Tmpl.Lookup(layout); templ != nil {
+ return templ.Execute(w, d)
+ }
+ return fmt.Errorf("Layout not found: %s", layout)
+
}
func (s *Site) publish(path string, r io.Reader) (err error) {
diff --git a/hugolib/site_output_test.go b/hugolib/site_output_test.go
index 06c55a69c..86e1a55ca 100644
--- a/hugolib/site_output_test.go
+++ b/hugolib/site_output_test.go
@@ -90,15 +90,9 @@ outputs: %s
Alt Output: {{ .Name -}}|
{{- end -}}|
{{- range .OutputFormats -}}
-Output/Rel: {{ .Name -}}/{{ .Rel }}|{{ .MediaType }}
+Output/Rel: {{ .Name -}}/{{ .Rel }}|
{{- end -}}
- {{ with .OutputFormats.Get "JSON" }}
-<atom:link href={{ .Permalink }} rel="self" type="{{ .MediaType }}" />
-{{ end }}
`,
- "layouts/_default/list.html", `List HTML|{{ with .OutputFormats.Get "HTML" -}}
-<atom:link href={{ .Permalink }} rel="self" type="{{ .MediaType }}" />
-{{- end -}}`,
)
require.Len(t, h.Sites, 1)
@@ -119,6 +113,7 @@ Output/Rel: {{ .Name -}}/{{ .Rel }}|{{ .MediaType }}
require.Len(t, home.outputFormats, lenOut)
+ // TODO(bep) output assert template/text
// There is currently always a JSON output to make it simpler ...
altFormats := lenOut - 1
hasHTML := helpers.InStringArray(outputs, "html")
@@ -133,16 +128,9 @@ Output/Rel: {{ .Name -}}/{{ .Rel }}|{{ .MediaType }}
"Output/Rel: JSON/alternate|",
"Output/Rel: HTML/canonical|",
)
- th.assertFileContent("public/index.html",
- // The HTML entity is a deliberate part of this test: The HTML templates are
- // parsed with html/template.
- `List HTML|<atom:link href=http://example.com/blog/ rel="self" type="text/html&#43;html" />`,
- )
} else {
th.assertFileContent("public/index.json",
"Output/Rel: JSON/canonical|",
- // JSON is plain text, so no need to safeHTML this and that
- `<atom:link href=http://example.com/blog/index.json rel="self" type="application/json+json" />`,
)
}
diff --git a/hugolib/site_test.go b/hugolib/site_test.go
index 5f66b153c..a3ec66880 100644
--- a/hugolib/site_test.go
+++ b/hugolib/site_test.go
@@ -52,6 +52,24 @@ func pageMust(p *Page, err error) *Page {
return p
}
+func TestDegenerateRenderThingMissingTemplate(t *testing.T) {
+ t.Parallel()
+ cfg, fs := newTestCfg()
+
+ writeSource(t, fs, filepath.Join("content", "a", "file.md"), pageSimpleTitle)
+
+ s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
+
+ require.Len(t, s.RegularPages, 1)
+
+ p := s.RegularPages[0]
+
+ err := s.renderThing(p, "foobar", nil)
+ if err == nil {
+ t.Errorf("Expected err to be returned when missing the template.")
+ }
+}
+
func TestRenderWithInvalidTemplate(t *testing.T) {
t.Parallel()
cfg, fs := newTestCfg()
diff --git a/hugolib/sitemap_test.go b/hugolib/sitemap_test.go
index 47f29c947..df342953b 100644
--- a/hugolib/sitemap_test.go
+++ b/hugolib/sitemap_test.go
@@ -48,7 +48,7 @@ func doTestSitemapOutput(t *testing.T, internal bool) {
depsCfg := deps.DepsCfg{Fs: fs, Cfg: cfg}
if !internal {
- depsCfg.WithTemplate = func(templ tpl.TemplateHandler) error {
+ depsCfg.WithTemplate = func(templ tpl.Template) error {
templ.AddTemplate("sitemap.xml", sitemapTemplate)
return nil
}
diff --git a/hugolib/testhelpers_test.go b/hugolib/testhelpers_test.go
index fbaab7192..d50514529 100644
--- a/hugolib/testhelpers_test.go
+++ b/hugolib/testhelpers_test.go
@@ -164,9 +164,9 @@ func newDebugLogger() *jww.Notepad {
func newErrorLogger() *jww.Notepad {
return jww.NewNotepad(jww.LevelError, jww.LevelError, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
}
-func createWithTemplateFromNameValues(additionalTemplates ...string) func(templ tpl.TemplateHandler) error {
+func createWithTemplateFromNameValues(additionalTemplates ...string) func(templ tpl.Template) error {
- return func(templ tpl.TemplateHandler) error {
+ return func(templ tpl.Template) error {
for i := 0; i < len(additionalTemplates); i += 2 {
err := templ.AddTemplate(additionalTemplates[i], additionalTemplates[i+1])
if err != nil {