Skip to content

feat(blog): taxonomies and client-side filter UI#499

Merged
tym83 merged 5 commits intomainfrom
feat/blog-taxonomies-and-filters
Apr 17, 2026
Merged

feat(blog): taxonomies and client-side filter UI#499
tym83 merged 5 commits intomainfrom
feat/blog-taxonomies-and-filters

Conversation

@tym83
Copy link
Copy Markdown
Contributor

@tym83 tym83 commented Apr 17, 2026

Summary

Adds two blog-specific taxonomies (article_types, topics) and a client-side filter UI on the blog index so readers can narrow /blog/ by article type and/or subject area.

What

Data model — hugo.yaml

  • Registers two new taxonomies: article_type / article_types and topic / topics.
  • Preserves Hugo's built-in tag and category taxonomies so nothing breaks if they are used later.

Tagging — every existing post

  • 68 posts tagged across content/en/blog/ with a combination of:
    • article_types: release | how-to | case | tech-article | news (usually one).
    • topics: platform, postgresql, kubernetes, cilium, talos, opensearch, kubevirt, networking, storage, security, events, community, gpu (zero to three, only when the subject is a main theme of the post — not incidental mentions).
  • Release posts get platform by default, plus any headline features that were clearly the reason for the release (e.g. OpenSearch, GPU passthrough).

Filter UI — layouts/blog/list.html

  • Overrides the Docsy blog list template. Two rows of chips above the post list: Type (fixed order: release → how-to → case → tech-article → news) and Topic (auto-sorted).
  • Click a chip to toggle. Multiple chips within one dimension combine with OR; the two dimensions combine with AND.
  • State is mirrored into the URL: /blog/?types=how-to&topics=postgresql,kubernetes. Shareable, back/forward works.
  • Live counter: "Showing X of Y posts". Year groups collapse when empty under the current filter.
  • Pagination is dropped — for ~70 posts, showing the full archive once keeps filtering honest (otherwise filters only affect the visible page).

Why

Until now, the blog has been strictly chronological with no way to narrow down. Readers coming in from a community share ("how-to posts only", "anything about OpenSearch", "Cozystack release history") had to scroll the full archive.

This change takes advantage of existing structure — most posts already fall cleanly into one of the five editorial types and a small set of topics — without introducing new maintenance burden: adding tags to new posts is a two-line frontmatter change.

Preview

Netlify deploy preview will render the full filter UI on /blog/. Things worth checking:

  • Chip layout on mobile (should wrap gracefully).
  • Empty-state when a filter combination matches zero posts.
  • URL deep-linking: open /blog/?types=release&topics=platform directly and the chips should arrive pre-selected.
  • Dark-mode contrast on chips (uses Bootstrap CSS variables).

Follow-ups (not in this PR)

  • Make post tags on each card clickable so they act as filter shortcuts (currently they go to the Hugo-generated taxonomy list pages at /article-types/<slug>/ and /topics/<slug>/, which still work but are separate URLs).
  • Optional: server-rendered filter state for SEO on common filter combinations.

Summary by CodeRabbit

  • New Features

    • Added interactive blog filtering by article type and topic with live search.
    • Blog posts are now organized with categorization metadata for improved discoverability.
    • Filter selections persist via URL parameters for easy sharing.
  • Chores

    • Organized existing blog posts with article type and topic classifications.

tym83 added 3 commits April 17, 2026 19:08
Introduce two blog-specific taxonomies that drive the new filter UI:

- article_types: release, case, how-to, tech-article, news
- topics: platform, postgresql, kubernetes, cilium, talos, opensearch,
  kubevirt, networking, storage, security, events, community, gpu

Hugo's built-in tags and categories taxonomies are kept explicitly so
they still work if used later. No template changes in this commit;
tagging posts and wiring the filter UI follow in separate commits.

Signed-off-by: tym83 <6355522@gmail.com>
Populate the two new taxonomies on every existing blog post so the
upcoming filter UI has real data to work with:

