{# ================================================================================ Content Tiles Component (Kida-Native) ================================================================================ Flexible content display with optional headers, multiple content sources, and variant display modes. Variants: - compact: Row-based list with icons (default) - cards: Grid of preview cards - minimal: Simple link list Usage: {{ content_tiles(title='Section', children=posts, variant='cards') }} ================================================================================ #} {# ============================================================================= CONTENT TILES COMPONENT ============================================================================= #} {% def content_tiles( title=none, children=none, subsections=none, related=none, related_title=none, related_limit=5, variant='compact', show_descriptions=true, show_icons=true, group_by=none, page=none ) %} {% let all_items = [] %} {% let page_path = page?._path ?? '' %} {# Add subsections with metadata #} {% if subsections %} {% for subsection in subsections %} {% let sub_pages = subsection?.pages ?? [] %} {% set _ = all_items.append({ 'type': 'section', 'group': 'children', 'obj': subsection, 'title': subsection?.title ?? 'Untitled', 'href': subsection?.href ?? subsection?._path ?? '', 'description': subsection?.metadata?.description ?? '', 'weight': subsection?.weight ?? 999, 'page_count': sub_pages | length, 'date': none, 'icon': subsection?.metadata?.icon ?? '' }) %} {% end %} {% end %} {# Add child pages with metadata #} {% if children %} {% for post in children %} {# Skip the current page #} {% if (post?._path ?? '') != page_path %} {% let post_content = post?.content ?? '' %} {% let post_desc = post?.metadata?.description ?? '' %} {% let desc = post_desc ?? (post_content | strip_html | excerpt(120) if post_content else '') %} {% set _ = all_items.append({ 'type': 'page', 'group': 'children', 'obj': post, 'title': post?.title ?? 'Untitled', 'href': post?.href ?? post?._path ?? '', 'description': desc, 'weight': post?.weight ?? 999, 'page_count': 0, 'date': post?.date ?? none, 'icon': post?.metadata?.icon ?? '' }) %} {% end %} {% end %} {% end %} {# Add related pages (deduped) #} {% let related_pages = [] %} {% if related is sameas true %} {% let page_related = page?.related_posts ?? [] %} {% let related_pages = page_related[:related_limit] %} {% elif related %} {% let related_pages = related %} {% end %} {# Build set of existing URLs for dedup #} {% let children_urls = [] %} {% for item in all_items %} {% set _ = children_urls.append(item.href) %} {% end %} {% for rel_page in related_pages %} {% let rel_path = rel_page?._path ?? '' %} {% let rel_href = rel_page?.href ?? rel_page?._path ?? '' %} {% let is_current = rel_path == page_path %} {% let is_duplicate = rel_href in children_urls %} {% if not is_current and not is_duplicate %} {% let rel_content = rel_page?.content ?? '' %} {% let rel_desc = rel_page?.metadata?.description ?? '' %} {% let desc = rel_desc ?? (rel_content | strip_html | excerpt(100) if rel_content else '') %} {% set _ = all_items.append({ 'type': 'related', 'group': 'related', 'obj': rel_page, 'title': rel_page?.title ?? 'Untitled', 'href': rel_href, 'description': desc, 'weight': rel_page?.weight ?? 999, 'page_count': 0, 'date': rel_page?.date ?? none, 'icon': rel_page?.metadata?.icon ?? '' }) %} {% end %} {% end %} {% if all_items | length > 0 %} {# Sort items #} {% let sorted_items = all_items | sort(attribute='group,weight,title') if group_by == 'type' else all_items | sort(attribute='weight,title') %}
{% if title %}

{{ title }}

{% end %} {% match variant %} {# ===== CARDS VARIANT ===== #} {% case 'cards' %}
{% for item in sorted_items %}
{% if show_icons %}
{% if item.icon %} {{ icon(item.icon, size=24) }} {% else %} {% match item.type %} {% case 'section' %}{{ icon('folder', size=24) }} {% case 'related' %}{{ icon('link', size=24) }} {% case _ %}{{ icon('file-text', size=24) }} {% end %} {% end %}
{% end %}

{{ item.title }}

{% if show_descriptions and item.description %}

{{ item.description | excerpt_for_card(item.title) | excerpt(120) }}

{% end %}
{% match item.type %} {% case 'section' %} {% if item.page_count > 0 %} {{ item.page_count }} page{{ 's' if item.page_count != 1 else '' }} {% end %} {% case 'related' %} Related {% case _ %} {% if item.date %} {{ item.date | time_ago }} {% end %} {% end %}
{% end %}
{# ===== MINIMAL VARIANT ===== #} {% case 'minimal' %} {# ===== COMPACT VARIANT (default) ===== #} {% case _ %}
{% for group in sorted_items | groupby('group') %} {% let group_name = group.grouper %} {% let group_items = group.list %} {# Group headers when group_by='type' #} {% if group_by == 'type' and group_name == 'related' and related_title %}
{{ related_title }}
{% end %} {% for item in group_items %}
{% if show_icons %}
{% if item.icon %} {{ icon(item.icon, size=20) }} {% elif item.type == 'section' %} {{ icon('folder', size=20) }} {% elif item.type == 'related' %} {{ icon('link', size=20) }} {% else %} {{ icon('file-text', size=20) }} {% end %}
{% end %}
{{ item.title }} {% if show_descriptions and item.description %} {{ item.description | excerpt_for_card(item.title) }} {% end %} {% if item.type == 'section' and item.page_count > 0 %} {{ item.page_count }} page{{ 's' if item.page_count != 1 else '' }} {% elif item.type == 'related' %} Related {% elif item.date %} {{ item.date | time_ago }} {% end %}
{% end %} {% end %}
{% end %}
{% end %} {% end %}