Where Content Meets Templates—and Trust

Hugo's renderer receives assembled page state, but it still has to answer three concrete questions: what data is in scope, which template should run, and how should content be transformed without crossing an unintended trust boundary? This chapter follows that handoff from template context through lookup, Markdown rendering, shortcodes, and output policy. Understanding it lets you debug a wrong title, a missing layout, a changed table of contents, or an unsafe markup decision as a mechanism rather than a mystery.

The page graph supplies the material; the template system supplies the transformation. Those roles are deliberately separate. Content authors can write a page without embedding its entire presentation, while project authors can change presentation without copying every page. The separation works only if the boundaries between context, selection, transformation, and trust remain clear.

Context determines what a template can see

Hugo templates use Go's template packages. A page template normally receives a Page object as its data, and the dot—.—stands for the current context. A reference such as .Title therefore asks the current page for its title, while .Site reaches the site that contains it.

The current context is not fixed for the lifetime of a template. Inside a range block, the dot becomes the item being iterated. If a template ranges over pages, the dot is now one page at a time; if it ranges over resources, the dot is a resource. Inside a with block, the dot becomes the value that passed the block's truth test. This is a small syntax rule with a large practical consequence: a template can still be valid while asking the wrong object for a field.

The dollar sign preserves the outer context. If a page template ranges over a collection and needs both the current item and the original page, it can use the inner dot for the item and $ for the page context. The rule is easier to remember as a state transition: range and with rebind the dot; $ remains attached to the top-level context.

This context model supports composition. A partial receives a context explicitly, and the calling template decides whether to pass the page, a site, a resource, or a smaller value. A partial that expects a page cannot safely be given a resource merely because both are represented by a dot. The interface is implicit in the data passed at the call site, so keeping context intentional is part of template correctness.

The same context can expose methods rather than raw fields. A page can provide its title, parameters, resources, terms, or output formats; a site can provide its configuration and data. Templates can use functions to transform values and methods to query objects. This turns a page template into a controlled view over the graph rather than a direct read of arbitrary files.

Lookup turns many layouts into a deterministic choice

A project often has a default layout, a section-specific layout, a theme layout, and perhaps a specialized layout for one content type or output format. Hugo resolves that apparent abundance through a specificity-based lookup order. It considers the page kind, an explicitly selected layout, output format, language, content type, and section.