Data Reference ============== Every template receives a small set of objects from pyplanner. This page is a complete reference of those objects, their properties and the values they produce. Keep it open while you design - it answers "what can I put inside ``{{ }}``?". **Key topics** * The variables injected into every template (``base``, ``calendar``, ``lang`` and ``params``). * Year, Month, Day, WeekDay objects and their properties. * The ``month.table`` grid explained visually. * String representation shortcuts. * The ``loop`` variable inside ``for`` blocks. Injected variables ------------------ pyplanner passes these variables to your template: .. list-table:: :header-rows: 1 :widths: 20 20 55 * - Name - Type - Description * - ``base`` - string - Path prefix pointing to the template directory. Prefix every ``src`` and ``href`` attribute with ``{{ base }}/`` so that asset paths resolve correctly regardless of where the output file is written. Don't prepend ``{{ base }}/`` to links within the same page (starting with ``#``). * - ``calendar`` - Calendar - Entry point for all calendar data. Use it to build a Year object and to access weekday names. * - ``lang`` - string - The active display language code (e.g. ``"en"``, ``"ru"``, ``"kr"``), set by ``--lang``. ``"ko"`` is accepted as an alias for ``"kr"`` and resolves to the same value. Use the variable to apply language-specific CSS such as font families, font sizes or layout adjustments. * - ``params`` - namespace - Template parameters loaded from ``params.xml``. Access values with dot notation: ``{{ params.accent }}``, ``{{ params.colors.primary }}``. Defaults to an empty namespace when no ``params.xml`` exists. See :doc:`template-parameters` for details on declaring and overriding parameters. Calendar -------- The ``calendar`` object itself has two things you will use: .. list-table:: :header-rows: 1 :widths: 30 15 50 * - Expression - Type - Description * - ``calendar.year(2026)`` - Year - Build a Year object for the given year number. * - ``calendar.weekdays`` - tuple - Seven WeekDay objects starting from the configured first day of the week. Defaults to Monday through Sunday; changes when ``--first-weekday`` or ``--country`` is used. * - ``calendar.firstweekday`` - int - The first day of the week as a number (0 = Monday ... 6 = Sunday). * - ``calendar.lang`` - string - The active display language code (same value as the top-level ``lang`` variable). ``calendar.weekdays`` example (default, Monday start): **Template:** .. code-block:: html+jinja %% for wd in calendar.weekdays {{ wd.name }} %% endfor **Output:** .. code-block:: text Monday Tuesday Wednesday Thursday Friday Saturday Sunday When ``--first-weekday sunday`` is used, the same loop outputs: .. code-block:: text Sunday Monday Tuesday Wednesday Thursday Friday Saturday Year ---- Returned by ``calendar.year()``. .. list-table:: :header-rows: 1 :widths: 25 10 20 40 * - Property - Type - Example - Description * - ``value`` - int - ``2026`` - The year number. * - ``months`` - list - (12 Month objects) - All months, January through December. * - ``id`` - string - ``"2026"`` - Identifier string. Useful for HTML ``id`` attributes. * - ``isleap`` - bool - ``false`` - Whether the year is a leap year. * - ``days()`` - iterator - (365 or 366 Day objects) - Every day in the year, in order. **String representation:** ``{{ year }}`` outputs the year number, for example ``2026``. Month ----- Each item in ``year.months``. .. list-table:: :header-rows: 1 :widths: 25 10 20 40 * - Property - Type - Example - Description * - ``value`` - int - ``1`` - Month number (1 = January, 12 = December). * - ``name`` - string - ``"January"`` - Full month name (translated when ``--lang`` is used). * - ``short_name`` - string - ``"Jan"`` - Abbreviated month name (translated when ``--lang`` is used). * - ``days`` - list - (28-31 Day objects) - Every day in the month, in order. * - ``table`` - list of lists - (see below) - Calendar grid for rendering tables. * - ``id`` - string - ``"2026-01"`` - Identifier in ``YYYY-MM`` format. **String representation:** ``{{ month }}`` outputs the month name, for example ``January``. Understanding ``month.table`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``month.table`` is a list of weeks. Each week is a list of seven slots - one per weekday, ordered to match ``calendar.weekdays``. A slot contains a Day object or ``None`` if that weekday falls outside the month. The column order depends on the configured first day of the week. January 2026 starts on Thursday. With the default Monday start the table looks like this:: Mon Tue Wed Thu Fri Sat Sun ---- ---- ---- ---- ---- ---- ---- None None None 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 None In your template you loop over weeks (rows) and then over days (cells). Check for ``None`` before printing: .. code-block:: html+jinja %% for week in month.table %% for day in week %% if day is not none {{ day }} %% else %% endif %% endfor %% endfor Day --- Each item in ``month.days`` or in the cells of ``month.table``. .. list-table:: :header-rows: 1 :widths: 25 10 25 35 * - Property - Type - Example - Description * - ``value`` - int - ``15`` - Day of month number. * - ``weekday`` - WeekDay - (WeekDay object) - The weekday this day falls on. * - ``id`` - string - ``"2026-01-15"`` - Identifier in ``YYYY-MM-DD`` format. Use for HTML ``id`` attributes and ``href="#..."`` links. * - ``is_off_day`` - bool - ``true`` - Whether this is a day off (weekend or public holiday). * - ``name`` - string or None - ``"Christmas Day"`` - International holiday name if the day is a public holiday, otherwise ``None``. Populated by providers that supply holiday names (e.g. Nager.Date). * - ``local_name`` - string or None - ``"Weihnachten"`` - Localized holiday name in the country's language, otherwise ``None``. Populated by providers that supply holiday names (e.g. Nager.Date). * - ``launch_year`` - int or None - ``1967`` - The year the public holiday was established, otherwise ``None``. * - ``holiday_types`` - tuple of strings or None - ``("Public",)`` - Holiday type labels. ``None`` when not supplied by the provider. Possible values (Nager.Date definitions): * ``"Public"`` - general public holiday, a day off for the population. * ``"Bank"`` - bank holiday; banks and offices are closed. * ``"School"`` - school holiday; schools are closed. * ``"Authorities"`` - government offices are closed. * ``"Optional"`` - majority of people take a day off but it is not mandatory. * ``"Observance"`` - optional festivity, no paid day off. **String representation:** ``{{ day }}`` outputs the day number, for example ``15``. Linking between pages ~~~~~~~~~~~~~~~~~~~~~ Every Day, Month and Year has an ``id`` property that makes a good HTML anchor. Set it as the ``id`` of a ``.page`` div, then link to it with ``#``: **Template:** .. code-block:: html+jinja ## Create a page with an anchor
...
## Link to that page from elsewhere {{ day }} **Output:** .. code-block:: html
...
15 WeekDay ------- Each item in ``calendar.weekdays`` or accessed through ``day.weekday``. .. list-table:: :header-rows: 1 :widths: 25 10 25 35 * - Property - Type - Example - Description * - ``value`` - int - ``0`` - Weekday number (starting from zero). * - ``name`` - string - ``"Monday"`` - Full weekday name (translated when ``--lang`` is used). * - ``short_name`` - string - ``"Mon"`` - Abbreviated weekday name (translated when ``--lang`` is used). * - ``letter`` - string - ``"M"`` - Single-letter weekday label (translated when ``--lang`` is used). Suitable for compact calendar grids. * - ``is_off_day`` - bool - ``false`` - Default off-day flag. Saturday and Sunday are ``true``, the rest are ``false``. **String representation:** ``{{ weekday }}`` outputs the weekday name, for example ``Monday``. Common patterns: .. list-table:: :header-rows: 1 :widths: 40 25 * - Expression - Output * - ``{{ day.weekday }}`` - ``Wednesday`` * - ``{{ day.weekday.short_name }}`` - ``Wed`` * - ``{{ day.weekday.letter }}`` - ``W`` ``loop`` variable reference --------------------------- Available inside every ``%% for`` block. .. list-table:: :header-rows: 1 :widths: 25 50 * - Property - Description * - ``loop.index`` - Current iteration number, starting at 1. * - ``loop.index0`` - Current iteration number, starting at 0. * - ``loop.first`` - ``true`` on the very first iteration. * - ``loop.last`` - ``true`` on the very last iteration. * - ``loop.length`` - Total number of items in the list. * - ``loop.revindex`` - Iterations remaining (including current), starting at the length and counting down to 1. * - ``loop.revindex0`` - Like ``revindex`` but counts down to 0. Quick cheat sheet ----------------- :: lang -> "en" (set by --lang) params -> namespace from params.xml .year -> 2026 (example int param) .accent -> "#4A90D9" (example str param) .colors.primary -> "#000" (nested namespace) calendar .year(2026) -> Year .weekdays -> (Mon, Tue, ..., Sun) *rotated by --first-weekday* .firstweekday -> 0 (0=Mon .. 6=Sun) .lang -> "en" Year .value -> 2026 .months -> [January, ..., December] .id -> "2026" .isleap -> false .days() -> iterator of all Day objects Month .value -> 1 .name -> "January" .short_name -> "Jan" .days -> [Day(1), Day(2), ..., Day(31)] .table -> [[None, None, ..., Day], ...] .id -> "2026-01" Day .value -> 15 .weekday -> WeekDay .id -> "2026-01-15" .is_off_day -> true / false .name -> "Christmas Day" / None .local_name -> "Weihnachten" / None .launch_year -> 1967 / None .holiday_types -> ("Public",) / None WeekDay .value -> 0 .name -> "Monday" .short_name -> "Mon" .letter -> "M" .is_off_day -> false What is next ------------ Continue to :doc:`template-parameters` to learn how to declare customizable parameters for your template.