]> juplo.de Git - website/commitdiff
Breadcrumb zeigt kanonischen Nav-Pfad statt Schnellzugriff-Pfad
authorKai Moritz <kai.milan.moritz@googlemail.com>
Sun, 21 Jun 2026 07:28:38 +0000 (07:28 +0000)
committerKai Moritz <kai.milan.moritz@googlemail.com>
Sun, 21 Jun 2026 07:28:38 +0000 (07:28 +0000)
Der bisherige Breadcrumb war auf 3 Einträge (Home → Projects → Titel)
hartkodiert und ignorierte die Nav-Hierarchie. Für Seiten mit Alias-Einträgen
(z.B. Mojo-Seiten) wirkte das wie der Schnellzugriff-Pfad.

Neue Funktion findCanonicalPath() traversiert den Nav-Baum unter Auslassung
von Alias-Nodes und liefert den vollständigen Pfad von der Projekt-Wurzel
zur aktuellen Seite. ProjectPage.astro baut den Breadcrumb daraus auf.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
src/components/ProjectPage.astro
src/lib/projects.ts

index a8526463690b1eae09ffb4dff50771a20cef24c5..031c48cdf349d4542285bc5af0a2259346060715 100644 (file)
@@ -3,6 +3,7 @@ import { getEntry } from 'astro:content';
 import BaseLayout from '../layouts/BaseLayout.astro';
 import Breadcrumb from '../components/Breadcrumb.astro';
 import BlogNav from '../components/BlogNav.astro';
+import { getActiveProject, findCanonicalPath } from '../lib/projects';
 
 interface Props {
   entryId: string;
@@ -17,11 +18,23 @@ const canonical = params.canonical
   ? new URL(params.canonical, Astro.site).toString()
   : undefined;
 
-const crumbs = [
-  { title: 'Home', url: '/' },
-  { title: 'Projects', url: '/projects/' },
-  { title },
-];
+const activeProject = await getActiveProject(url);
+const navPath = activeProject?.navRoot
+  ? findCanonicalPath(activeProject.navRoot, url)
+  : null;
+
+const crumbs = navPath && navPath.length > 0
+  ? [
+      { title: 'Home', url: '/' },
+      { title: 'Projects', url: '/projects/' },
+      ...navPath.slice(0, -1).map(node => ({ title: node.title, url: node.url })),
+      { title: navPath[navPath.length - 1].title },
+    ]
+  : [
+      { title: 'Home', url: '/' },
+      { title: 'Projects', url: '/projects/' },
+      { title },
+    ];
 ---
 
 <BaseLayout title={title} canonical={canonical}>
index 125ee04002814c9281dc292d9b829cdca5bbb999..e69932499961a74f6ea84577a51d84163e084cf1 100644 (file)
@@ -137,6 +137,21 @@ export async function getActiveProject(currentUrl: string): Promise<ProjectInfo
   return null;
 }
 
+// Find the path from navRoot to the canonical (non-alias) node matching `url`.
+// Returns [root, ..., target], or null if not found.
+export function findCanonicalPath(
+  node: ProjectNavNode,
+  url: string,
+): ProjectNavNode[] | null {
+  if (node.isAlias) return null;
+  if (node.url === url) return [node];
+  for (const c of node.children) {
+    const sub = findCanonicalPath(c, url);
+    if (sub) return [node, ...sub];
+  }
+  return null;
+}
+
 // Returns the nav tree for ALL visible projects (for the normal-case nav).
 export async function getVisibleProjectNavTrees(): Promise<ProjectInfo[]> {
   const pages = await getAllProjectPages();