diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2017-02-17 13:30:50 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2017-02-17 17:15:26 +0100 |
commit | c507e2717df7dd4b870478033bc5ece0b039a8c4 (patch) | |
tree | 873684fe890f1d23749ecbdbe8303712b6d9fafa | |
parent | 93ca7c9e958e34469a337e4efcc7c75774ec50fd (diff) |
tpl: Refactor package
Now:
* The template API lives in /tpl
* The rest lives in /tpl/tplimpl
This is bound te be more improved in the future.
Updates #2701
-rw-r--r-- | deps/deps.go | 8 | ||||
-rw-r--r-- | hugolib/embedded_shortcodes_test.go | 6 | ||||
-rw-r--r-- | hugolib/hugo_sites.go | 12 | ||||
-rw-r--r-- | hugolib/shortcode.go | 4 | ||||
-rw-r--r-- | hugolib/shortcode_test.go | 38 | ||||
-rw-r--r-- | hugolib/site.go | 10 | ||||
-rw-r--r-- | hugolib/sitemap_test.go | 4 | ||||
-rw-r--r-- | hugolib/testhelpers_test.go | 6 | ||||
-rw-r--r-- | tpl/template.go | 586 | ||||
-rw-r--r-- | tpl/tplimpl/amber_compiler.go (renamed from tpl/amber_compiler.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/reflect_helpers.go (renamed from tpl/reflect_helpers.go) | 4 | ||||
-rw-r--r-- | tpl/tplimpl/template.go | 575 | ||||
-rw-r--r-- | tpl/tplimpl/template_ast_transformers.go (renamed from tpl/template_ast_transformers.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_ast_transformers_test.go (renamed from tpl/template_ast_transformers_test.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_embedded.go (renamed from tpl/template_embedded.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_func_truncate.go (renamed from tpl/template_func_truncate.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_func_truncate_test.go (renamed from tpl/template_func_truncate_test.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_funcs.go (renamed from tpl/template_funcs.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_funcs_test.go (renamed from tpl/template_funcs_test.go) | 14 | ||||
-rw-r--r-- | tpl/tplimpl/template_resources.go (renamed from tpl/template_resources.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_resources_test.go (renamed from tpl/template_resources_test.go) | 2 | ||||
-rw-r--r-- | tpl/tplimpl/template_test.go (renamed from tpl/template_test.go) | 10 | ||||
-rw-r--r-- | tplapi/template.go | 28 |
23 files changed, 661 insertions, 662 deletions
diff --git a/deps/deps.go b/deps/deps.go index 39a3d31a4..de1b955cb 100644 --- a/deps/deps.go +++ b/deps/deps.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/hugo/config" "github.com/spf13/hugo/helpers" "github.com/spf13/hugo/hugofs" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl" jww "github.com/spf13/jwalterweatherman" ) @@ -20,7 +20,7 @@ type Deps struct { Log *jww.Notepad `json:"-"` // The templates to use. - Tmpl tplapi.Template `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 tplapi.Template) error `json:"-"` + WithTemplate func(templ tpl.Template) error `json:"-"` translationProvider ResourceProvider } @@ -147,7 +147,7 @@ type DepsCfg struct { // Template handling. TemplateProvider ResourceProvider - WithTemplate func(templ tplapi.Template) error + WithTemplate func(templ tpl.Template) error // i18n handling. TranslationProvider ResourceProvider diff --git a/hugolib/embedded_shortcodes_test.go b/hugolib/embedded_shortcodes_test.go index 513767eb4..a98ca1369 100644 --- a/hugolib/embedded_shortcodes_test.go +++ b/hugolib/embedded_shortcodes_test.go @@ -25,7 +25,7 @@ import ( "github.com/spf13/hugo/deps" "github.com/spf13/hugo/helpers" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl" "github.com/stretchr/testify/require" ) @@ -335,7 +335,7 @@ func TestShortcodeTweet(t *testing.T) { th = testHelper{cfg} ) - withTemplate := func(templ tplapi.Template) error { + withTemplate := func(templ tpl.Template) error { templ.Funcs(tweetFuncMap) return nil } @@ -390,7 +390,7 @@ func TestShortcodeInstagram(t *testing.T) { th = testHelper{cfg} ) - withTemplate := func(templ tplapi.Template) error { + withTemplate := func(templ tpl.Template) error { templ.Funcs(instagramFuncMap) return nil } diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go index f0feec23e..3cbe4fa90 100644 --- a/hugolib/hugo_sites.go +++ b/hugolib/hugo_sites.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/hugo/i18n" "github.com/spf13/hugo/tpl" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl/tplimpl" ) // HugoSites represents the sites to build. Each site represents a language. @@ -72,7 +72,7 @@ func newHugoSites(cfg deps.DepsCfg, sites ...*Site) (*HugoSites, error) { func applyDepsIfNeeded(cfg deps.DepsCfg, sites ...*Site) error { if cfg.TemplateProvider == nil { - cfg.TemplateProvider = tpl.DefaultTemplateProvider + cfg.TemplateProvider = tplimpl.DefaultTemplateProvider } if cfg.TranslationProvider == nil { @@ -121,8 +121,8 @@ func NewHugoSites(cfg deps.DepsCfg) (*HugoSites, error) { return newHugoSites(cfg, sites...) } -func (s *Site) withSiteTemplates(withTemplates ...func(templ tplapi.Template) error) func(templ tplapi.Template) error { - return func(templ tplapi.Template) error { +func (s *Site) withSiteTemplates(withTemplates ...func(templ tpl.Template) error) func(templ tpl.Template) error { + return func(templ tpl.Template) error { templ.LoadTemplates(s.absLayoutDir()) if s.hasTheme() { templ.LoadTemplatesWithPrefix(s.absThemeDir()+"/layouts", "theme") @@ -191,7 +191,7 @@ func (h *HugoSites) reset() { h.Sites[i] = s.reset() } - tpl.ResetCaches() + tplimpl.ResetCaches() } func (h *HugoSites) createSitesFromConfig() error { @@ -553,7 +553,7 @@ func (h *HugoSites) Pages() Pages { return h.Sites[0].AllPages } -func handleShortcodes(p *Page, t tplapi.Template, rawContentCopy []byte) ([]byte, error) { +func handleShortcodes(p *Page, t tpl.Template, rawContentCopy []byte) ([]byte, error) { if len(p.contentShortCodes) > 0 { p.s.Log.DEBUG.Printf("Replace %d shortcodes in %q", len(p.contentShortCodes), p.BaseFileName()) shortcodes, err := executeShortcodeFuncMap(p.contentShortCodes) diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index 4ce6df7e9..775c57e8c 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -26,7 +26,7 @@ import ( bp "github.com/spf13/hugo/bufferpool" "github.com/spf13/hugo/helpers" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl" ) // ShortcodeWithPage is the "." context in a shortcode template. @@ -541,7 +541,7 @@ func replaceShortcodeTokens(source []byte, prefix string, replacements map[strin return source, nil } -func getShortcodeTemplate(name string, t tplapi.Template) *template.Template { +func getShortcodeTemplate(name string, t tpl.Template) *template.Template { if x := t.Lookup("shortcodes/" + name + ".html"); x != nil { return x } diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go index b1f28d53b..665e3a944 100644 --- a/hugolib/shortcode_test.go +++ b/hugolib/shortcode_test.go @@ -25,12 +25,12 @@ import ( "github.com/spf13/hugo/deps" "github.com/spf13/hugo/helpers" "github.com/spf13/hugo/source" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl" "github.com/stretchr/testify/require" ) // TODO(bep) remove -func pageFromString(in, filename string, withTemplate ...func(templ tplapi.Template) 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 tplapi.Templ return s.NewPageFrom(strings.NewReader(in), filename) } -func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tplapi.Template) 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 tplapi.Template) error, expectError bool) { +func CheckShortCodeMatchAndError(t *testing.T, input, expected string, withTemplate func(templ tpl.Template) error, expectError bool) { cfg, fs := newTestCfg() @@ -100,7 +100,7 @@ func TestNonSC(t *testing.T) { // Issue #929 func TestHyphenatedSC(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("hyphenated-video.html", `Playing Video {{ .Get 0 }}`) return nil } @@ -111,7 +111,7 @@ func TestHyphenatedSC(t *testing.T) { // Issue #1753 func TestNoTrailingNewline(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("a.html", `{{ .Get 0 }}`) return nil } @@ -121,7 +121,7 @@ func TestNoTrailingNewline(t *testing.T) { func TestPositionalParamSC(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 0 }}`) return nil } @@ -135,7 +135,7 @@ func TestPositionalParamSC(t *testing.T) { func TestPositionalParamIndexOutOfBounds(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 1 }}`) return nil } @@ -146,7 +146,7 @@ func TestPositionalParamIndexOutOfBounds(t *testing.T) { func TestNamedParamSC(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("img.html", `<img{{ with .Get "src" }} src="{{.}}"{{end}}{{with .Get "class"}} class="{{.}}"{{end}}>`) return nil } @@ -161,7 +161,7 @@ func TestNamedParamSC(t *testing.T) { // Issue #2294 func TestNestedNamedMissingParam(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + 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>`) @@ -174,7 +174,7 @@ func TestNestedNamedMissingParam(t *testing.T) { func TestIsNamedParamsSC(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + 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}}">`) @@ -190,7 +190,7 @@ func TestIsNamedParamsSC(t *testing.T) { func TestInnerSC(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) return nil } @@ -201,7 +201,7 @@ func TestInnerSC(t *testing.T) { func TestInnerSCWithMarkdown(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) return nil } @@ -215,7 +215,7 @@ func TestInnerSCWithMarkdown(t *testing.T) { func TestInnerSCWithAndWithoutMarkdown(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + wt := func(tem tpl.Template) error { tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) return nil } @@ -246,7 +246,7 @@ func TestEmbeddedSC(t *testing.T) { func TestNestedSC(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + 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 @@ -258,7 +258,7 @@ func TestNestedSC(t *testing.T) { func TestNestedComplexSC(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + 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-`) @@ -274,7 +274,7 @@ func TestNestedComplexSC(t *testing.T) { func TestParentShortcode(t *testing.T) { t.Parallel() - wt := func(tem tplapi.Template) error { + 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 }}`) @@ -342,7 +342,7 @@ func TestExtractShortcodes(t *testing.T) { fmt.Sprintf("Hello %sworld%s. And that's it.", testScPlaceholderRegexp, testScPlaceholderRegexp), ""}, } { - p, _ := pageFromString(simplePage, "simple.md", func(templ tplapi.Template) error { + 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`) @@ -514,7 +514,7 @@ tags: sources[i] = source.ByteSource{Name: filepath.FromSlash(test.contentPath), Content: []byte(test.content)} } - addTemplates := func(templ tplapi.Template) error { + addTemplates := func(templ tpl.Template) error { templ.AddTemplate("_default/single.html", "{{.Content}}") templ.AddInternalShortcode("b.html", `b`) diff --git a/hugolib/site.go b/hugolib/site.go index bd0156849..a5555d0e4 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -40,7 +40,7 @@ import ( "github.com/spf13/hugo/parser" "github.com/spf13/hugo/source" "github.com/spf13/hugo/target" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl" "github.com/spf13/hugo/transform" "github.com/spf13/nitro" "github.com/spf13/viper" @@ -149,7 +149,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 tplapi.Template) error) (*Site, error) { +func NewSiteDefaultLang(withTemplate ...func(templ tpl.Template) error) (*Site, error) { v := viper.New() loadDefaultSettingsFor(v) return newSiteForLang(helpers.NewDefaultLanguage(v), withTemplate...) @@ -158,15 +158,15 @@ func NewSiteDefaultLang(withTemplate ...func(templ tplapi.Template) error) (*Sit // 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 tplapi.Template) 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 tplapi.Template) error) (*Site, error) { - withTemplates := func(templ tplapi.Template) 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 diff --git a/hugolib/sitemap_test.go b/hugolib/sitemap_test.go index 8bbcb487b..daefde524 100644 --- a/hugolib/sitemap_test.go +++ b/hugolib/sitemap_test.go @@ -19,7 +19,7 @@ import ( "reflect" "github.com/spf13/hugo/deps" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl" ) const sitemapTemplate = `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> @@ -48,7 +48,7 @@ func doTestSitemapOutput(t *testing.T, internal bool) { depsCfg := deps.DepsCfg{Fs: fs, Cfg: cfg} if !internal { - depsCfg.WithTemplate = func(templ tplapi.Template) 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 33e78e121..f0fcd9530 100644 --- a/hugolib/testhelpers_test.go +++ b/hugolib/testhelpers_test.go @@ -7,7 +7,7 @@ import ( "github.com/spf13/hugo/deps" "github.com/spf13/hugo/helpers" "github.com/spf13/hugo/source" - "github.com/spf13/hugo/tplapi" + "github.com/spf13/hugo/tpl" "github.com/spf13/viper" "io/ioutil" @@ -66,9 +66,9 @@ func newDebugLogger() *jww.Notepad { return jww.NewNotepad(jww.LevelDebug, jww.LevelError, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime) } -func createWithTemplateFromNameValues(additionalTemplates ...string) func(templ tplapi.Template) error { +func createWithTemplateFromNameValues(additionalTemplates ...string) func(templ tpl.Template) error { - return func(templ tplapi.Template) 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 { diff --git a/tpl/template.go b/tpl/template.go index 9a6364d5a..aaf7fc8c7 100644 --- a/tpl/template.go +++ b/tpl/template.go @@ -1,575 +1,27 @@ -// Copyright 2016 The Hugo Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package tpl import ( - "fmt" "html/template" "io" - "os" - "path/filepath" - "strings" - - "sync" - - "github.com/eknkc/amber" - "github.com/spf13/afero" - bp "github.com/spf13/hugo/bufferpool" - "github.com/spf13/hugo/deps" - "github.com/spf13/hugo/helpers" - "github.com/yosssi/ace" ) -// TODO(bep) globals get rid of the rest of the jww.ERR etc. - -// Protecting global map access (Amber) -var amberMu sync.Mutex - -type templateErr struct { - name string - err error -} - -type GoHTMLTemplate struct { - *template.Template - - clone *template.Template - - // a separate storage for the overlays created from cloned master templates. - // note: No mutex protection, so we add these in one Go routine, then just read. - overlays map[string]*template.Template - - errors []*templateErr - - funcster *templateFuncster - - amberFuncMap template.FuncMap - - *deps.Deps -} - -type TemplateProvider struct{} - -var DefaultTemplateProvider *TemplateProvider - -// Update updates the Hugo Template System in the provided Deps. -// with all the additional features, templates & functions -func (*TemplateProvider) Update(deps *deps.Deps) error { - // TODO(bep) check that this isn't called too many times. - tmpl := &GoHTMLTemplate{ - Template: template.New(""), - overlays: make(map[string]*template.Template), - errors: make([]*templateErr, 0), - Deps: deps, - } - - deps.Tmpl = tmpl - - tmpl.initFuncs(deps) - - tmpl.LoadEmbedded() - - if deps.WithTemplate != nil { - err := deps.WithTemplate(tmpl) - if err != nil { - tmpl.errors = append(tmpl.errors, &templateErr{"init", err}) - } - - } - - tmpl.MarkReady() - - return nil - -} - -// Clone clones -func (*TemplateProvider) Clone(d *deps.Deps) error { - - t := d.Tmpl.(*GoHTMLTemplate) - - // 1. Clone the clone with new template funcs - // 2. Clone any overlays with new template funcs - - tmpl := &GoHTMLTemplate{ - Template: template.Must(t.Template.Clone()), - overlays: make(map[string]*template.Template), - errors: make([]*templateErr, 0), - Deps: d, - } - - d.Tmpl = tmpl - tmpl.initFuncs(d) - - for k, v := range t.overlays { - vc := template.Must(v.Clone()) - // The extra lookup is a workaround, see - // * https://github.com/golang/go/issues/16101 - // * https://github.com/spf13/hugo/issues/2549 - vc = vc.Lookup(vc.Name()) - vc.Funcs(tmpl.funcster.funcMap) - tmpl.overlays[k] = vc - } - - tmpl.MarkReady() - - return nil -} - -func (t *GoHTMLTemplate) initFuncs(d *deps.Deps) { - - t.funcster = newTemplateFuncster(d) - - // The URL funcs in the funcMap is somewhat language dependent, - // so we need to wait until the language and site config is loaded. - t.funcster.initFuncMap() - - t.amberFuncMap = template.FuncMap{} - - amberMu.Lock() - for k, v := range amber.FuncMap { - t.amberFuncMap[k] = v - } - - for k, v := range t.funcster.funcMap { - t.amberFuncMap[k] = v - // Hacky, but we need to make sure that the func names are in the global map. - amber.FuncMap[k] = func() string { - panic("should never be invoked") - } - } - amberMu.Unlock() - -} - -func (t *GoHTMLTemplate) Funcs(funcMap template.FuncMap) { - t.Template.Funcs(funcMap) -} - -func (t *GoHTMLTemplate) Partial(name string, contextList ...interface{}) template.HTML { - if strings.HasPrefix("partials/", name) { - name = name[8:] - } - var context interface{} - - if len(contextList) == 0 { - context = nil - } else { - context = contextList[0] - } - return t.ExecuteTemplateToHTML(context, "partials/"+name, "theme/partials/"+name) -} - -func (t *GoHTMLTemplate) executeTemplate(context interface{}, w io.Writer, layouts ...string) { - var worked bool - for _, layout := range layouts { - templ := t.Lookup(layout) - if templ == nil { - layout += ".html" - templ = t.Lookup(layout) - } - - if templ != nil { - if err := templ.Execute(w, context); err != nil { - helpers.DistinctErrorLog.Println(layout, err) - } - worked = true - break - } - } - if !worked { - t.Log.ERROR.Println("Unable to render", layouts) - t.Log.ERROR.Println("Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations", layouts) - } -} - -func (t *GoHTMLTemplate) ExecuteTemplateToHTML(context interface{}, layouts ...string) template.HTML { - b := bp.GetBuffer() - defer bp.PutBuffer(b) - t.executeTemplate(context, b, layouts...) - return template.HTML(b.String()) -} - -func (t *GoHTMLTemplate) Lookup(name string) *template.Template { - - if templ := t.Template.Lookup(name); templ != nil { - return templ - } - - if t.overlays != nil { - if templ, ok := t.overlays[name]; ok { - return templ - } - } - - // The clone is used for the non-renderable HTML pages (p.IsRenderable == false) that is parsed - // as Go templates late in the build process. - if t.clone != nil { - if templ := t.clone.Lookup(name); templ != nil { - return templ - } - } - - return nil - -} - -func (t *GoHTMLTemplate) GetClone() *template.Template { - return t.clone -} - -func (t *GoHTMLTemplate) LoadEmbedded() { - t.EmbedShortcodes() - t.EmbedTemplates() -} - -// MarkReady marks the template as "ready for execution". No changes allowed -// after this is set. -func (t *GoHTMLTemplate) MarkReady() { - if t.clone == nil { - t.clone = template.Must(t.Template.Clone()) - } -} - -func (t *GoHTMLTemplate) checkState() { - if t.clone != nil { - panic("template is cloned and cannot be modfified") - } -} - -func (t *GoHTMLTemplate) AddInternalTemplate(prefix, name, tpl string) error { - if prefix != "" { - return t.AddTemplate("_internal/"+prefix+"/"+name, tpl) - } - return t.AddTemplate("_internal/"+name, tpl) -} - -func (t *GoHTMLTemplate) AddInternalShortcode(name, content string) error { - return t.AddInternalTemplate("shortcodes", name, content) -} - -func (t *GoHTMLTemplate) AddTemplate(name, tpl string) error { - t.checkState() - templ, err := t.New(name).Parse(tpl) - if err != nil { - t.errors = append(t.errors, &templateErr{name: name, err: err}) - return err - } - if err := applyTemplateTransformers(templ); err != nil { - return err - } - - return nil -} - -func (t *GoHTMLTemplate) AddTemplateFileWithMaster(name, overlayFilename, masterFilename string) error { - - // There is currently no known way to associate a cloned template with an existing one. - // This funky master/overlay design will hopefu |