Question about "define" warning in documentation

Hi,

I noticed a new warning in the go-template/define documentation introduced in 0015e7a:

[!warning]
Only [template comments] are allowed outside of the define and end statements. Avoid placing any other text, including HTML comments, outside of these boundaries. Doing so will cause rendering issues, potentially resulting in a blank page. See the example below.

I’ve been using define blocks together with regular HTML rendering in the same file. Based on this new warning, does that mean those templates are now considered invalid?

If so, what’s the recommended way to fix this?

Here are a couple of examples for context:

basic.html

render-image.html

Thanks in advance!

The warning is about HTML comments, not about standard HTML elements.

Thanks, but the warning says “any other text, including HTML comments,” and the example shows that even a plain <div> breaks the template. So it’s not just about HTML comments.

Thank you for bringing this to my attention. We need to refine the warning, describing the conditions under which the problem occurs.

https://github.com/gohugoio/hugoDocs/issues/3133

Here’s a simple example with two template types: base and home. The home template contains HTML before the define statement, triggering the problem.

git clone --single-branch -b hugo-forum-topic-55289 https://github.com/jmooring/hugo-testing hugo-forum-topic-55289
cd hugo-forum-topic-55289
hugo server

Also note that the warning has existed elsewhere in the documentation for a long time. The commit you reference moved the warning from a page that was deleted in the same PR.

At the moment I’m struggling with how to properly word this, but the warning applies when a base template (e.g., baseof.html) contains one or more block templates that are redefined within a page template (e.g., home.html, page.html, section.html, taxonomy.html, or term.html). In this case, the page template must not include anything other than template comments outside of its define/end blocks. That may not be precise, but I think it’s close.

Reference: https://pkg.go.dev/text/template#hdr-Nested_template_definitions

When parsing a template, another template may be defined and associated with the template being parsed. Template definitions must appear at the top level of the template, much like global variables in a Go program.

The last sentence does not seem to apply to Hugo’s implementation where you can define the template after the template call.

I also searched the Go issue queue for open and closed issues related to the text/template and html/template packages but couldn’t find anything to help me understand the limitation.

@bep Your comments/suggestions are welcome. I understand this is a Go templating limitation, and you have a much better understanding of that.

I don’t think that’s what they mean by that sentence (or I may misunderstand you). So this is OK:

{{ printf "foo" }}
{{ define "bar" }}
   asdfasf
{{ end }}

This is NOT OK:

{{ with .Foo }}
  {{ define "bar" }}
     asdfasf
  {{ end }}
{{ end }}

As to defines for base blocks (e.g. main), the current limitation in Hugo is just about making the “does this template need a base template?” relatively simple:

Thanks, that is exactly what I needed.

1 Like

So my code is fine then?

Pretty sure the original warning was for block, so does this only apply to define used with block?

Yes.

I’ve removed the warning from the define page and rewritten the description of base templates.

The important part:

A base template can be applied to these template types: home, page, section, taxonomy, term, single, list, and all. When Hugo parses any of these template types, it will apply a base template if the template being parsed meets these specific criteria:

  • It must begin with a define action.
  • This define action can optionally be preceded by a template comment or whitespace.
  • The template must only contain define actions.

If the template does not satisfy all the criteria, it will be executed exactly as provided, without the application of a base template.

Consider this base template:

layouts/baseof.html
<!DOCTYPE html>
<html lang="{{ site.Language.LanguageCode }}" dir="{{ or site.Language.LanguageDirection `ltr` }}">
<head>
  {{ partial "head.html" . }}
</head>
<body>
  <header>
    {{ partial "header.html" . }}
  </header>
  <main>
    {{ block "title" . }}{{ end }}
    {{ block "content" . }}{{ end }}
  </main>
  <footer>
    {{ partial "footer.html" . }}
  </footer>
</body>
</html>

And these section templates:

layouts/section.html (example 1)
xxx

{{ define "title" }}
  <h1>{{ .Title }}</h1>
{{ end }}

{{ define "content" }}
  {{ .Content }}
  {{ range .Pages }}
    <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
  {{ end }}
{{ end }}

layouts/section.html (example 2)
{{ define "title" }}
  <h1>{{ .Title }}</h1>
{{ end }}

xxx

{{ define "content" }}
  {{ .Content }}
  {{ range .Pages }}
    <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
  {{ end }}
{{ end }}

layouts/section.html (example 3)
{{ define "title" }}
  <h1>{{ .Title }}</h1>
{{ end }}

{{ define "content" }}
  {{ .Content }}
  {{ range .Pages }}
    <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
  {{ end }}
{{ end }}

xxx

In all cases Hugo renders the section pages like this:

xxx

The base template was obviously not applied to any of the section template examples.

It doesn’t matter if you replace the string xxx with a template action such as {{ .Kind }}. Again, in all cases, Hugo will not apply the base template because one or more of the criteria has not been met.

@bep Please comment if you’d care to tweak this. I tested all three examples above.

Thanks @jmooring and @bep for the clarification, and for your continued dedication to maintaining the project!

maybe another language barrier: but for me that sound like you may not have any more comments at the top level.

with my tests template comments are also allowed after the first define

{{/* content block */}}
{{ define "main" }}
   <h1>{{ .Title }}</h1>
{{ end }}

{{/* just some foo */}}
{{ define "foo" }}
   <h2>foo</h2>
{{ end }}

{{/* following some bar */}}
{{ define "bar" }}
   <h2>bar</h2>
{{ end }}
{{/* finally we are done */}}

what about:

  • The template only contains define actions and template comments
  • The template must contain at least one define action

I’ve updated the criteria per your comments above:
https://gohugo.io/templates/types/#base

3 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.