Templating

Templates are inherited, so if you call a template that isn't defined in your theme but exist in a parent theme, the parent template will be loaded.

Each theme defines a templates folder in its getTemplatesFolder() method which is relative to the theme base path. By default this equals to templates.

Layouts in Pro version

You can set any templates to your category groups and sections, if a layout matches for that request, the layout associated will be added to the variables. In your template you simply need to call {{ layout.renderRegions() }}. The view mode for such a request is always the default one.

For convenience a default page template is defined in this plugin : themed_page, see here, this template could be used in every section/category, and can be overridden.

There are two ways to render layouts: regions or displays. The method Layout::render(Element $element, string $viewMode) will render the displays, the other Layout::renderRegions() the regions.

Rendering the regions will call a special template defined by the theme in ThemePlugin::getRegionsTemplate(), by default this equals to regions.

Template naming (Pro)

Each element of the page (layouts, regions, blocks, field and file displayers) templates can be overridden by your themes using a specific folder structure that allows much granularity. These folder structures are defined below, they are ordered from most to less specific where the most specific will be loaded first if found.

The following variables mentioned in folder structures are defined as :

  •  {type}: The layout type, user, tag, category, global, entry, product, variant, volume or custom
  •  {viewMode}: The rendered view mode's handle

Entry layouts

Entry layouts will define more templates as they define two keys, {section} the handle of the section, and {entryType} the handle of the entry type.

Rendering layouts (displays mode):

layouts/{type}_{section}-{entryType}_{viewMode}.twig
layouts/{type}_{section}_{viewMode}.twig
layouts/{type}_{section}-{entryType}.twig
layouts/{type}_{section}.twig
layouts/{type}.twig
layouts/layout.twig

Rendering regions:

regions/{type}_{section}-{entryType}_region-{handle}.twig
regions/{type}_{section}_region-{handle}.twig
regions/{type}_{section}-{entryType}_region.twig
regions/{type}_{section}_region.twig
regions/{type}_region-{handle}.twig
regions/{type}_region.twig
regions/region-{handle}.twig
regions/region.twig

Where {handle} is the region's handle

blocks/{type}_{section}-{entryType}_{region}_{handle}.twig
blocks/{type}_{section}_{region}_{handle}.twig
blocks/{type}_{section}-{entryType}_{handle}.twig
blocks/{type}_{section}_{handle}.twig
blocks/{type}_{handle}.twig
blocks/{handle}.twig

Where {handle} is the machine name of the block. A block latestBlogs of a provider system will be system-latestBlogs

Where {region} is the handle of the region the block is in.

Rendering fields:

fields/{type}_{section}-{entryType}_{viewMode}_{displayer}_{field}.twig
fields/{type}_{section}_{viewMode}_{displayer}_{field}.twig
fields/{type}_{section}-{entryType}_{viewMode}_{displayer}.twig
fields/{type}_{section}_{viewMode}_{displayer}.twig
fields/{type}_{section}-{entryType}_{displayer}_{field}.twig
fields/{type}_{section}_{displayer}_{field}.twig
fields/{type}_{section}-{entryType}_{displayer}.twig
fields/{type}_{section}_{displayer}.twig
fields/{type}_{displayer}_{field}.twig
fields/{type}_{displayer}.twig
fields/{displayer}_{field}.twig
fields/{displayer}.twig

Where {displayer} is the handle of the field displayer.

Where {field} is the handle of the field.

Rendering files:

files/{type}_{section}-{entryType}_{viewMode}_{displayer}_{field}.twig
files/{type}_{section}_{viewMode}_{displayer}_{field}.twig
files/{type}_{section}-{entryType}_{viewMode}_{displayer}.twig
files/{type}_{section}_{viewMode}_{displayer}.twig
files/{type}_{section}-{entryType}_{displayer}_{field}.twig
files/{type}_{section}_{displayer}_{field}.twig
files/{type}_{section}-{entryType}_{displayer}.twig
files/{type}_{section}_{displayer}.twig
files/{type}_{displayer}_{field}.twig
files/{type}_{displayer}.twig
files/{displayer}_{field}.twig
files/{displayer}.twig

Where {displayer} is the handle of the file displayer.

Where {field} is the handle of the field.

Rendering groups:

groups/{type}_{section}-{entryType}_{viewMode}_group-{handle}.twig
groups/{type}_{section}_{viewMode}_group-{handle}.twig
groups/{type}_{section}-{entryType}_{viewMode}_group.twig
groups/{type}_{section}_{viewMode}_group.twig
groups/{type}_{section}-{entryType}_group-{handle}.twig
groups/{type}_{section}_group-{handle}.twig
groups/{type}_{section}-{entryType}_group.twig
groups/{type}_{section}_group.twig
groups/{type}_group-{handle}.twig
groups/{type}_group.twig
groups/group-{handle}.twig
groups/group.twig

