mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-17 21:01:26 +02:00
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
This commit is contained in:
@@ -281,8 +281,8 @@ urlize: bat-man
|
||||
v.Set("CurrentContentLanguage", helpers.NewLanguage("en", v))
|
||||
|
||||
config := newDepsConfig(v)
|
||||
config.WithTemplate = func(templ tpl.Template) error {
|
||||
if _, err := templ.New("test").Parse(in); err != nil {
|
||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||
if err := templ.AddTemplate("test", in); err != nil {
|
||||
t.Fatal("Got error on parse", err)
|
||||
}
|
||||
return nil
|
||||
@@ -2858,6 +2858,56 @@ func TestReadFile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPartialHTMLAndText(t *testing.T) {
|
||||
t.Parallel()
|
||||
config := newDepsConfig(viper.New())
|
||||
|
||||
data := struct {
|
||||
Name string
|
||||
}{
|
||||
Name: "a+b+c", // This should get encoded in HTML.
|
||||
}
|
||||
|
||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||
if err := templ.AddTemplate("htmlTemplate.html", `HTML Test Partial: {{ partial "test.foo" . -}}`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := templ.AddTemplate("_text/textTemplate.txt", `Text Test Partial: {{ partial "test.foo" . -}}`); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Use "foo" here to say that the extension doesn't really matter in this scenario.
|
||||
// It will look for templates in "partials/test.foo" and "partials/test.foo.html".
|
||||
if err := templ.AddTemplate("partials/test.foo", "HTML Name: {{ .Name }}"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := templ.AddTemplate("_text/partials/test.foo", "Text Name: {{ .Name }}"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
de, err := deps.New(config)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, de.LoadResources())
|
||||
|
||||
templ := de.Tmpl.Lookup("htmlTemplate.html")
|
||||
require.NotNil(t, templ)
|
||||
resultHTML, err := templ.ExecuteToString(data)
|
||||
require.NoError(t, err)
|
||||
|
||||
templ = de.Tmpl.Lookup("_text/textTemplate.txt")
|
||||
require.NotNil(t, templ)
|
||||
resultText, err := templ.ExecuteToString(data)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Contains(t, resultHTML, "HTML Test Partial: HTML Name: a+b+c")
|
||||
require.Contains(t, resultText, "Text Test Partial: Text Name: a+b+c")
|
||||
|
||||
}
|
||||
|
||||
func TestPartialCached(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := []struct {
|
||||
@@ -2893,7 +2943,7 @@ func TestPartialCached(t *testing.T) {
|
||||
|
||||
config := newDepsConfig(viper.New())
|
||||
|
||||
config.WithTemplate = func(templ tpl.Template) error {
|
||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||
err := templ.AddTemplate("testroot", tmp)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -2933,7 +2983,7 @@ func TestPartialCached(t *testing.T) {
|
||||
|
||||
func BenchmarkPartial(b *testing.B) {
|
||||
config := newDepsConfig(viper.New())
|
||||
config.WithTemplate = func(templ tpl.Template) error {
|
||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||
err := templ.AddTemplate("testroot", `{{ partial "bench1" . }}`)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -2965,7 +3015,7 @@ func BenchmarkPartial(b *testing.B) {
|
||||
|
||||
func BenchmarkPartialCached(b *testing.B) {
|
||||
config := newDepsConfig(viper.New())
|
||||
config.WithTemplate = func(templ tpl.Template) error {
|
||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||
err := templ.AddTemplate("testroot", `{{ partialCached "bench1" . }}`)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -3010,12 +3060,12 @@ func newTestFuncsterWithViper(v *viper.Viper) *templateFuncster {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return d.Tmpl.(*GoHTMLTemplate).funcster
|
||||
return d.Tmpl.(*templateHandler).html.funcster
|
||||
}
|
||||
|
||||
func newTestTemplate(t *testing.T, name, template string) *template.Template {
|
||||
func newTestTemplate(t *testing.T, name, template string) tpl.Template {
|
||||
config := newDepsConfig(viper.New())
|
||||
config.WithTemplate = func(templ tpl.Template) error {
|
||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||
err := templ.AddTemplate(name, template)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Reference in New Issue
Block a user