{# The title block is rendered ONCE into page_title (a set-block capture,
verified to honour child overrides and super() on this Jinja version),
so
and og:title always agree without re-rendering the block.
A page names only itself there, and site_title() writes the one format
every public page shares, the page's name then the site name. A suffix
an older page still adds by hand is recognised and never doubled (see
titles.py). The description cascades from the page (meta_description,
with the older page_description spelling kept working) to the
product's tagline, and is omitted entirely when neither provides one. #}
{% set page_title %}{% block title %}{{ site.name }}{% endblock %}{% endset %}
{% set document_title = site_title(page_title | trim) %}
{% set meta_desc = meta_description | default(page_description, true) | default(site.tagline, true) %}
{{ document_title }}
{% if meta_desc %}{% endif %}
{# A page that sets noindex (the 404 does) is not one a crawler should
keep or a reader be led to: it tells robots so, links no canonical,
and further down the shell derives no trail from its address. #}
{% set noindex = noindex | default(false) %}
{% if noindex %}{% else %}{% endif %}
{% if meta_desc %}{% endif %}
{# Same rule as the canonical above: an address that leads nowhere is not
one to hand a crawler or a preview card. It also keeps every 404 byte
for byte the same page, which is what makes a withheld exam
indistinguishable from one that was never written. #}
{% if not noindex %}{% endif %}
{% if site.locale %}{% endif %}
{# og:image only when the product actually ships static/og.png; the theme
never fabricates one. Crawlers need an absolute URL. #}
{% if site.og_image %}
{% else %}
{% endif %}
{# The product's own icons, whichever files it ships (see theme.__init__). #}
{% for ic in site.icons %}
{% endfor %}
{% if theme_tokens and theme_tokens.font_url %}
{% endif %}
{# Feature stylesheets, declared via register_asset(); emitted in a
deterministic, deduplicated order (theme base ~0, features ~100, skins ~200). #}
{% for href in get_assets('css') %}
{% endfor %}
{% block head %}{% endblock %}
{% for hook in get_template_hooks("layout.head") %}{{ hook() | safe }}{% endfor %}
{% for hook in get_template_hooks("layout.body_start") %}{{ hook() | safe }}{% endfor %}
{# Any page can hand the shell a trail of {label, url} entries as
`breadcrumb`, and that explicit trail always wins. Every other page
gets a trail derived from the URL, the nav and the page's name,
governed by the site_breadcrumbs appearance setting (deep, all or
off), and no markup at all when the mode hides it. See
blocks/breadcrumb.html and the module docstrings of hooks.py and
breadcrumbs.py. #}
{%- if breadcrumb %}{{ render_block('breadcrumb', breadcrumb=breadcrumb) }}
{%- elif not noindex %}
{%- set auto_trail = auto_breadcrumb(page_title | trim, setting('site_breadcrumbs', config.get('SITE_BREADCRUMBS', 'deep'))) %}
{%- if auto_trail %}{{ render_block('breadcrumb', breadcrumb=auto_trail) }}{% endif %}
{%- endif %}
{# Messages a feature flashed before sending the reader here, such as a
signup that ends on the home page or a form that redirects after
saving. The page content is rendered first, into page_content, so a
message the page already shows in a box of its own (a contact form,
a login page) is not shown twice. The shell shows the rest under the
header. An error is announced at once (role alert), anything else
politely (role status). The content block stays defined here, so
pages that extend this layout keep working as before. #}
{%- set page_content %}{% block content %}{% endblock %}{% endset %}
{%- set flashes = namespace(shown=[]) %}
{%- for category, message in get_flashed_messages(with_categories=true) %}
{%- if not page_shows_flash(page_content, message) %}{% set flashes.shown = flashes.shown + [(category, message)] %}{% endif %}
{%- endfor %}
{%- if flashes.shown %}
{%- for category, message in flashes.shown %}
{%- set kind = 'danger' if category in ('danger', 'error') else (category if category in ('success', 'warning', 'info') else 'info') %}
{{ message }}
{%- endfor %}
{%- endif %}
{% for hook in get_template_hooks("layout.hero") %}{{ hook() | safe }}{% endfor %}
{% block hero %}{% endblock %}
{{ page_content }}
{# Feature scripts, declared via register_asset(); deferred, deduped, ordered. #}
{% for href in get_assets('js') %}
{% endfor %}
{% for hook in get_template_hooks("layout.scripts") %}{{ hook() | safe }}{% endfor %}
{% block scripts %}{% endblock %}