- article_types: release | case | how-to | tech-article | news
- topics: platform, postgresql, kubernetes, cilium, talos, opensearch,
  kubevirt, networking, storage, security, events, community, gpu

Topics are assigned only when they are a main subject of the post, not
for incidental mentions. Most release posts get 'platform' plus any
headline features that were clearly the reason for the release.

Signed-off-by: tym83 <6355522@gmail.com>
Override the blog list layout to render two parallel filter dimensions
at the top of /blog/:

- Article type (release, how-to, case, tech-article, news) — ordered
  by editorial lifecycle, not alphabetical.
- Topic (platform, postgresql, kubernetes, cilium, talos, opensearch,
  kubevirt, networking, storage, security, events, community, gpu,
  ...) — auto-sorted.

Filtering is client-side only:
- Multiple chips within a dimension combine with OR.
- The two dimensions combine with AND.
- State is mirrored into the URL query string (?types=...&topics=...)
  so filtered views are shareable.
- Empty year groups collapse when no post in them matches.
- Pagination is dropped so the full archive is filterable in one pass;
  for ~70 posts this is well under 100 KB and keeps the UX honest.

Signed-off-by: tym83 <6355522@gmail.com>
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 17, 2026

Deploy Preview for cozystack ready!

Name Link
🔨 Latest commit 54490f8
🔍 Latest deploy log https://app.netlify.com/projects/cozystack/deploys/69e2885a7a12ff00080f7fda
😎 Deploy Preview https://deploy-preview-499--cozystack.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 17, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd9d622c-4755-4fd5-b443-7518118763ca

📥 Commits

Reviewing files that changed from the base of the PR and between 6955a88 and 54490f8.

