<commit_before>Template Designer Documentation
===============================

.. highlight:: html+jinja

This document describes the syntax and semantics of the template engine and
will be most useful as reference to those creating Jinja templates.  As the
template engine is very flexible the configuration from the application might
be slightly different from here in terms of delimiters and behavior of
undefined values.


Synopsis
--------

A template is simply a text file.  It can generate any text-based format
(HTML, XML, CSV, LaTeX, etc.).  It doesn't have a specific extension,
``.html`` or ``.xml`` are just fine.

A template contains **variables** or **expressions**, which get replaced with
values when the template is evaluated, and tags, which control the logic of
the template.  The template syntax is heavily inspired by Django and Python.

Below is a minimal template that illustrates a few basics.  We will cover
the details later in that document::

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html lang="en">
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <ul id="navigation">
        {% for item in navigation %}
            <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
        {% endfor %}
        </ul>

        <h1>My Webpage</h1>
        {{ a_variable }}
    </body>
    </html>

This covers the default settings.  The application developer might have
changed the syntax from ``{% foo %}`` to ``<% foo %>`` or something similar.

There are two kinds of delimiters. ``{% ... %}`` and ``{{ ... }}``.  The first
one is used to execute statements such as for-loops or assign values, the
latter prints the result of the expression to the template.

.. _variables:

Variables
---------

The application passes variables to the templates you can mess around in the
template.  Variables may have attributes or elements on them you can access
too.  How a variable looks like, heavily depends on the application providing
those.

You can use a dot (``.``) to access attributes of a variable, alternative the
so-called "subscript" syntax (``[]``) can be used.  The following lines do
the same::

    {{ foo.bar }}
    {{ foo['bar'] }}

It's important to know that the curly braces are *not* part of the variable
but the print statement.  If you access variables inside tags don't put the
braces around.

If a variable or attribute does not exist you will get back an undefined
value.  What you can do with that kind of value depends on the application
configuration, the default behavior is that it evaluates to an empty string
if printed and that you can iterate over it, but every other operation fails.

.. _notes-on-subscriptions:

.. admonition:: Implementation

    For convenience sake ``foo.bar`` in Jinja2 does the following things on
    the Python layer:

    -   check if there is an attribute called `bar` on `foo`.
    -   if there is not, check if there is an item ``'bar'`` in `foo`.
    -   if there is not, return an undefined object.

    ``foo['bar']`` on the other hand works mostly the same with the a small
    difference in the order:

    -   check if there is an item ``'bar'`` in `foo`.
    -   if there is not, check if there is an attribute called `bar` on `foo`.
    -   if there is not, return an undefined object.

    This is important if an object has an item or attribute with the same
    name.  Additionally there is the :func:`attr` filter that just looks up
    attributes.

.. _filters:

Filters
-------

Variables can be modified by **filters**.  Filters are separated from the
variable by a pipe symbol (``|``) and may have optional arguments in
parentheses.  Multiple filters can be chained.  The output of one filter is
applied to the next.

``{{ name|striptags|title }}`` for example will remove all HTML Tags from the
`name` and title-cases it.  Filters that accept arguments have parentheses
around the arguments, like a function call.  This example will join a list
by commas:  ``{{ list|join(', ') }}``.

The :ref:`builtin-filters` below describes all the builtin filters.

.. _tests:

Tests
-----

Beside filters there are also so called "tests" available.  Tests can be used
to test a variable against a common expression.  To test a variable or
expression you add `is` plus the name of the test after the variable.  For
example to find out if a variable is defined you can do ``name is defined``
which will then return true or false depending on if `name` is defined.

Tests can accept arguments too.  If the test only takes one argument you can
leave out the parentheses to group them.  For example the following two
expressions do the same::

    {% if loop.index is divisibleby 3 %}
    {% if loop.index is divisibleby(3) %}

The :ref:`builtin-tests` below describes all the builtin tests.


Comments
--------

