commit dcec674f5b6e46e4dfad1eb550caeece7a331034
parent 29b51e3c69facf17865e20e03e1d3fea523cc57c
Author: breadcat <breadcat@users.noreply.github.com>
Date: Wed, 10 Dec 2025 22:32:09 +0000
Implement breadcrumb bar on tag filter page
Diffstat:
3 files changed, 82 insertions(+), 10 deletions(-)
diff --git a/main.go b/main.go
@@ -46,6 +46,11 @@ type Config struct {
TagAliases []TagAliasGroup `json:"tag_aliases"`
}
+type Breadcrumb struct {
+ Name string
+ URL string
+}
+
type TagAliasGroup struct {
Category string `json:"category"`
Aliases []string `json:"aliases"`
@@ -56,6 +61,12 @@ type TagDisplay struct {
Count int
}
+type ListData struct {
+ Tagged []File
+ Untagged []File
+ Breadcrumbs []Breadcrumb
+}
+
type PageData struct {
Title string
Data interface{}
@@ -64,6 +75,7 @@ type PageData struct {
Port string
Files []File
Tags map[string][]TagDisplay
+ Breadcrumbs []Breadcrumb
Pagination *Pagination
GallerySize string
}
@@ -588,10 +600,11 @@ func listFilesHandler(w http.ResponseWriter, r *http.Request) {
total = untaggedTotal
}
- pageData := buildPageDataWithPagination("Home", struct {
- Tagged []File
- Untagged []File
- }{tagged, untagged}, page, total, perPage)
+ pageData := buildPageDataWithPagination("File Browser", ListData{
+ Tagged: tagged,
+ Untagged: untagged,
+ Breadcrumbs: []Breadcrumb{},
+ }, page, total, perPage)
renderTemplate(w, "list.html", pageData)
}
@@ -1006,8 +1019,15 @@ func tagFilterHandler(w http.ResponseWriter, r *http.Request) {
Values []string // Expanded values including aliases
}
+ breadcrumbs := []Breadcrumb{
+ {Name: "Home", URL: "/"},
+ {Name: "Tags", URL: "/tags"}, // or wherever your tags overview page is
+ }
+
var filters []filter
- for _, pair := range tagPairs {
+ currentPath := "/tag"
+
+ for i, pair := range tagPairs {
parts := strings.Split(pair, "/")
if len(parts) != 2 {
renderError(w, "Invalid tag filter path", http.StatusBadRequest)
@@ -1025,6 +1045,34 @@ func tagFilterHandler(w http.ResponseWriter, r *http.Request) {
}
filters = append(filters, f)
+
+ // Build breadcrumb path incrementally
+ if i == 0 {
+ currentPath += "/" + parts[0] + "/" + parts[1]
+ } else {
+ currentPath += "/and/tag/" + parts[0] + "/" + parts[1]
+ }
+
+ // Add category breadcrumb (only if it's the first occurrence)
+ categoryExists := false
+ for _, bc := range breadcrumbs {
+ if bc.Name == parts[0] {
+ categoryExists = true
+ break
+ }
+ }
+ if !categoryExists {
+ breadcrumbs = append(breadcrumbs, Breadcrumb{
+ Name: strings.Title(parts[0]),
+ URL: "/tags#tag-" + parts[0],
+ })
+ }
+
+ // Add value breadcrumb
+ breadcrumbs = append(breadcrumbs, Breadcrumb{
+ Name: strings.Title(parts[1]),
+ URL: currentPath,
+ })
}
// Build count query
@@ -1126,10 +1174,12 @@ func tagFilterHandler(w http.ResponseWriter, r *http.Request) {
}
title := "Tagged: " + strings.Join(titleParts, ", ")
- pageData := buildPageDataWithPagination(title, struct {
- Tagged []File
- Untagged []File
- }{files, nil}, page, total, perPage)
+ pageData := buildPageDataWithPagination(title, ListData{
+ Tagged: files,
+ Untagged: nil,
+ Breadcrumbs: []Breadcrumb{}, // Empty here
+ }, page, total, perPage)
+ pageData.Breadcrumbs = breadcrumbs // Set at PageData level
renderTemplate(w, "list.html", pageData)
}
diff --git a/static/style.css b/static/style.css
@@ -86,3 +86,10 @@ img.file-content-image {max-width:400px}
.pagination .disabled{color:#666;cursor:not-allowed}
.pagination .page-info{font-weight:700;padding:.5rem 1rem}
.pagination input#pageInput {width: 60px; text-align: center}
+
+/* breadcrumb bar */
+.breadcrumb a,.breadcrumb span,.breadcrumb-separator{vertical-align:bottom}
+.breadcrumb{padding:1rem;font-size:1.1rem}
+.breadcrumb a:hover{text-decoration:underline}
+.breadcrumb span{font-weight:500}
+.breadcrumb-separator{font-size:.8em}
+\ No newline at end of file
diff --git a/templates/list.html b/templates/list.html
@@ -1,5 +1,19 @@
{{template "_header" .}}
-<h1>Files</h1>
+
+{{if .Breadcrumbs}}
+<div class="breadcrumb">
+ {{range $index, $crumb := .Breadcrumbs}}
+ {{if ne $index 0}} <span class="breadcrumb-separator">▶</span> {{end}}
+ {{if $crumb.URL}}
+ <a href="{{$crumb.URL}}">{{$crumb.Name}}</a>
+ {{else}}
+ <a href="/tags#tag-{{$crumb.Name}}">{{$crumb.Name}}</a>
+ {{end}}
+ {{end}}
+</div>
+{{else}}
+<h1>File Browser</h1>
+{{end}}
{{if .Data.Tagged}}
<div class="gallery">