Includes

Include partial templates and components

3 min read 528 words

Include reusable template fragments (partials) in your templates.

Basic Include

{% include "partials/header.html" %}

<main>
    Content here
</main>

{% include "partials/footer.html" %}

Context Inheritance

Included templates have access to the current context, including loop variables and block-scoped{% set %}variables:

{# page.html #}
{% set user = get_current_user() %}
{% include "partials/user-card.html" %}
{# partials/user-card.html #}
<div class="user-card">
    <h3>{{ user.name }}</h3>
    <p>{{ user.email }}</p>
</div>

Loop Variables in Includes

Loop variables from{% for %}are visible inside included templates:

{# page.html #}
{% for item in items %}
    {% include "partials/item-card.html" %}
{% end %}
{# partials/item-card.html — item and loop are available #}
<div class="card">
    <span>{{ loop.index }}.</span>
    <h3>{{ item.name }}</h3>
</div>

This works for nested loops and tuple-unpacked variables too:

{% for key, value in entries %}
    {% include "partials/entry.html" %}
{% end %}

Passing Variables

Pass specific variables withwith:

{% include "components/button.html" with text="Click Me", url="/action" %}
{# components/button.html #}
<a href="{{ url }}" class="button">{{ text }}</a>

Isolated Context

Useonlyto include with an empty context:

{% include "components/widget.html" with title="Widget" only %}

The included template only sees title, not the parent context.

Ignore Missing

Skip if the template doesn't exist:

{% include "optional/sidebar.html" ignore missing %}

With fallback:

{% include ["theme/header.html", "default/header.html"] %}

Kida tries each template in order, using the first one found.

Dynamic Includes

Include based on a variable:

{% include component_name %}

{# Or with string concatenation #}
{% include "components/" + widget_type + ".html" %}

Include vs Extends

Aspect {% include %} {% extends %}
Purpose Embed a fragment Inherit structure
Context Shares parent context Isolated
Blocks Cannot override blocks Overrides blocks
Use case Components, partials Page layouts

Common Patterns

Component Library

templates/
├── components/
│   ├── button.html
│   ├── card.html
│   ├── modal.html
│   └── nav.html
└── pages/
    └── home.html
{# pages/home.html #}
{% include "components/nav.html" %}

<main>
    {% for item in items %}
        {% include "components/card.html" %}
    {% end %}
</main>

Conditional Includes

{% if user.is_admin %}
    {% include "admin/toolbar.html" %}
{% end %}

{% if show_sidebar %}
    {% include "partials/sidebar.html" %}
{% end %}

Loop Includes

{% for post in posts %}
    {% include "partials/post-card.html" %}
{% end %}

The loop variable post and loop context are automatically visible in the included template. You can still use withto pass additional variables if needed:

{% for post in posts %}
    {% include "partials/post-card.html" with show_date=True %}
{% end %}

Performance

Included templates are cached just like regular templates. The compilation cost is paid once, then reused.

# Templates are compiled once and cached
env = Environment(loader=FileSystemLoader("templates/"))
env.cache_info()  # Shows template cache stats

See Also