A new groupby filter lets you group any array of objects by a field, with optional date-part extraction for year, month or day. Perfect for listing posts per year. Ships alongside a wordcount helper and a baseURL CLI override.
The groupby filter groups an array of objects by a field value and returns an array of { key, items }. Pass an optional second argument (year, month, day) to group by a date part instead of the raw value. Groups keep insertion order, so sort your posts date-descending and the years come out newest-first for free.
{% set byYear = collections.items | groupby("date", "year") %}
{% for group in byYear %}
<h2>{{ group.key }}</h2>
{% for post in group.items %}
<p><a href="{{ post.url }}">{{ post.title }}</a></p>
{% endfor %}
{% endfor %}
Liquid uses the colon syntax: {{ collections.posts | groupby: "date", "year" }}.
Every collection item already carries a wordcount property — Poops strips the HTML/Markdown and counts the words when it builds the collection, so you don't compute anything at render time. Turn it into a reading-time estimate by dividing by an average reading speed (~200 words per minute) and rounding up so even a short post reads as "1 min".
{% for post in collection.items %}
<h3>{{ post.title }}</h3>
<small>{{ (post.wordcount / 200) | round(0, "ceil") }} min read</small>
{% endfor %}
Liquid uses divided_by with a float divisor (so it doesn't do integer division) and ceil:
{% for post in collection.items %}
<h3>{{ post.title }}</h3>
<small>{{ post.wordcount | divided_by: 200.0 | ceil }} min read</small>
{% endfor %}
Bump 200 to whatever fits your audience — 225 for skimmers, 130 for dense technical prose.
--base-url CLI flag — overrides baseURL at build time, so GitHub Actions can point the same source at different deploy targets.
2026
v2.1.0 — a schema for poops.json, llms.txt on its own (4 min read)
v2.0.0 — the dev loop, modernized (5 min read)
v1.9.8 — fence info strings carry through (2 min read)
v1.9.7 — site-wide JSON-LD defaults (2 min read)
v1.9.6 — output path templating for styles and scripts (4 min read)
v1.9.5 — index entries take their directory's name (3 min read)
v1.9.4 — one build, one copy (2 min read)
v1.9.3 — a --quiet flag for parallel runs (2 min read)
v1.9.2 — extensionless URLs, like GitHub Pages (2 min read)
v1.9.1 — load paths stop eating your pages (2 min read)
v1.9.0 — templates from npm packages (2 min read)
v1.8.0 — native dev server, fewer dependencies, hardening (3 min read)
v1.7.1 — "Edit this page on GitHub" links (1 min read)
v1.7.0 — Tags & categories (taxonomies) (3 min read)
v1.6.0 — SEO metadata, breadcrumbs, feeds and llms.txt (8 min read)
v1.5.1–v1.5.3 — incremental watch rebuilds, faster renders, smarter livereload (3 min read)
v1.5.0 — named image crops, markdown footnotes (2 min read)
v1.4.0 — style globs, auto watch and GFM extras (2 min read)
v1.3.0 — custom markup engines and navigation trees (2 min read)
v1.2.4 — poops-images integration and cleanup (2 min read)
v1.2.3 — Group posts by year with the groupby filter (2 min read)
PostCSS Pipeline & Tailwind CSS Support (2 min read)
Liquid Template Engine Support (1 min read)
Design Token Support for Sass (3 min read)
React JSX Support (1 min read)
2025
Copy feature (1 min read)
2023
Blog Functionality (2 min read)
Markdown Support (1 min read)
Added Front Matter support! (2 min read)