diff options
author | Bjørn Erik Pedersen <[email protected]> | 2017-03-27 20:43:49 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2017-04-02 11:37:30 +0200 |
commit | 5c5efa03d2512749950b0d05a7d4bde35ecbdc37 (patch) | |
tree | 9f3e31a7e30c51fab5ed3f7c323393fcafadc5e8 /tpl/tplimpl/template_ast_transformers.go | |
parent | 73c1c7b69d8302000fa5c5b804ad3eeac36da12f (diff) | |
download | hugo-5c5efa03d2512749950b0d05a7d4bde35ecbdc37.tar.gz hugo-5c5efa03d2512749950b0d05a7d4bde35ecbdc37.zip |
tpl: Rework to handle both text and HTML templates
Before this commit, Hugo used `html/template` for all Go templates.
While this is a fine choice for HTML and maybe also RSS feeds, it is painful for plain text formats such as CSV, JSON etc.
This commit fixes that by using the `IsPlainText` attribute on the output format to decide what to use.
A couple of notes:
* The above requires a nonambiguous template name to type mapping. I.e. `/layouts/_default/list.json` will only work if there is only one JSON output format, `/layouts/_default/list.mytype.json` will always work.
* Ambiguous types will fall back to HTML.
* Partials inherits the text vs HTML identificator of the container template. This also means that plain text templates can only include plain text partials.
* Shortcode templates are, by definition, currently HTML templates only.
Fixes #3221
Diffstat (limited to 'tpl/tplimpl/template_ast_transformers.go')
-rw-r--r-- | tpl/tplimpl/template_ast_transformers.go | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/tpl/tplimpl/template_ast_transformers.go b/tpl/tplimpl/template_ast_transformers.go index 339e2264a..bbd0f28a4 100644 --- a/tpl/tplimpl/template_ast_transformers.go +++ b/tpl/tplimpl/template_ast_transformers.go @@ -17,6 +17,7 @@ import ( "errors" "html/template" "strings" + texttemplate "text/template" "text/template/parse" ) @@ -35,32 +36,57 @@ var paramsPaths = [][]string{ } type templateContext struct { - decl decl - templ *template.Template - visited map[string]bool + decl decl + visited map[string]bool + lookupFn func(name string) *parse.Tree } -func (c templateContext) getIfNotVisited(name string) *template.Template { +func (c templateContext) getIfNotVisited(name string) *parse.Tree { if c.visited[name] { return nil } c.visited[name] = true - return c.templ.Lookup(name) + return c.lookupFn(name) } -func newTemplateContext(templ *template.Template) *templateContext { - return &templateContext{templ: templ, decl: make(map[string]string), visited: make(map[string]bool)} +func newTemplateContext(lookupFn func(name string) *parse.Tree) *templateContext { + return &templateContext{lookupFn: lookupFn, decl: make(map[string]string), visited: make(map[string]bool)} } -func applyTemplateTransformers(templ *template.Template) error { - if templ == nil || templ.Tree == nil { +func createParseTreeLookup(templ *template.Template) func(nn string) *parse.Tree { + return func(nn string) *parse.Tree { + tt := templ.Lookup(nn) + if tt != nil { + return tt.Tree + } + return nil + } +} + +func applyTemplateTransformersToHMLTTemplate(templ *template.Template) error { + return applyTemplateTransformers(templ.Tree, createParseTreeLookup(templ)) +} + +func applyTemplateTransformersToTextTemplate(templ *texttemplate.Template) error { + return applyTemplateTransformers(templ.Tree, + func(nn string) *parse.Tree { + tt := templ.Lookup(nn) + if tt != nil { + return tt.Tree + } + return nil + }) +} + +func applyTemplateTransformers(templ *parse.Tree, lookupFn func(name string) *parse.Tree) error { + if templ == nil { return errors.New("expected template, but none provided") } - c := newTemplateContext(templ) + c := newTemplateContext(lookupFn) - c.paramsKeysToLower(templ.Tree.Root) + c.paramsKeysToLower(templ.Root) return nil } @@ -84,7 +110,7 @@ func (c *templateContext) paramsKeysToLower(n parse.Node) { case *parse.TemplateNode: subTempl := c.getIfNotVisited(x.Name) if subTempl != nil { - c.paramsKeysToLowerForNodes(subTempl.Tree.Root) + c.paramsKeysToLowerForNodes(subTempl.Root) } case *parse.PipeNode: for i, elem := range x.Decl { |