Templates

Blog List

blog.list.twig

The blog.list.twig template renders a list (grid or stacked list) of blog posts and links each item to its single-post page at /blog/{slug}. It’s optimized for fast loading with optional covers, short excerpts, and simple pagination.

What it does

  • Lists all published posts from your content directory
  • Shows title, optional cover image, and excerpt/summary
  • Links each card to the single-post view (/blog/{slug})
  • Supports simple pagination

Available Twig Variables

The template receives an array called posts containing post entries. Each post entry is a structured array with the following variables:

posts - List of blog posts

{% for post in posts %}
{# render post card #}
{% endfor %}

Inside each post object

Variable Type Description
post.slug string Directory/URL slug (e.g. my-first-post)
post.title string Post title (from YAML; falls back to capitalized slug)
post.url string Absolute path to the post: /blog/{slug}
post.cover string (optional) URL of the cached cover image (already sized)
post.excerpt string (optional) Short text used on the list view
post.is_published bool Visibility flag; only true should be listed
post.tags array (optional) Array of tag strings
post.published_at string (optional) Publication date (e.g., YYYY-MM-DD), can be used for sorting or display

Notes

  • The list should not include unpublished items.
  • If you don’t maintain excerpt in YAML, you can derive it (e.g., from the first lines of the Markdown body) at build time.

Example Twig usage

{% if posts is not empty %}
    <ul class="blog-list">
        {% for post in posts %}
            <li class="blog-entry">
                {% if post.cover %}
                    <img src="{{ post.cover }}" alt="{{ post.title }}" class="cover-img">
                {% endif %}

                <h2>
                    <a href="/blog/{{ post.slug }}">{{ post.title }}</a>
                </h2>

                <p class="date">{{ post.date }}</p>

                {% if post.excerpt %}
                    <p class="excerpt">{{ post.excerpt }}</p>
                {% else %}
                    <p class="excerpt">{{ post.content|striptags|slice(0, 150) ~ '...' }}</p>
                {% endif %}
            </li>
        {% endfor %}
    </ul>
{% else %}
    <p>No Blogposts found.</p>
{% endif %}

Example Pagination

{% if pagination is defined %}
  <nav class="w-full flex items-center justify-between border-t border-gray-200 px-4 sm:px-6 mt-8">
    {% if pagination.has_prev %}
      <a href="?page={{ pagination.current - 1 }}" class="py-2">Previous</a>
    {% endif %}

    <span class="text-sm">Page {{ pagination.current }} of {{ pagination.total }}</span>

    {% if pagination.has_next %}
      <a href="?page={{ pagination.current + 1 }}" class="py-2">Next</a>
    {% endif %}
  </nav>
{% endif %}
Previous
Image