Skip to main content

Theme templates

Paligo uses up to four templates, all in the templates/ folder:

Template

Used for

Required

page.html.twig

Every topic page

Yes

portal.html.twig

The portal page, the site's front page

No

search.html.twig

The search results page

No

base.html.twig

Nothing directly. The others can extend it, so the page frame is written once

No

If the theme has no portal, search or base template, Paligo uses a plain built-in one. The search page is only produced when the layout has a search engine turned on.

Every other template, such as a partial for the header, can have any name and is used only when one of your templates includes it. Paligo checks every .twig file in the theme, including any that nothing uses.

A minimal theme

This page.html.twig produces a complete page:

<!doctype html>
<html lang="{{ site.lang }}"{% if site.dir %} dir="{{ site.dir }}"{% endif %}>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ page.title }} | {{ site.title }}</title>
    <link rel="stylesheet" href="{{ asset('css/main.css') }}">
    {{ paligo.head }}
</head>
<body>
    <main>
        <h1>{{ page.title }}</h1>
        {{ page.content }}
    </main>
    {{ paligo.foot }}
</body>
</html>

What every page needs

  • {{ paligo.head }} just before </head>. It adds the stylesheet for your content, the search setup, analytics, SEO tags and the layout's Custom &lt;head&gt; code.

  • {{ paligo.foot }} just before </body>. It adds the scripts for search, code copy buttons and glossary popovers, and the layout's Custom end-of-body code.

  • lang="{{ site.lang }}" on <html>. Search with several languages uses it to choose the right index.

  • dir="{{ site.dir }}" on <html> when site.dir is set, so right-to-left languages display correctly.

If a template leaves out paligo.head or paligo.foot, Paligo adds it before </head> or </body> itself and writes a warning in the publishing log. Place them yourself so that you control where they go.

Share a page frame between templates

Write the parts every page shares once in base.html.twig, and fill in the parts that differ with blocks:

templates/base.html.twig:

<!doctype html>
<html lang="{{ site.lang }}"{% if site.dir %} dir="{{ site.dir }}"{% endif %}>
<head>
    <meta charset="utf-8">
    <title>{% block title %}{{ page.title }} | {{ site.title }}{% endblock %}</title>
    <link rel="stylesheet" href="{{ asset('css/main.css') }}">
    {{ paligo.head }}
</head>
<body>
    {% include 'partials/header.html.twig' %}
    {% block content %}{% endblock %}
    {{ paligo.foot }}
</body>
</html>

templates/page.html.twig:

{% extends 'base.html.twig' %}

{% block content %}
    <main>
        <h1>{{ page.title }}</h1>
        {{ page.content }}
    </main>
{% endblock %}

Template names are relative to the templates/ folder.

HTML is escaped

Everything a template prints is HTML-escaped, so text from your content or the layout can't break the page. The values that already are HTML print as HTML without anything extra: page.content, paligo.head, paligo.foot and the output of the paligo_…() components.

Limits

Each page must finish rendering within 10 seconds. A template that includes itself, or a macro that calls itself without stopping, is stopped after 128 levels.