To comment-out part of a line in a template, use the comment syntax which is
by default set to ``{# ... #}``.  This is useful to comment out parts of the
template for debugging or to add information for other template designers or
yourself::

    {# note: disabled template because we no longer use this
        {% for user in users %}
            ...
        {% endfor %}
    #}


Whitespace Control
------------------

In the default configuration whitespace is not further modified by the
template engine, so each whitespace (spaces, tabs, newlines etc.) is returned
unchanged.  If the application configures Jinja to `trim_blocks` the first
newline after a a template tag is removed automatically (like in PHP).

But you can also strip whitespace in templates by hand.  If you put an minus
sign (``-``) to the start or end of an block (for example a for tag), a
comment or variable expression you can remove the whitespaces after or before
that block::
<commit_msg>Improve whitespace docs to reflect reality.<commit_after>Template Designer Documentation
===============================

.. highlight:: html+jinja

This document describes the syntax and semantics of the template engine and
will be most useful as reference to those creating Jinja templates.  As the
template engine is very flexible the configuration from the application might
be slightly different from here in terms of delimiters and behavior of
undefined values.


Synopsis
--------

A template is simply a text file.  It can generate any text-based format
(HTML, XML, CSV, LaTeX, etc.).  It doesn't have a specific extension,
``.html`` or ``.xml`` are just fine.

A template contains **variables** or **expressions**, which get replaced with
values when the template is evaluated, and tags, which control the logic of
the template.  The template syntax is heavily inspired by Django and Python.

Below is a minimal template that illustrates a few basics.  We will cover
the details later in that document::

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html lang="en">
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <ul id="navigation">
        {% for item in navigation %}
            <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
        {% endfor %}
        </ul>

        <h1>My Webpage</h1>
        {{ a_variable }}
    </body>
    </html>

This covers the default settings.  The application developer might have
changed the syntax from ``{% foo %}`` to ``<% foo %>`` or something similar.

There are two kinds of delimiters. ``{% ... %}`` and ``{{ ... }}``.  The first
one is used to execute statements such as for-loops or assign values, the
latter prints the result of the expression to the template.

.. _variables:

Variables
---------

The application passes variables to the templates you can mess around in the
template.  Variables may have attributes or elements on them you can access
too.  How a variable looks like, heavily depends on the application providing
those.

You can use a dot (``.``) to access attributes of a variable, alternative the
so-called "subscript" syntax (``[]``) can be used.  The following lines do
the same::

    {{ foo.bar }}
    {{ foo['bar'] }}

It's important to know that the curly braces are *not* part of the variable
but the print statement.  If you access variables inside tags don't put the
braces around.

If a variable or attribute does not exist you will get back an undefined
value.  What you can do with that kind of value depends on the application
configuration, the default behavior is that it evaluates to an empty string
if printed and that you can iterate over it, but every other operation fails.

.. _notes-on-subscriptions:

.. admonition:: Implementation

    For convenience sake ``foo.bar`` in Jinja2 does the following things on
    the Python layer:

    -   check if there is an attribute called `bar` on `foo`.
    -   if there is not, check if there is an item ``'bar'`` in `foo`.
    -   if there is not, return an undefined object.

    ``foo['bar']`` on the other hand works mostly the same with the a small
    difference in the order:

    -   check if there is an item ``'bar'`` in `foo`.
    -   if there is not, check if there is an attribute called `bar` on `foo`.
    -   if there is not, return an undefined object.

    This is important if an object has an item or attribute with the same
    name.  Additionally there is the :func:`attr` filter that just looks up
    attributes.

.. _filters:

Filters
-------

Variables can be modified by **filters**.  Filters are separated from the
variable by a pipe symbol (``|``) and may have optional arguments in
parentheses.  Multiple filters can be chained.  The output of one filter is
applied to the next.

``{{ name|striptags|title }}`` for example will remove all HTML Tags from the
`name` and title-cases it.  Filters that accept arguments have parentheses
around the arguments, like a function call.  This example will join a list
by commas:  ``{{ list|join(', ') }}``.

The :ref:`builtin-filters` below describes all the builtin filters.

.. _tests:

Tests
-----

Beside filters there are also so called "tests" available.  Tests can be used
to test a variable against a common expression.  To test a variable or
expression you add `is` plus the name of the test after the variable.  For
example to find out if a variable is defined you can do ``name is defined``
which will then return true or false depending on if `name` is defined.

Tests can accept arguments too.  If the test only takes one argument you can
leave out the parentheses to group them.  For example the following two
expressions do the same::

    {% if loop.index is divisibleby 3 %}
    {% if loop.index is divisibleby(3) %}

The :ref:`builtin-tests` below describes all the builtin tests.


Comments
--------

To comment-out part of a line in a template, use the comment syntax which is
by default set to ``{# ... #}``.  This is useful to comment out parts of the
template for debugging or to add information for other template designers or
yourself::

    {# note: disabled template because we no longer use this
        {% for user in users %}
            ...
        {% endfor %}
    #}


Whitespace Control
------------------

In the default configuration, a single trailing newline is stripped if
present, and whitespace is not further modified by the template engine. Each
whitespace (spaces, tabs, newlines etc.) is returned unchanged.  If the
application configures Jinja to `trim_blocks` the first newline after a a
template tag is removed automatically (like in PHP).

But you can also strip whitespace in templates by hand.  If you put an minus
sign (``-``) to the start or end of an block (for example a for tag), a
comment or variable expression you can remove the whitespaces after or before
that block::

{'fraction_non_alphanumeric': 0.09220646043411383, 'fraction_numerical': 0.0015381985985301657, 'mean_word_length': 3.283674963396779, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5767570', 'n_tokens_mistral': 3141, 'n_tokens_neox': 2999, 'n_words': 1697}