mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-20 21:31:32 +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:
@@ -193,7 +193,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.Template) error) (*Site, error) {
|
||||
func NewSiteDefaultLang(withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
|
||||
v := viper.New()
|
||||
loadDefaultSettingsFor(v)
|
||||
return newSiteForLang(helpers.NewDefaultLanguage(v), withTemplate...)
|
||||
@@ -202,15 +202,15 @@ func NewSiteDefaultLang(withTemplate ...func(templ tpl.Template) error) (*Site,
|
||||
// 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.Template) error) (*Site, error) {
|
||||
func NewEnglishSite(withTemplate ...func(templ tpl.TemplateHandler) 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.Template) error) (*Site, error) {
|
||||
withTemplates := func(templ tpl.Template) error {
|
||||
func newSiteForLang(lang *helpers.Language, withTemplate ...func(templ tpl.TemplateHandler) error) (*Site, error) {
|
||||
withTemplates := func(templ tpl.TemplateHandler) error {
|
||||
for _, wt := range withTemplate {
|
||||
if err := wt(templ); err != nil {
|
||||
return err
|
||||
@@ -1911,14 +1911,14 @@ 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 {
|
||||
layout, found := s.findFirstLayout(layouts...)
|
||||
if !found {
|
||||
templ := s.findFirstTemplate(layouts...)
|
||||
if templ == nil {
|
||||
s.Log.WARN.Printf("[%s] Unable to locate layout for %s: %s\n", s.Language.Lang, name, layouts)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := s.renderThing(d, layout, w); err != nil {
|
||||
if err := templ.Execute(w, d); err != nil {
|
||||
|
||||
// Behavior here should be dependent on if running in server or watch mode.
|
||||
distinctErrorLogger.Printf("Error while rendering %q: %s", name, err)
|
||||
@@ -1933,23 +1933,13 @@ func (s *Site) renderForLayouts(name string, d interface{}, w io.Writer, layouts
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Site) findFirstLayout(layouts ...string) (string, bool) {
|
||||
func (s *Site) findFirstTemplate(layouts ...string) tpl.Template {
|
||||
for _, layout := range layouts {
|
||||
if s.Tmpl.Lookup(layout) != nil {
|
||||
return layout, true
|
||||
if templ := s.Tmpl.Lookup(layout); templ != nil {
|
||||
return templ
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Site) publish(path string, r io.Reader) (err error) {
|
||||
|
Reference in New Issue
Block a user