📒 Files selected for processing (70)
  • content/en/blog/2020-05-14-configuring-routing-for-metallb-in-l2-mode.md
  • content/en/blog/2024-02-20-cozystack-v0-1.md
  • content/en/blog/2024-02-21-introducing-cozystack-a-free-paas-platform-based-on-kubernetes.md
  • content/en/blog/2024-04-05-cozystack-v0-2.md
  • content/en/blog/2024-04-05-diy-create-your-own-cloud-with-kubernetes-part-1/index.md
  • content/en/blog/2024-04-05-diy-create-your-own-cloud-with-kubernetes-part-2/index.md
  • content/en/blog/2024-04-05-diy-create-your-own-cloud-with-kubernetes-part-3/index.md
  • content/en/blog/2024-04-18-cozystack-v0-3.md
  • content/en/blog/2024-05-06-cozystack-v0-4.md
  • content/en/blog/2024-05-10-cozystack-v0-5.md
  • content/en/blog/2024-05-16-cozystack-v0-6.md
  • content/en/blog/2024-05-29-cozystack-v0-7.md
  • content/en/blog/2024-05-29-introducing-talm-a-configuration-manager-for-talos-linux.md
  • content/en/blog/2024-07-04-cozystack-v0-8.md
  • content/en/blog/2024-07-10-cozystack-v0-9.md
  • content/en/blog/2024-07-23-cozystack-v0-10.md
  • content/en/blog/2024-08-15-cozystack-v0-11.md
  • content/en/blog/2024-08-16-installing-a-kubernetes-cluster-managed-by-cozystack-a-detailed-guide-by-gohost-and-nix.md
  • content/en/blog/2024-08-21-cozystack-v0-12.md
  • content/en/blog/2024-08-31-cozystack-v0-13.md
  • content/en/blog/2024-09-04-cozystack-v0-14.md
  • content/en/blog/2024-09-16-cozystack-v0-15.md
  • content/en/blog/2024-09-25-cozystack-has-officially-been-included-in-the-cncf-landscape.md
  • content/en/blog/2024-09-26-recent-changes-in-the-cozystack-open-source-platform-opencost-log-collection-system-bridge.md
  • content/en/blog/2024-10-03-the-open-source-platform-cozystack-version-0-16-0.md
  • content/en/blog/2024-10-04-cozystack-on-hacktoberfest-become-a-part-of-the-global-it-event.md
  • content/en/blog/2024-10-24-what-s-new-in-cozystack-v0-17.md
  • content/en/blog/2024-11-07-cozystack-v0-18.md
  • content/en/blog/2024-12-04-cozystack-v0-19.md
  • content/en/blog/2024-12-12-cozystack-v0-20-release-terraform-keycloak-and-stability-security-improvements.md
  • content/en/blog/2024-12-12-how-we-built-a-dynamic-kubernetes-api-server-for-the-api-aggregation-layer-in-cozystack.md
  • content/en/blog/2024-12-28-introducing-the-pre-new-year-release-of-open-source-platform-cozystack-v0-21.md
  • content/en/blog/2025-01-17-cozystack-v0-22-release-telemetry-patched-talos-v1-9-1-new-entities-workload-workloadmonitor.md
  • content/en/blog/2025-01-17-cozystack-v0-23.md
  • content/en/blog/2025-03-13-cozystack-becomes-a-cncf-sandbox-project.md
  • content/en/blog/2025-04-10-cozystack-v0-30.md
  • content/en/blog/2025-04-10-updates-to-the-open-source-platform-cozystack-0-24-0-29.md
  • content/en/blog/2025-04-18-cozystack-now-offers-gpu-passthrough-for-ai-ml-virtual-machines.md
  • content/en/blog/2025-04-28-a-simple-way-to-install-talos-linux-on-any-machine-with-any-provider.md
  • content/en/blog/2025-05-21-cozystack-recognized-in-cncf-s-cnai-landscape.md
  • content/en/blog/2025-06-04-the-evolution-of-virtualization-platforms-the-rise-of-managed-services-and-local-providers-edge.md
  • content/en/blog/2025-06-06-cozystack-became-a-certified-kubernetes-platform.md
  • content/en/blog/2025-06-18-cozyhr-how-we-simplified-local-development-with-helm-and-flux.md
  • content/en/blog/2025-07-09-cozystack-v0-31-0-33.md
  • content/en/blog/2025-08-04-cozystack-v0-34.md
  • content/en/blog/2025-08-14-invitation-to-cozysummit-virtual-december-3.md
  • content/en/blog/2025-08-21-cozystack-v0-35.md
  • content/en/blog/2025-09-03-cncf-webinar-one-api-to-rule-them-all-building-a-unified-platform-with-kubernetes-aggregation.md
  • content/en/blog/2025-09-05-new-cncf-webinar-building-your-own-cloud-platform-with-open-source.md
  • content/en/blog/2025-09-10-protofire-experience-operating-kubernetes-with-cozystack.md
  • content/en/blog/2025-10-01-cozystack-v0-36.md
  • content/en/blog/2025-10-08-cozystack-applied-to-cncf-incubated.md
  • content/en/blog/2025-10-10-cozystack-v0-37.md
  • content/en/blog/2025-10-14-cozysummit-lineup-is-out.md
  • content/en/blog/2025-11-25-cozystack-v0-38.md
  • content/en/blog/2025-12-12-flux-aio-kubernetes-mtls-and-the-chicken-and-egg-problem/index.md
  • content/en/blog/2025-12-17-talm-v0-17-built-in-age-encryption-for-secrets.md
  • content/en/blog/2025-12-23-cozystack-v0-39.md
  • content/en/blog/2026-01-10-cozystack-v0-40.md
  • content/en/blog/2026-01-20-cozystack-v0-41.md
  • content/en/blog/2026-02-11-invitation-to-cozysummit-virtual-may-26.md
  • content/en/blog/2026-03-11-cozystack-at-kubecon-amsterdam-26.md
  • content/en/blog/2026-03-31-cozystack-1-2-opensearch-vpc-peering-and-smarter-tenant-scheduling.md
  • content/en/blog/2026-04-06-cozysummit-virtual-2026-the-program-is-set/index.md
  • content/en/blog/2026-04-08-cozystack-oss-health-section/index.md
  • content/en/blog/2026-04-17-managed-postgresql-synchronous-replication/index.md
  • content/en/blog/cozystack-1-0-release/index.md
  • content/en/blog/game-servers-on-cozystack-no-april-fools-joke/index.md
  • hugo.yaml
  • layouts/blog/list.html

