sphinx-jinja2

A sphinx extension to add the jinja directive, for rendering Jinja templates (powered by minijinja).

Note

This is an adaption of sphinx-jinja, which appears to be unmaintained.

Usage

PyPI

Simply install and add sphinx_jinja2 to your conf.py extensions list.

pip install sphinx-jinja2
extensions = [
    ...
    'sphinx_jinja2',
    ...
]

Guide

The most basic usage is to render an inline template using the jinja directive, where the ctx option is a JSON dict that will be passed to the template as the context:

Example 1

.. jinja::
    :ctx: {"name": "World"}

    Hallo {{ name }}!

Hallo World!

The Sphinx environment is also available by default as env:

Example 2

.. jinja::

    This is {{ env.config.project }} version {{ env.config.version }}.

This is sphinx-jinja2 version 0.1.0.

To set globally available variables, use the jinja2_contexts option in your conf.py, and refer to them by name as the first argument to the jinja directive:

Example 3

conf.py:
jinja2_contexts = {"ctx1": {"name": "World"}}
.. jinja:: ctx1

    Hallo {{ name }}!

Hallo World!

Templates from files

To load a template from a file, use the file option. Similar to the include directive, the path is relative to the source file that contains the directive, or relative to the source directory if the path starts with /. The file should always be encoded in UTF-8. If these files change then Sphinx will re-build pages that use them!

Example 4

templates/example1.jinja:
Hallo {{ name }}!
.. jinja::
    :file: templates/example1.jinja
    :ctx: {"name": "World"}

Hallo World!

Templates can include or extend other templates. Referenced templates are always relative to the source directory, and Sphinx will also correctly re-build pages that use them. Templates can never be loaded from outside the source directory (absolute paths and .. parent traversal are rejected).

Example 5

templates/example1.jinja:
Hallo {{ name }}!
.. jinja::
    :ctx: {"name": "World", "more": "content"}

    {% include "templates/example1.jinja" %}

    More {{ more }}!

Hallo World!

More content!

Headings in templates

Rendered templates are parsed within the context of the current document, and so heading levels are relative to the current document.

Example 6

.. jinja::

    Sub-heading
    ...........

    Content

Sub-heading

Content

If you need a generic template containing a heading, then perhaps use a context variable to specify the heading character:

Example 7

.. jinja::
    :ctx: {"heading_char": "."}

    Sub-heading
    {{ heading_char * 11 }}

    Content

Sub-heading

Content

Custom filters and tests

Custom filters and tests can be added to the environment, using the jinja2_filters and jinja2_tests configuration options. These map names to Python functions, or import strings of the form "module.path:func_name". Import strings are preferred, since Sphinx cannot cache function objects, meaning that full re-builds are always triggered.

Example 8

conf.py:
jinja2_tests = {"is_big": "my_module:is_big"}
.. jinja::
    :ctx: {"number": 200}

    {% if number is is_big %}{{ number }} is big!{% endif %}

200 is big!

Raw output

By default, the rendered template is parsed as source input, to instead output it as raw content of a given format, use the raw option:

Example 9

.. jinja::
    :ctx: {"name": "World"}
    :raw: html

    Hello <em>{{ name }}</em>!
Hello World!

MyST Markdown documents

The jinja directive can also be used within MyST Markdown documents, in which case the rendered template is parsed as MyST Markdown:

```{jinja}
:ctx: {"name": "World"}

Hello *{{ name }}*!
```

Debugging

To see the rendered templates in the built documentation, use the debug option for a single directive, or the jinja2_debug option in your conf.py to enable it globally:

Example 10

.. jinja::
    :ctx: {"name": "World"}
    :debug:

    Hallo **{{ name }}**!
Hallo **World**!

Hallo World!

Warning messages

Warning messages are displayed in the Sphinx build output, for problematic inputs, these all have the type jinja2, which can be used to suppress them in the Sphinx configuration:

suppress_warnings = ["jinja2"]

Since it is difficult / impossible to map the source line numbers, from the template to the Jinja rendered content:

  • In reStructuredText documents, problems with the parsing of the rendered content always refer to the first line number either of the jinja directive, or the template file (when using the file option).

  • In MyST Markdown documents, they refer to a line number within the rendered content, offset from the jinja directive (and with myst-parser >=5, they are always attributed to the document containing the directive, rather than the template file).

Migration from Jinja2

Since v0.1.0, templates are rendered using minijinja, a modern re-implementation of the Jinja template engine, rather than Jinja2. Most templates will render identically, but note the following differences:

  • jinja2_env_kwargs are now passed to minijinja.Environment. Common keyword arguments (trim_blocks, lstrip_blocks, keep_trailing_newline, custom delimiters, …) are unchanged; Jinja2-only arguments are ignored, with a warning.

  • Undefined variables raise errors (as previously, with StrictUndefined), but this can now be relaxed with jinja2_env_kwargs = {"undefined_behavior": "lenient"}.

  • None values are rendered as none rather than None (use {% if var %}{{ var }}{% endif %} guards if this matters).

  • A small number of Jinja2-only filters (e.g. wordwrap, urlize, xmlattr, center, wordcount) are not built in to minijinja; they can be re-added via jinja2_filters if required.

  • Custom filters and tests receive values as plain arguments; Jinja2’s @pass_context, @pass_environment and @pass_eval_context decorators are not supported by minijinja (such filters fail when the template is rendered, with a warning).

  • Python methods on objects (e.g. {{ "a,b".split(",") }}) continue to work, via minijinja’s Python compatibility mode.

Configuration

The following global configuration variables are available:

Configuration Options

jinja2_contexts:

A mapping of context names to context variables (default: {})

jinja2_env_kwargs:

Keyword arguments passed to minijinja.Environment (see https://github.com/mitsuhiko/minijinja/tree/main/minijinja-py) (default: {})

jinja2_filters:

A mapping of filter names to filter functions, or import strings like 'module.path:func_name' (preferred, since it is cacheable) (default: {})

jinja2_tests:

A mapping of test names to test functions, or import strings like 'module.path:func_name' (preferred, since it is cacheable) (default: {})

jinja2_debug:

Output the rendered template (default: False)