From fedc153483fbab1e19931573ade0b2738f5f94b4 Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Sat, 6 Jun 2026 10:45:54 +0000 Subject: [PATCH] Step 8: Taxonomie-Seiten (Kategorien und Tags) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Vier neue Seiten für das Blog-Taxonomie-System: - /blog/categories/ — Übersicht aller Kategorien - /categories/[term]/ — Artikel einer Kategorie (mit Wortanzahl/Lesezeit) - /blog/tags/ — Übersicht aller Tags - /tags/[term]/ — Artikel eines Tags (mit Wortanzahl/Lesezeit) Zugleich BlogNav überarbeitet: korrekte active/off-Zustände für Taxonomy-Kontext (Archiv-Subtree wird nur bei onArchive/onBlog gerendert, Category/Tag-Items erhalten nav-leaf-Klasse wenn nicht im Taxonomy-Kontext). Entspricht Hugos categories/taxonomy.html und categories/term.html Layouts. Co-Authored-By: Claude Sonnet 4.6 --- src/components/BlogNav.astro | 153 ++++++++++++++++++-------- src/pages/blog/categories/index.astro | 52 +++++++++ src/pages/blog/tags/index.astro | 52 +++++++++ src/pages/categories/[term].astro | 93 ++++++++++++++++ src/pages/tags/[term].astro | 93 ++++++++++++++++ 5 files changed, 397 insertions(+), 46 deletions(-) create mode 100644 src/pages/blog/categories/index.astro create mode 100644 src/pages/blog/tags/index.astro create mode 100644 src/pages/categories/[term].astro create mode 100644 src/pages/tags/[term].astro diff --git a/src/components/BlogNav.astro b/src/components/BlogNav.astro index d4da2825..fa44f530 100644 --- a/src/components/BlogNav.astro +++ b/src/components/BlogNav.astro @@ -52,11 +52,29 @@ const mainSections = [ { name: 'about', url: '/about.html', title: 'About' }, ]; +// URL classification const onBlog = currentUrl === '/blog/'; -// A blog post URL (flat, not /blog/...) still counts as "in archive" const isOnBlogPost = allPosts.some(p => (p.data.url ?? `/${p.id}/`) === currentUrl); const onArchive = currentUrl.startsWith('/blog/archive/') || isOnBlogPost; -const blogSelected = onBlog || onArchive; + +const onCategoriesIndex = currentUrl === '/blog/categories/'; +const onCategoryTerm = currentUrl.startsWith('/categories/'); +const onTagsIndex = currentUrl === '/blog/tags/'; +const onTagTerm = currentUrl.startsWith('/tags/'); + +const blogSelected = onBlog || onArchive || onCategoriesIndex || onCategoryTerm || onTagsIndex || onTagTerm; + +// Active state flags +const categoriesSelected = onCategoriesIndex || onCategoryTerm; +const tagsSelected = onTagsIndex || onTagTerm; + +// "off" class logic derived from Hugo nav output: +// On archive pages: Categories and Tags are off; Archive is normal (selected) +// On category term: Archive and Tags are off +// On tag term: Archive and Categories are off +const archiveOff = onCategoryTerm || onTagTerm; +const categoriesOff = onArchive || onTagTerm; +const tagsOff = onArchive || onCategoryTerm; // Determine active section const activeSection = mainSections.find(s => { @@ -74,6 +92,10 @@ function isActiveYear(year: string) { return currentUrl === `/blog/archive/${year}/` || postsByYear[year]?.some(p => postUrl(p) === currentUrl) === true; } + +// Active taxonomy term from URL +const activeCatSlug = onCategoryTerm ? currentUrl.replace(/^\/categories\//, '').replace(/\/$/, '') : ''; +const activeTagSlug = onTagTerm ? currentUrl.replace(/^\/tags\//, '').replace(/\/$/, '') : ''; ---