📝 Walkthrough

Walkthrough

This PR adds metadata taxonomy support to the blog by introducing article_types and topics front-matter fields to 58 blog posts, configures Hugo taxonomies, and implements interactive blog filtering via select dropdowns in the blog list template.

Changes

Cohort / File(s) Summary
Blog Post Metadata Updates
content/en/blog/2020-05-14-configuring-routing-for-metallb-in-l2-mode.md, content/en/blog/2024-02-20-cozystack-v0-1.md, content/en/blog/2024-02-21-introducing-cozystack-a-free-paas-platform-based-on-kubernetes.md, content/en/blog/2024-04-05-cozystack-v0-2.md, content/en/blog/2024-04-05-diy-create-your-own-cloud-with-kubernetes-part-1/index.md, content/en/blog/2024-04-05-diy-create-your-own-cloud-with-kubernetes-part-2/index.md, content/en/blog/2024-04-05-diy-create-your-own-cloud-with-kubernetes-part-3/index.md, content/en/blog/2024-04-18-cozystack-v0-3.md, content/en/blog/2024-05-06-cozystack-v0-4.md, content/en/blog/2024-05-10-cozystack-v0-5.md, content/en/blog/2024-05-16-cozystack-v0-6.md, content/en/blog/2024-05-29-cozystack-v0-7.md, content/en/blog/2024-05-29-introducing-talm-a-configuration-manager-for-talos-linux.md, content/en/blog/2024-07-04-cozystack-v0-8.md, content/en/blog/2024-07-10-cozystack-v0-9.md, content/en/blog/2024-07-23-cozystack-v0-10.md, content/en/blog/2024-08-15-cozystack-v0-11.md, content/en/blog/2024-08-16-installing-a-kubernetes-cluster-managed-by-cozystack-a-detailed-guide-by-gohost-and-nix.md, content/en/blog/2024-08-21-cozystack-v0-12.md, content/en/blog/2024-08-31-cozystack-v0-13.md, content/en/blog/2024-09-04-cozystack-v0-14.md, content/en/blog/2024-09-16-cozystack-v0-15.md, content/en/blog/2024-09-25-cozystack-has-officially-been-included-in-the-cncf-landscape.md, content/en/blog/2024-09-26-recent-changes-in-the-cozystack-open-source-platform-opencost-log-collection-system-bridge.md, content/en/blog/2024-10-03-the-open-source-platform-cozystack-version-0-16-0.md, content/en/blog/2024-10-04-cozystack-on-hacktoberfest-become-a-part-of-the-global-it-event.md, content/en/blog/2024-10-24-what-s-new-in-cozystack-v0-17.md, content/en/blog/2024-11-07-cozystack-v0-18.md, content/en/blog/2024-12-04-cozystack-v0-19.md, content/en/blog/2024-12-12-cozystack-v0-20-release-terraform-keycloak-and-stability-security-improvements.md, content/en/blog/2024-12-12-how-we-built-a-dynamic-kubernetes-api-server-for-the-api-aggregation-layer-in-cozystack.md, content/en/blog/2024-12-28-introducing-the-pre-new-year-release-of-open-source-platform-cozystack-v0-21.md, content/en/blog/2025-01-17-cozystack-v0-22-release-telemetry-patched-talos-v1-9-1-new-entities-workload-workloadmonitor.md, content/en/blog/2025-01-17-cozystack-v0-23.md, content/en/blog/2025-03-13-cozystack-becomes-a-cncf-sandbox-project.md, content/en/blog/2025-04-10-cozystack-v0-30.md, content/en/blog/2025-04-10-updates-to-the-open-source-platform-cozystack-0-24-0-29.md, content/en/blog/2025-04-18-cozystack-now-offers-gpu-passthrough-for-ai-ml-virtual-machines.md, content/en/blog/2025-04-28-a-simple-way-to-install-talos-linux-on-any-machine-with-any-provider.md, content/en/blog/2025-05-21-cozystack-recognized-in-cncf-s-cnai-landscape.md, content/en/blog/2025-06-04-the-evolution-of-virtualization-platforms-the-rise-of-managed-services-and-local-providers-edge.md, content/en/blog/2025-06-06-cozystack-became-a-certified-kubernetes-platform.md, content/en/blog/2025-06-18-cozyhr-how-we-simplified-local-development-with-helm-and-flux.md, content/en/blog/2025-07-09-cozystack-v0-31-0-33.md, content/en/blog/2025-08-04-cozystack-v0-34.md, content/en/blog/2025-08-14-invitation-to-cozysummit-virtual-december-3.md, content/en/blog/2025-08-21-cozystack-v0-35.md, content/en/blog/2025-09-03-cncf-webinar-one-api-to-rule-them-all-building-a-unified-platform-with-kubernetes-aggregation.md, content/en/blog/2025-09-05-new-cncf-webinar-building-your-own-cloud-platform-with-open-source.md, content/en/blog/2025-09-10-protofire-experience-operating-kubernetes-with-cozystack.md, content/en/blog/2025-10-01-cozystack-v0-36.md, content/en/blog/2025-10-08-cozystack-applied-to-cncf-incubated.md, content/en/blog/2025-10-10-cozystack-v0-37.md, content/en/blog/2025-10-14-cozysummit-lineup-is-out.md, content/en/blog/2025-11-25-cozystack-v0-38.md, content/en/blog/2025-12-12-flux-aio-kubernetes-mtls-and-the-chicken-and-egg-problem/index.md, content/en/blog/2025-12-17-talm-v0-17-built-in-age-encryption-for-secrets.md, content/en/blog/2025-12-23-cozystack-v0-39.md, content/en/blog/2026-01-10-cozystack-v0-40.md, content/en/blog/2026-01-20-cozystack-v0-41.md, content/en/blog/2026-02-11-invitation-to-cozysummit-virtual-may-26.md, content/en/blog/2026-03-11-cozystack-at-kubecon-amsterdam-26.md, content/en/blog/2026-03-31-cozystack-1-2-opensearch-vpc-peering-and-smarter-tenant-scheduling.md, content/en/blog/2026-04-06-cozysummit-virtual-2026-the-program-is-set/index.md, content/en/blog/2026-04-08-cozystack-oss-health-section/index.md, content/en/blog/2026-04-17-managed-postgresql-synchronous-replication/index.md, content/en/blog/cozystack-1-0-release/index.md, content/en/blog/game-servers-on-cozystack-no-april-fools-joke/index.md
Added YAML front-matter fields article_types and topics to categorize blog content. Each post receives classification values like release, news, how-to, tech-article, or case, and topic tags such as platform, kubernetes, networking, storage, etc.
Hugo Configuration
hugo.yaml
Added taxonomies section defining two new taxonomy axes: article_type: article_types and topic: topics, enabling Hugo to generate taxonomy list pages alongside preserved default tag and category mappings.
Blog List Template
layouts/blog/list.html
Implemented interactive filtering UI with two dropdown selectors (Type and Topic) and client-side JavaScript logic that: (1) adds data-article-types and data-topics attributes to blog post cards, (2) syncs filter selections to URL query parameters (?type= / ?topic=), (3) hides/shows posts based on selections, (4) collapses empty year sections. Removed pagination block from template.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • lllamnyp
  • nbykov0

