`_ on the wrapping template
With Jinja2 Fragments, you can:
1. Define all blocks in a single template file
2. Render the full template when needed
3. Render specific blocks from that template when needed
This approach is especially useful when working with htmx or similar libraries that fetch partial HTML content.
Simple Block Rendering
======================
Let's start with a basic example using vanilla Jinja2. Consider the following template ``page.html.jinja2``:
.. code-block:: html
This is the title
This is a header
{% block content %}
This is the magic number: {{ magic_number }}.
{% endblock %}
If you want to render only the ``content`` block, you can use ``render_block`` like this:
.. code-block:: python
from jinja2 import Environment, FileSystemLoader, select_autoescape
from jinja2_fragments import render_block
environment = Environment(
loader=FileSystemLoader("my_templates"),
autoescape=select_autoescape(("html", "jinja2")),
)
rendered_html = render_block(
environment, "page.html.jinja2", "content", magic_number=42
)
This will only render:
.. code-block:: html
This is the magic number: 42.
.. note::
The ``render_block`` function takes the same arguments as Jinja2's ``render_template`` function,
plus an additional argument for the block name to render.
Multiple Blocks Rendering
=========================
Jinja2 Fragments also allows you to render multiple blocks at once with the ``render_blocks`` function (notice the plural):
.. code-block:: python
from jinja2 import Environment, FileSystemLoader, select_autoescape
from jinja2_fragments import render_blocks
environment = Environment(
loader=FileSystemLoader("my_templates"),
autoescape=select_autoescape(("html", "jinja2")),
)
rendered_html = render_blocks(
environment, "page.html.jinja2", ["header", "content"], magic_number=42
)
.. note::
Rendering multiple blocks is particularly useful for implementing `out-of-band updates `_
when using htmx, allowing you to update multiple parts of a page in a single request.
Rendering Blocks from Within Templates
======================================
You can also call ``render_block`` and ``render_blocks`` directly from within
Jinja2 template expressions. This is useful when a template needs to compose
fragments from other template files.
To enable this, call :func:`~jinja2_fragments.setup_globals` on your Jinja2
environment:
.. code-block:: python
from jinja2 import Environment, FileSystemLoader, select_autoescape
from jinja2_fragments import setup_globals
environment = Environment(
loader=FileSystemLoader("my_templates"),
autoescape=select_autoescape(("html", "jinja2")),
)
setup_globals(environment)
Once installed, you can use ``render_block`` and ``render_blocks`` in any
template rendered with that environment:
.. code-block:: html
{{ render_block("customer/edit.html.jinja2", "customer", customer=invoice.customer) }}
{# Render multiple blocks at once #}
{{ render_blocks("dashboard.html.jinja2", ["stats", "chart"], user=user) }}
The current template context is automatically forwarded to the rendered block(s).
Any keyword arguments you pass will override individual context variables.
.. note::
``setup_globals`` automatically selects the correct sync or async
implementation based on ``environment.is_async``, so it works with both
synchronous and asynchronous environments.
Existing globals named ``render_block`` and ``render_blocks`` are preserved.