Choosing a template
Four steps, in order, and no cascade
A page is rendered with the first of these that exists:
- the
templatenamed in the page's front matter section.html, if the page is a section index- the
page_templateset on the parent section's_index.md page.html
That is the whole rule. Naming a template that does not exist is an error,
and the message lists the templates you do have.
Why it is four steps and not twenty
Hugo resolves templates through a lookup order built from kind × section × type × layout × language × output format. It is more powerful, and it is the single thing Hugo users get lost in most often — there is a decade-old request open asking the tool to at least print which template it picked.
Four steps you can hold in your head need no such command. If you cannot tell which template rendered a page, the rule is too complicated.
Setting a section's default
# content/blog/_index.md
+++
= "Blog"
= "post.html"
+++
Every page in content/blog/ now renders with post.html unless it names its
own. Note that this reaches direct children only; a subsection sets its own.
Extending a base
The usual arrangement is one skeleton and thin templates on top:
{# templates/base.html #}
<!doctype html>
{{ page.title }}
{% block content %}{% endblock %}
{# templates/page.html #}
{% extends "base.html" %}
{% block content %}{{ page.content | safe }}{% endblock %}