{# ================================================================================ Track Prev/Next Navigation (Kida-Native) ================================================================================ Sequential prev/next control for a reader sitting ON a track member page (NOT the pillar page). Finds which track owns the current page, then derives the previous/next siblings WITHOUT `.index()` (unavailable in kida) by walking `track.items` with a loop and recording the neighbours of the matching slug. DOM contract: .chirp-theme-track-nav card with .chirp-theme-track-nav__actions (prev/next buttons) .chirp-theme-track-nav__progress (progress bar) USAGE: {% include 'partials/track_nav.html' %} ================================================================================ #} {% from "chirpui/badge.html" import badge %} {% from "chirpui/button.html" import btn %} {% from "chirpui/card.html" import card %} {% from "chirpui/layout.html" import cluster %} {% from "chirpui/progress.html" import progress_bar %} {% let _current_href = page?.href ?? '' %} {% let all_tracks = site?.data?.tracks ?? {} %} {% for track_id, track in all_tracks | items %} {% let track_items = track?.items ?? [] %} {# Walk the item list once to find the current page's position + neighbours. Match on resolved page identity (href), not a slug string: the Page object exposes no content-relative-path attribute under strict undefined, so we resolve each item via get_page() and compare its href to the current page. Avoids `.index()` (not available in kida) and capital `None`. Accumulate into lists (append survives loop scope). #} {% set _positions = [] %} {% set _prev = [] %} {% set _next = [] %} {% for item_slug in track_items %} {% let _item_page = get_page(item_slug) %} {% if _item_page and _current_href and (_item_page.href == _current_href) %} {% set _ = _positions.append(loop.index) %} {% if not loop.first %}{% set _ = _prev.append(track_items[loop.index0 - 1]) %}{% end %} {% if not loop.last %}{% set _ = _next.append(track_items[loop.index0 + 1]) %}{% end %} {% end %} {% end %} {% if _positions | length > 0 %} {% let total = track_items | length %} {% let position = _positions[0] %} {% let prev_slug = _prev[0] if _prev | length > 0 else none %} {% let next_slug = _next[0] if _next | length > 0 else none %} {% let progress_value = (position / total) * 100 if total > 0 else 0 %} {% let position_label = position ~ " of " ~ total %} {% call card(title=track?.title ?? 'Track', subtitle=position_label, cls="chirp-theme-track-nav") %} {% slot header_actions %}{{ badge("Track", variant="primary") }}{% end %} {% call cluster(gap="sm", cls="chirp-theme-track-nav__actions") %} {% if prev_slug %} {% let prev_page = get_page(prev_slug) %} {% if prev_page %} {{ btn(prev_page.title, href=prev_page.href, variant="ghost", size="sm", icon="arrow-left") }} {% else %} Previous unavailable {% end %} {% else %} Start of track {% end %} {% if next_slug %} {% let next_page = get_page(next_slug) %} {% if next_page %} {{ btn(next_page.title, href=next_page.href, variant="primary", size="sm", icon="arrow-right") }} {% else %} Next unavailable {% end %} {% else %} {{ btn("Finish track", href=('/tracks/' | absolute_url), variant="success", size="sm", icon="check") }} {% end %} {% end %} {{ progress_bar(progress_value, label=position_label, variant="gold", size="sm", cls="chirp-theme-track-nav__progress") }} {% end %} {% end %} {% end %}