summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--deps/deps.go6
-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
-rw-r--r--output/layout.go28
-rw-r--r--output/layout_base.go19
-rw-r--r--output/layout_base_test.go6
-rw-r--r--output/layout_test.go4
-rw-r--r--output/outputFormat.go40
-rw-r--r--output/outputFormat_test.go27
-rw-r--r--tpl/template.go111
-rw-r--r--tpl/tplimpl/ace.go51
-rw-r--r--tpl/tplimpl/amber_compiler.go4
-rw-r--r--tpl/tplimpl/template.go770
-rw-r--r--tpl/tplimpl/templateFuncster.go86
-rw-r--r--tpl/tplimpl/templateProvider.go59
-rw-r--r--tpl/tplimpl/template_ast_transformers.go50
-rw-r--r--tpl/tplimpl/template_ast_transformers_test.go12
-rw-r--r--tpl/tplimpl/template_embedded.go57
-rw-r--r--tpl/tplimpl/template_funcs.go33
-rw-r--r--tpl/tplimpl/template_funcs_test.go106
-rw-r--r--tpl/tplimpl/template_test.go232
31 files changed, 777 insertions, 1186 deletions
diff --git a/deps/deps.go b/deps/deps.go
index 188863876..659f259dd 100644
--- a/deps/deps.go
+++ b/deps/deps.go
@@ -20,7 +20,7 @@ type Deps struct {
Log *jww.Notepad `json:"-"`
// The templates to use.
- Tmpl tpl.TemplateHandler `json:"-"`
+ Tmpl tpl.Template `json:"-"`
// The file systems to use.
Fs *hugofs.Fs `json:"-"`
@@ -40,7 +40,7 @@ type Deps struct {
Language *helpers.Language
templateProvider ResourceProvider
- WithTemplate func(templ tpl.TemplateHandler) error `json:"-"`
+ WithTemplate func(templ tpl.Template) error `json:"-"`
translationProvider ResourceProvider
}
@@ -158,7 +158,7 @@ type DepsCfg struct {
// Template handling.
TemplateProvider ResourceProvider
- WithTemplate func(templ tpl.TemplateHandler) error
+ WithTemplate func(templ tpl.Template) error
// i18n handling.
TranslationProvider ResourceProvider
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