Partials & Includes

Partials are reusable template fragments included into other templates. They inherit all variables from the including template automatically.

Including a Partial

{% include "partials/post-card.tpl" %}
{% include "partials/pagination.tpl" %}
{% include "PluginsMyPluginViewsstore\_card.tpl" %}

Paths are relative to the theme's views/ directory. For plugin templates, use the full path.

Variable Scope

Partials inherit all variables from the including template. No explicit passing needed. partials/author-card.tpl can access {{ author_profile }} because it is included from post.tpl where that variable exists.

Standard Partials

post-card.tpl — Blog listing card

<article class="{{ cls.cls_card }} mb-4">
    {% if post.featured_image %}
    <img src="{{ post.featured_image }}" class="{{ cls.cls_card_img_top }}" alt="{{ post.title }}">
    {% endif %}
    <div class="{{ cls.cls_card_body }}">
        <h2><a href="{! post_url post.slug !}">{{ post.title }}</a></h2>
        <p class="{{ cls.cls_text_muted }}">{{ post.published_at | date "F j, Y" }}</p>
        <p>{{ post.excerpt }}</p>
        <a href="{! post_url post.slug !}" class="{{ cls.cls_btn_primary }} {{ cls.cls_btn_sm }}">
            {! lang "Blog.read_more" !}
        </a>
    </div>
</article>

pagination.tpl — Pager controls

{% if pager %}
<nav>{! pager !}</nav>
{% endif %}

_comment.tpl — Single comment (recursive)

<div class="{{ cls.cls_card }} {{ cls.cls_mb_3 }}" id="comment-{{ comment.id }}">
    <div class="{{ cls.cls_card_body }}">
        <strong>{{ comment.author_name }}</strong>
        <small>{{ comment.created_at | date "M j, Y" }}</small>
        <p>{{ comment.body | nl2br }}</p>
        {% if comment.replies | count > 0 %}
        <div style="margin-left:2rem">
            {% for comment in comment.replies %}{% include "partials/_comment.tpl" %}{% endfor %}
        </div>
        {% endif %}
    </div>
</div>

comment-form.tpl — Comment submission form

<form method="post" action="{! site_url "comments/store" !}">
    {! csrf_field !}
    <input type="hidden" name="post_id" value="{{ post.id }}">
    <div class="{{ cls.cls_mb_3 }}">
        <label class="{{ cls.cls_form_label }}">{! lang "Blog.your_name" !}</label>
        <input type="text" name="author_name" class="{{ cls.cls_form_control }}" required>
    </div>
    <div class="{{ cls.cls_mb_3 }}">
        <textarea name="body" class="{{ cls.cls_form_control }}" rows="5" required></textarea>
    </div>
    <button type="submit" class="{{ cls.cls_btn_primary }}">{! lang "Blog.submit_comment" !}</button>
</form>

Naming Conventions

ConventionPurpose
Leading underscore (_comment.tpl)Sub-partials included from other partials
partials/ subdirectoryAll partials live here
Lowercase with hyphensFile naming convention