Variables, Expressions and Comments ==================================== Templates become powerful when you mix HTML with dynamic data. Jinja2 is the template engine Feather Flow uses. This page covers the basics - outputting values, creating your own variables, using filters and leaving comments. **Key topics** * Two syntax styles - block tags and line statements. * Outputting values with ``{{ }}``. * Creating variables with ``set``. * Accessing properties with dot notation. * Filters for transforming values. * Comments. Two syntax styles ----------------- Jinja2 has a standard block syntax that uses curly braces. In addition, Feather Flow enables a shorthand called *line statements* that starts with ``%%``. Both are equivalent - use whichever you find more readable. .. list-table:: :header-rows: 1 :widths: 25 35 35 * - Purpose - Block syntax - Line statement * - Output a value - ``{{ year }}`` - (same) * - Statement - ``{% set x = 1 %}`` - ``%% set x = 1`` * - Comment - ``{# a comment #}`` - ``## a comment`` The rest of this guide uses line statements (``%%``) because they look cleaner in HTML templates. Remember you can always switch to the block form if you prefer. Outputting values ----------------- Double curly braces print a value into the HTML: **Template:** .. code-block:: html+jinja
Hello, {{ "world" }}!
**Output:** .. code-block:: htmlHello, world!
You can output any expression - a string, a number or a variable. Jinja2 converts it to text automatically. Setting variables ----------------- Use ``set`` to create a variable that you can reuse later. **Template:** .. code-block:: html+jinja %% set year = calendar.year(2026){{ year }} has {{ year.months|length }} months
**Don't:** .. code-block:: html+jinja{{ calendar.year(2026) }} again
Dot notation ------------ Objects have properties you access with a dot: **Template:** .. code-block:: html+jinja %% set year = calendar.year(2026) %% set january = year.months[0]First month: {{ january.name }}
Month ID: {{ january.id }}
Days in January: {{ january.days|length }}
**Output:** .. code-block:: htmlFirst month: January
Month ID: 2026-01
Days in January: 31
Use square brackets to access items by position. Positions start at zero, so ``year.months[0]`` is January and ``year.months[11]`` is December. Short names ----------- Month and WeekDay objects have dedicated ``short_name`` properties for abbreviated display. WeekDay also has a ``letter`` property for single-character labels. These work correctly across all languages set via ``--lang``. **Template:** .. code-block:: html+jinja %% set year = calendar.year(2026) %% set january = year.months[0]{{ year.months|length }} months
**Output:** .. code-block:: html12 months
You will rarely need filters beyond ``length`` in planner templates, but they are there if you want them. Comments -------- Comments are ignored by the engine and do not appear in the output. **Line comment** (recommended in Feather Flow templates): .. code-block:: html+jinja ## This line will not appear in the output.This line will.
**Block comment:** .. code-block:: html+jinja {# This will not appear in the output either. #}This line will.
**HTML comment** (still appears in the output): .. code-block:: html Use ``##`` or ``{# #}`` for notes to yourself. Use ```` only if you want the comment to survive into the final HTML. Update the Demo Planner ----------------------- Open ``planners/demo/demo.html`` and add variables for the year and the month. Our Demo Planner covers a single month, so we pick January (``year.months[0]``). The cover shows both the month name and the year dynamically: .. code-block:: html+jinja %% set year = calendar.year(2026) %% set month = year.months[0]