Poem

🐰 Fifty-eight blogs now wear their tags with pride,
Article types and topics organized side by side,
Hugo's taxonomies spin their magic thread,
Filters dance on dropdowns—no more manual spread!
A hopping celebration of content control,
Where rabbits organize knowledge as a whole! ✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/blog-taxonomies-and-filters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a dynamic filtering system for the blog, utilizing new Hugo taxonomies for article types and topics. The implementation includes a filter UI in the blog list layout with corresponding CSS and JavaScript for client-side interactivity. Feedback suggests ensuring the alphabetical sorting of topics, enhancing accessibility by adding ARIA live regions to the post counter, and improving browser history support by utilizing pushState instead of replaceState.

Comment thread layouts/blog/list.html Outdated
Comment on lines +106 to +110
{{ range $slug, $_ := .Site.Taxonomies.topics }}
<button type="button" class="blog-filter__chip"
data-filter-kind="topic" data-filter-value="{{ $slug }}"
aria-pressed="false">{{ $slug | humanize }}</button>
{{ end }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PR description mentions that topics are "auto-sorted", but ranging over the .Site.Taxonomies.topics map in Hugo does not guarantee alphabetical order. To ensure the topics are consistently sorted by name as intended, you should use the .Alphabetical method.

Suggested change
{{ range $slug, $_ := .Site.Taxonomies.topics }}
<button type="button" class="blog-filter__chip"
data-filter-kind="topic" data-filter-value="{{ $slug }}"
aria-pressed="false">{{ $slug | humanize }}</button>
{{ end }}
{{ range .Site.Taxonomies.topics.Alphabetical }}
<button type="button" class="blog-filter__chip"
data-filter-kind="topic" data-filter-value="{{ .Term }}"
aria-pressed="false">{{ .Term | humanize }}</button>
{{ end }}

Comment thread layouts/blog/list.html Outdated
{{ end }}
</div>
<div class="blog-filter__footer">
<p class="blog-filter__count" id="blog-filter-count"></p>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The post counter is updated dynamically via JavaScript. To ensure that screen reader users are notified when the count changes after applying a filter, the element should be marked as an ARIA live region.

Suggested change
<p class="blog-filter__count" id="blog-filter-count"></p>
<p class="blog-filter__count" id="blog-filter-count" aria-live="polite"></p>

Comment thread layouts/blog/list.html
if (topics.length) p.set('topics', topics.join(',')); else p.delete('topics');
var q = p.toString();
var next = window.location.pathname + (q ? '?' + q : '') + window.location.hash;
window.history.replaceState(null, '', next);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PR description states that "back/forward works" for the filter UI, but the implementation uses history.replaceState, which does not create history entries. To support back/forward navigation through filter states, history.pushState should be used instead. Note that if you switch to pushState, you should also add a popstate event listener to re-apply filters when the user navigates through their history.

Suggested change
window.history.replaceState(null, '', next);
window.history.pushState(null, '', next);

tym83 added 2 commits April 18, 2026 00:01
Replace the chip-based multi-select filter with two plain <select>
dropdowns, one for article type and one for topic. Only one dropdown
can be active at a time: selecting a value in either clears the other.
Selection is single-value within each dropdown, no multi-select.

URL state simplified to a single query param: ?type=... or ?topic=...
(never both). Reflects the new interaction model one-to-one.

Signed-off-by: tym83 <6355522@gmail.com>
@tym83 tym83 marked this pull request as ready for review April 17, 2026 19:24
@tym83 tym83 requested review from kvaps and lllamnyp as code owners April 17, 2026 19:24
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.

Once credits are available, reopen this pull request to trigger a review.

@tym83 tym83 merged commit 6cd9eb1 into main Apr 17, 2026
5 of 6 checks passed
@tym83 tym83 deleted the feat/blog-taxonomies-and-filters branch April 17, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant