{# ================================================================================ Track Helper Macros (Kida-Native) ================================================================================ Reusable PRESENTATIONAL macros for the data-file track pillar page. WHY NO get_track_id()/get_track() VALUE-RETURNING MACROS: Kida `{% def %}` emits TEXT, not Python objects. A macro that "returns" a track id or dict via `{{ track_id }}` yields rendered whitespace, not a usable value. Resolve track state INLINE in the consuming template with `{% let %}` + null-coalescing instead: {% let track_id = params?.track_id ?? page?.slug ?? '' %} {% let tracks = site?.data?.tracks ?? {} %} {% let track = tracks[track_id] if (track_id and track_id in tracks) else none %} {% let track_items = track?.items ?? [] %} This file therefore exports HTML-emitting macros only. They are the shared visual vocabulary consumed by tracks/single.html and the CSS/JS waves (see the DOM contract documented at the top of tracks/single.html). EXPORTS: track_progress_indicator(total_steps, current_step) — stepped progress rail track_section_block(item_page, index, is_last) — one embedded lesson track_section_missing(item_slug, index) — placeholder for a slug with no page USAGE: {% from 'partials/track-helpers.html' import track_progress_indicator, track_section_block, track_section_missing %} ================================================================================ #} {% from "chirpui/badge.html" import badge %} {# ============================================================================= PROGRESS INDICATOR Stepped rail showing how many sections a track contains. `current_step` marks the section a reader has reached (defaults to the first). DOM contract: .chirp-theme-track-progress[role="progressbar"] ============================================================================= #} {% def track_progress_indicator(total_steps, current_step=1) %} {% let total = total_steps ?? 0 %} {% if total > 0 %}
    {% let step = 1 %} {% while step <= total %} {% let is_complete = step < current_step %} {% let is_current = step == current_step %}
  1. {% if step < total %} {% end %}
  2. {% let step = step + 1 %} {% end %}
Step {{ current_step }} of {{ total }}
{% end %} {% end %} {# ============================================================================= TRACK SECTION BLOCK Renders one track member page inline as a pillar-page section. Headings are demoted one level and prefixed with `s{index}-` so anchors stay unique and the combined TOC (combine_track_toc) can link into them. Relative links are resolved to absolute so they keep working when embedded. DOM contract:
.chirp-theme-track-section__header .chirp-theme-track-section__number (the {index}) .chirp-theme-track-section__title (h2) .chirp-theme-track-section__lede (optional description) .chirp-theme-track-section__body (embedded, demoted HTML) .chirp-theme-track-section__complete (only on the final section) ============================================================================= #} {% def track_section_block(item_page, index, is_last=false) %} {% let section_prefix = "s" ~ index ~ "-" %} {% let item_title = item_page?.title ?? 'Section' %} {% let item_lede = item_page?.description ?? '' %} {% let item_html = item_page?.html_content ?? none %} {% let item_content = item_page?.content ?? '' %} {% let item_href = item_page?.href ?? '#' %}

{{ item_title }}

{% if item_lede %}

{{ item_lede }}

{% end %}
{% if item_html %} {{ item_html | resolve_links_for_embedding(item_page) | demote_headings | prefix_heading_ids(section_prefix) | safe }} {% elif item_content %} {{ item_content | resolve_links_for_embedding(item_page) | demote_headings | prefix_heading_ids(section_prefix) | safe }} {% else %}

This lesson has no inline content yet.

{{ badge('Open full page', variant='primary', icon='arrow-right', href=item_href) }}
{% end %}
{% if is_last %}
{{ badge('Track complete', variant='success', icon='check') }}
{% end %}
{% end %} {# ============================================================================= MISSING SECTION PLACEHOLDER Shown when a track item slug resolves to no page (broken `tracks.yaml` reference). Keeps the section anchor stable so the TOC does not break. ============================================================================= #} {% def track_section_missing(item_slug, index) %}

Section {{ index }} unavailable

No page matches {{ item_slug }}.

{% end %}