Where {handle} is the group's handle.

All other layouts

The mentionned key variable is defined as such :

  • For a user: user
  • For a category/volume/tag/global/product layout it will be the handle of the associated category group/volume/tag group/global set/product type
  • For a custom layout, the handle of the layout

Rendering layouts (displays mode):

layouts/{type}_{key}_{viewMode}.twig
layouts/{type}_{key}.twig
layouts/{type}.twig
layouts/layout.twig

Rendering regions:

regions/{type}_{key}_region-{handle}.twig
regions/{type}_{key}_region.twig
regions/{type}_region-{handle}.twig
regions/{type}_region.twig
regions/region-{handle}.twig
regions/region.twig

Where {handle} is the region's handle

Rendering blocks:

blocks/{type}_{key}_{region}_{handle}.twig
blocks/{type}_{key}_{handle}.twig
blocks/{type}_{handle}.twig
blocks/{handle}.twig

Where {handle} is the machine name of the block. A block latestBlogs of a provider system will be system-latestBlogs

Where {region} is the handle of the region the block is in

Rendering fields:

fields/{type}_{key}_{viewMode}_{displayer}_{field}.twig
fields/{type}_{key}_{viewMode}_{displayer}.twig
fields/{type}_{key}_{displayer}_{field}.twig
fields/{type}_{key}_{displayer}.twig
fields/{type}_{displayer}_{field}.twig
fields/{type}_{displayer}.twig
fields/{displayer}_{field}.twig
fields/{displayer}.twig

Where {displayer} is the handle of the field displayer.

Where {field} is the handle of the field.

Rendering files:

files/{type}_{key}_{viewMode}_{displayer}_{field}.twig
files/{type}_{key}_{viewMode}_{displayer}.twig
files/{type}_{key}_{displayer}_{field}.twig
files/{type}_{key}_{displayer}.twig
files/{type}_{displayer}_{field}.twig
files/{type}_{displayer}.twig
files/{displayer}_{field}.twig
files/{displayer}.twig

Where {displayer} is the handle of the file displayer.

Where {field} is the handle of the field.

Rendering groups:

groups/{type}_{key}_{viewMode}_group-{handle}.twig
groups/{type}_{key}_{viewMode}_group.twig
groups/{type}_{key}_group-{handle}.twig
groups/{type}_{key}_group.twig
groups/{type}_group-{handle}.twig
groups/{type}_group.twig
groups/group-{handle}.twig
groups/group.twig

Where {handle} is the group's handle.

Global variables & tests

Available variables :

craft.themes.layouts : Layouts service

craft.themes.viewModes : View mode service

craft.themes.registry : Theme registry

craft.themes.view : Theme view service

craft.themes.current : Current theme

Tests :

Array test : {% if variable is array %}

Numeric test : {% if variable is numeric %}

Instance of test : {% if variable is instanceof "My\\Namespaced\\Class" %}

Events (Pro)

More templates and variables can be defined by listening to events on the ViewService class :

  • Layouts : event BEFORE_RENDERING_LAYOUT
  • Files : event BEFORE_RENDERING_FILE
  • Fields : event BEFORE_RENDERING_FIELD
  • Blocks : event BEFORE_RENDERING_BLOCK
  • Regions : event BEFORE_RENDERING_REGION
  • Groups : event BEFORE_RENDERING_GROUP

Example :

Event::on(
    ViewService::class,
    ViewService::BEFORE_RENDERING_FILE,
    function (RenderEvent $event) {
        $event->prependTemplate('myTemplate')
        ->addVariable('myVar', 'myValue');
});

Those events can also be used to modify elements's classes and attributes :

Event::on(
    ViewService::class,
    ViewService::BEFORE_RENDERING_FILE,
    function (RenderEvent $event) {
        $e->variables['classes']->add(['my-class', 'my-other-class']);
        $e->variables['attributes']->add('id', 'my-id');
        $e->variables['containerClasses']->add('container-class');
        $e->variables['containerAttributes']->add('id', 'container-id');
        $e->variables['labelClasses']->remove('label-class');
        $e->variables['labelAttributes']->remove('label-id');
});

Or to skip the rendering of any element :

Event::on(
    ViewService::class,
    ViewService::BEFORE_RENDERING_FILE,
    function (RenderEvent $event) {
        $event->render = false;
});

Root templates folder

It is recommended to not use the root templates folder when using themes, if some templates are defined both in this folder and in a theme, the root templates folder will take precedence.

Other plugins templates

A theme can't override templates that have a namespace (ie other plugin templates), unless they register their templates roots with the '' (empty string) key.

You must enable javascript to view this website