package core import "strings" // NavItem is one entry in the repo-scoped navigation -- the top tab bar // and the page-nav chips both render the same slice, built from the route // table so a new tab is a one-line addition to site/routes.go, not a // second place to remember. type NavItem struct { Label string Href string Active bool } // BuildNav derives the repo-scoped nav from every route whose NavLabel is // set, in route-table order. current is the name of the route being // served, used to mark the matching tab active. func BuildNav(routes []Route, current, slug, ref string) []NavItem { if slug == "" { return nil } var items []NavItem for _, rt := range routes { if rt.Scope != ScopeRepo || rt.NavLabel == "" { continue } items = append(items, NavItem{ Label: rt.NavLabel, Href: navHref(rt, slug, ref), // The "repo" route (bare /{repo}/) renders tree.html at its // root, same as "tree" does at path "" -- so the files tab // lights up on both, even though "repo" carries no NavLabel // of its own and never appears in this loop as a tab. Active: rt.Name == current || (rt.Name == "tree" && current == "repo"), }) } return items } // navHref builds the href for a nav tab from its route pattern: the fixed // segment right after {repo}, plus the ref if the route is ref-addressed // ({rest...} or {rev}). Routes addressed only by {$} (graph, refs) link to // their bare index instead. func navHref(rt Route, slug, ref string) string { seg := navSegment(rt.Pattern) href := "/" + slug + "/" if seg != "" { href += seg + "/" } if strings.Contains(rt.Pattern, "{rest...}") || strings.Contains(rt.Pattern, "{rev}") { href += ref } return href } // navSegment extracts the literal path element between {repo} and the // next wildcard, e.g. "GET /{repo}/tree/{rest...}" -> "tree". Returns "" // for patterns with no such segment (e.g. "GET /{repo}/{$}"). func navSegment(pattern string) string { p := pattern if i := strings.IndexByte(p, ' '); i >= 0 { p = p[i+1:] } p = strings.TrimPrefix(p, "/{repo}/") seg, _, _ := strings.Cut(p, "/") if strings.HasPrefix(seg, "{") { return "" } return seg }