{% extends "base.html" %} {# Blog List Template Used for blog section indexes. Displays blog posts in reverse chronological order with featured posts, excerpts, and pagination. Usage: Set `type: blog` in section _index.md Context variables: - section: Section object with blog posts - posts: List of blog post pages (may be paginated) - subsections: Blog categories/archives - total_pages: Total pagination pages - current_page: Current page number #} {% from 'partials/navigation-components.html' import breadcrumbs, pagination %} {% from 'partials/content-components.html' import tag_list %} {# Defensive defaults for pagination variables (safe fallback if not provided) #} {% set total_pages = total_pages | default(1) %} {% set current_page = current_page | default(1) %} {% set total_posts = total_posts | default(posts | length if posts else 0) %} {% set base_url = base_url | default(section.url if section else '/blog/') %} {% block content %} {# Action Bar: Breadcrumbs + Share #} {% include 'partials/action-bar.html' with context %}

✍️ {{ section.title if section else title | default('Blog') }}

{% if section and section.metadata.get('description', '') %}

{{ section.metadata.get('description', '') }}

{% elif description %}

{{ description }}

{% endif %} {% if total_pages %}

Showing {{ posts | length }} of {{ total_posts }} posts {% if current_page > 1 %}(Page {{ current_page }} of {{ total_pages }}){% endif %}

{% endif %}
{% if posts %} {# Featured Posts Section #} {% set featured_posts = posts | where('featured', true) | limit(3) %} {% if featured_posts and current_page == 1 %} {% endif %} {# All Posts Section #} {% set regular_posts = posts | where_not('featured', true) if current_page == 1 else posts %} {% if regular_posts %}
{% if featured_posts and current_page == 1 %}

Recent Posts

{% endif %}
{% for post in regular_posts %}
{% if post.metadata.get('image') or post.metadata.get('cover') %} {% endif %}

{{ post.title }}

{% if post.metadata.get('description') or post.excerpt %}

{{ post.metadata.get('description') | default(post.excerpt) | truncate(200) }}

{% endif %}
{% if post.metadata.get('author') %} {% if post.metadata.get('author_avatar') %} {{ post.metadata.get('author') }} {% endif %} {{ post.metadata.get('author') }} {% endif %} {% if post.date %} {% endif %} {% if post.content %} {{ (post.content | wordcount / 200) | round }} min read {% endif %}
{% if post.tags %}
{{ tag_list(post.tags | limit(4)) }}
{% endif %} Read more →
{% endfor %}
{% endif %} {# Pagination #} {% if total_pages and total_pages > 1 %} {{ pagination(current_page, total_pages, base_url) }} {% endif %} {% elif subsections %} {# Show blog categories/archives if no posts #}

Categories

{% for subsection in subsections %}

{{ subsection.title }}

{% if subsection.metadata.get('description', '') %}

{{ subsection.metadata.get('description', '') }}

{% endif %} {% if subsection.regular_pages %} {# Count only non-index pages #} {% set index_url = subsection.index_page.url if subsection.index_page else '' %} {% set content_pages = subsection.regular_pages | rejectattr('url', 'equalto', index_url) | list %} {% if content_pages %}

{{ content_pages | length }} post{{ 's' if content_pages | length != 1 }}

{% endif %} {% endif %}
{% endfor %}
{% else %} {# Empty State #}

No blog posts yet. Check back soon!

{% endif %}
{% endblock %}