{# ================================================================================ Navigation Components (Kida-Native) ================================================================================ Reusable macro-based navigation components for the Bengal default theme. COMPONENTS: - breadcrumbs(page): Hierarchical breadcrumb navigation - pagination(current_page, total_pages, base_url): Page number controls - page_navigation(page): Sequential prev/next page links - section_navigation(page): Section statistics and subsection cards - toc(toc_items, toc, page): Table of contents sidebar KIDA FEATURES USED: - {% def %} for reusable macros - {% let %} for template-scoped variables - Optional chaining (?.) for null-safe access - Null coalescing (??) for smart defaults - {% match %} for type dispatch - {% spaceless %} for clean HTML output - Pipeline operator (|>) for filter chains USAGE: {% from 'partials/navigation-components.html' import breadcrumbs, pagination %} {{ breadcrumbs(page) }} {{ pagination(current_page=2, total_pages=10, base_url='/blog/') }} ================================================================================ #} {# ============================================================================= BREADCRUMBS COMPONENT Displays hierarchical navigation showing the current page's location. Note: URLs returned by get_breadcrumbs() are relative paths without baseurl. For display in HTML href attributes, apply the | absolute_url filter. ============================================================================= #} {% def breadcrumbs(page) %} {% with get_breadcrumbs(page) as breadcrumb_items %} {% end %} {% enddef %} {# ============================================================================= PAGINATION ITEM HELPER Renders a single pagination item (ellipsis, current page, or link). ============================================================================= #} {% def pagination_item(item) %} {% if item?.is_ellipsis %} ... {% elif item?.is_current %} {{ item.num }} {% else %} {{ item.num }} {% end %} {% end %} {# ============================================================================= PAGINATION COMPONENT Displays page number controls for paginated content with prev/next buttons. ============================================================================= #} {% def pagination(current_page, total_pages, base_url) %} {% if total_pages > 1 %} {% let p = get_pagination_items(current_page, total_pages, base_url) %} {% end %} {% end %} {# ============================================================================= PAGE NAVIGATION COMPONENT Displays previous/next page links for sequential navigation. Intelligently chooses navigation scope based on content type: - doc, tutorial, autodoc-*, blog: Section-scoped (prev/next within section) - page, others: Global (chronological order) ============================================================================= #} {% def page_navigation(page) %} {# Early return if page is null #} {% if page %} {# Check feature flag #} {% let theme_features = theme?.features ?? [] %} {% if 'navigation.prev_next' in theme_features %} {# Determine navigation scope based on content type #} {% let content_type = page?.metadata?.type ?? 'page' %} {% let section_types = ['doc', 'tutorial', 'autodoc-python', 'autodoc-cli', 'autodoc-rest', 'changelog', 'blog'] %} {% let use_section_nav = content_type in section_types %} {# Get navigation links with null-safe access #} {% let prev_link = page?.prev_in_section if use_section_nav else page?.prev %} {% let next_link = page?.next_in_section if use_section_nav else page?.next %} {% if prev_link or next_link %} {% end %} {% end %} {% end %} {% enddef %} {# ============================================================================= SECTION NAVIGATION COMPONENT Displays statistics and subsection cards for exploring a section hierarchy. ============================================================================= #} {% def section_navigation(page) %} {% let regular_pages = page?.regular_pages ?? [] %} {% let sections = page?.sections ?? [] %} {% let recursive_pages = page?.regular_pages_recursive ?? [] %} {% if regular_pages | length > 0 or sections | length > 0 %}
{# Section stats #}

{{ regular_pages | length }} pages in this section

{% if sections | length > 0 %}

{{ sections | length }} subsections

{% end %} {% if recursive_pages | length > regular_pages | length %}

{{ recursive_pages | length }} total pages (including subsections)

{% end %}
{# Subsection cards #} {% if sections | length > 0 %}

Subsections

{% for subsection in sections %} {% let sub_desc = subsection?.metadata?.description ?? '' %} {% let sub_pages = subsection?.regular_pages ?? [] %}

{{ subsection.title }}

{% if sub_desc %}

{{ sub_desc }}

{% end %}

{{ sub_pages | length }} pages

{% end %}
{% end %}
{% end %} {% end %} {# ============================================================================= TABLE OF CONTENTS COMPONENT Interactive TOC with progress tracking, collapsible sections, and metadata. Uses recursive macros for optimal performance and arbitrary depth. JS enhances with: active item tracking, auto-expand on scroll, progress. KIDA FEATURES SHOWCASED: - {% def %} recursive macros for tree traversal - {% cache %} for expensive TOC rendering - {% match %} for level-based styling - {% unless %} for negative conditionals - {% break %} for early loop termination (contributor limit) ============================================================================= #} {# HELPER: Render a single TOC node (recursive) is_section: marks top-level section groups for track filtering (default false) #} {% def toc_node(node, is_section=false) %} {% let node_id = node?.id ?? '' %} {% let node_title = node?.title ?? '' %} {% let node_level = node?.level ?? 2 %} {% let children = node?.children ?? [] %} {% let has_children = children | length > 0 %} {% if node_id %}
  • {% if has_children %} {# Auto-expand based on heading level using match #} {# Add data-toc-section for top-level groups (used by track filtering) #} {% match node_level %} {% case 1 %}
    {% case 2 %}
    {% case _ %}
    {% end %} {{ node_title }} {% spaceless %} {{ children | length }} {% end %}
      {% for child in children %} {{ toc_node(child) }} {% end %}
    {% else %} {{ node_title }} {% end %}
  • {% end %} {% enddef %} {% def toc(toc_items=none, toc=none, page=none) %} {# Cache TOC rendering per-page for performance #} {% cache 'toc-' ~ (page?._path ?? 'unknown') %}
    {# Scroll Progress Indicator #} {# Table of Contents #} {# Page Metadata Section #} {% if page %} {% let page_meta = page?.metadata ?? {} %} {% let contributors = page_meta?.contributors ?? [] %} {% let github_edit_base = config?.github_edit_base %} {% let source_path = page?.source_path %}
    {# Last Updated #} {% with page.date as date %}
    {{ icon('clock', size=14) }}
    {{ t('toc.last_updated', default='Last updated') }}
    {% end %} {# Edit on GitHub #} {% with page_meta?.edit_url ?? (github_edit_base ~ source_path if github_edit_base and source_path) as edit_url %} {{ icon('pencil', size=14) }} {{ t('toc.edit_page', default='Edit this page') }} {% end %} {# Contributors - limit display with loop control #} {% if contributors | length > 0 %}
    {{ icon('users', size=14) }}
    {{ t('toc.contributors', default='Contributors') }}
    {% let max_contributors = 5 %} {% let shown_contributors = contributors |> take(max_contributors) %} {{ shown_contributors | join(', ') }} {% if contributors | length > max_contributors %} +{{ contributors | length - max_contributors }} more {% end %}
    {% end %}
    {% end %}
    {% end %}{# End cache block #} {% enddef %}