taggart

Simple golang tagging filesystem webapp
Log | Files | Refs

commit 7d413502ec063df8b50016c25118721532b29436
parent abc6ee37e48263f3dc67fa380aa525fe24e64ab5
Author: breadcat <breadcat@users.noreply.github.com>
Date:   Sun, 21 Sep 2025 08:15:00 +0100

Implement head and footer templates

Diffstat:
Mmain.go | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Dstatic/style.css | 16----------------
Atemplates/_footer.html | 5+++++
Atemplates/_header.html | 27+++++++++++++++++++++++++++
Mtemplates/file.html | 32+++++++++++++-------------------
Mtemplates/list.html | 16++++------------
Mtemplates/tags.html | 15++++-----------
Mtemplates/untagged.html | 14+++-----------
Mtemplates/upload.html | 12+++---------
9 files changed, 116 insertions(+), 97 deletions(-)

diff --git a/main.go b/main.go @@ -32,6 +32,11 @@ type TagDisplay struct { Count int } +type PageData struct { + Title string + Data interface{} +} + func main() { var err error db, err = sql.Open("sqlite3", "./database.db") @@ -199,12 +204,16 @@ func listFilesHandler(w http.ResponseWriter, r *http.Request) { untagged = append(untagged, f) } - tmpl.ExecuteTemplate(w, "list.html", struct { - Tagged []File - Untagged []File - }{tagged, untagged}) -} + pageData := PageData{ + Title: "Home", + Data: struct { + Tagged []File + Untagged []File + }{tagged, untagged}, + } + tmpl.ExecuteTemplate(w, "list.html", pageData) +} // Show untagged files at /untagged func untaggedFilesHandler(w http.ResponseWriter, r *http.Request) { @@ -227,14 +236,22 @@ func untaggedFilesHandler(w http.ResponseWriter, r *http.Request) { files = append(files, f) } - tmpl.ExecuteTemplate(w, "untagged.html", files) -} + pageData := PageData{ + Title: "Untagged Files", + Data: files, + } + tmpl.ExecuteTemplate(w, "untagged.html", pageData) +} // Upload a file func uploadHandler(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { - tmpl.ExecuteTemplate(w, "upload.html", nil) + pageData := PageData{ + Title: "Upload File", + Data: nil, + } + tmpl.ExecuteTemplate(w, "upload.html", pageData) return } @@ -319,10 +336,15 @@ func fileHandler(w http.ResponseWriter, r *http.Request) { return } - tmpl.ExecuteTemplate(w, "file.html", struct { - File File - Categories []string - }{f, cats}) + pageData := PageData{ + Title: f.Filename, + Data: struct { + File File + Categories []string + }{f, cats}, + } + + tmpl.ExecuteTemplate(w, "file.html", pageData) } // Delete tag from file @@ -366,7 +388,12 @@ func tagsHandler(w http.ResponseWriter, r *http.Request) { tagMap[cat] = append(tagMap[cat], TagDisplay{Value: val, Count: count}) } - tmpl.ExecuteTemplate(w, "tags.html", tagMap) + pageData := PageData{ + Title: "All Tags", + Data: tagMap, + } + + tmpl.ExecuteTemplate(w, "tags.html", pageData) } // Filter files by tags @@ -411,10 +438,20 @@ func tagFilterHandler(w http.ResponseWriter, r *http.Request) { files = append(files, f) } - // Wrap in the same struct expected by list.html - tmpl.ExecuteTemplate(w, "list.html", struct { - Tagged []File - Untagged []File - }{files, nil}) -} + // Create title from filters + var titleParts []string + for _, f := range filters { + titleParts = append(titleParts, fmt.Sprintf("%s: %s", f.Category, f.Value)) + } + title := "Tagged: " + strings.Join(titleParts, ", ") + + pageData := PageData{ + Title: title, + Data: struct { + Tagged []File + Untagged []File + }{files, nil}, + } + tmpl.ExecuteTemplate(w, "list.html", pageData) +} +\ No newline at end of file diff --git a/static/style.css b/static/style.css @@ -1,15 +0,0 @@ -/* main body styling */ -body {background: #1a1a1a; color: #cfcfcf; font-family: sans-serif} -a {color: lightblue; text-decoration: none} -a:hover {text-decoration: underline} - -/* cascading menu */ -ul.tag-menu,ul.tag-menu ul{list-style:none;margin:0;padding:0} -ul.tag-menu li{position:relative} -ul.tag-menu>li{display:inline-block;margin-right:20px} -ul.tag-menu li a{text-decoration:none;padding:5px 10px;display:block;background:#eee;color:#333} -ul.tag-menu li ul{display:none;position:absolute;top:100%;left:0;min-width:150px;z-index:1000} -ul.tag-menu li ul li,ul.tag-menu li:hover>ul{display:block} -ul.tag-menu li ul li ul{left:100%;top:0} -ul.tag-menu li ul li a{background:#f9f9f9} -ul.tag-menu li ul li a:hover{background:#ddd} -\ No newline at end of file diff --git a/templates/_footer.html b/templates/_footer.html @@ -0,0 +1,4 @@ +{{define "_footer"}} +</body> +</html> +{{end}} +\ No newline at end of file diff --git a/templates/_header.html b/templates/_header.html @@ -0,0 +1,26 @@ +{{define "_header"}} +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>{{if .Title}}{{.Title}} - Taggart{{else}}Taggart{{end}}</title> + <style> +/* main body styling */ +body {background: #1a1a1a; color: #cfcfcf; font-family: sans-serif} +a {color: lightblue; text-decoration: none} +a:hover {text-decoration: underline} + +/* cascading menu */ +ul.tag-menu,ul.tag-menu ul{list-style:none;margin:0;padding:0} +ul.tag-menu li{position:relative} +ul.tag-menu>li{display:inline-block;margin-right:20px} +ul.tag-menu li a{text-decoration:none;padding:5px 10px;display:block;background:#eee;color:#333} +ul.tag-menu li ul{display:none;position:absolute;top:100%;left:0;min-width:150px;z-index:1000} +ul.tag-menu li ul li,ul.tag-menu li:hover>ul{display:block} +ul.tag-menu li ul li ul{left:100%;top:0} +ul.tag-menu li ul li a{background:#f9f9f9} +ul.tag-menu li ul li a:hover{background:#ddd} + </style> +</head> +<body> +{{end}} +\ No newline at end of file diff --git a/templates/file.html b/templates/file.html @@ -1,28 +1,22 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>File {{.File.Filename}}</title> - <link rel="stylesheet" type="text/css" href="/static/style.css"> -</head> -<body> -<h2>File: {{.File.Filename}}</h2> +{{template "_header" .}} +File {{.Data.File.Filename}} +<h2>File: {{.Data.File.Filename}}</h2> -{{if hasAnySuffix .File.Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}} - <img src="/uploads/{{.File.Filename}}" style="max-width:400px"><br> -{{else if hasAnySuffix .File.Filename ".mp4" ".webm" ".mov"}} +{{if hasAnySuffix .Data.File.Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}} + <img src="/uploads/{{.Data.File.Filename}}" style="max-width:400px"><br> +{{else if hasAnySuffix .Data.File.Filename ".mp4" ".webm" ".mov"}} <video controls width="400"> - <source src="/uploads/{{.File.Filename}}"> + <source src="/uploads/{{.Data.File.Filename}}"> </video><br> {{else}} - <a href="/uploads/{{.File.Filename}}">Download file</a><br> + <a href="/uploads/{{.Data.File.Filename}}">Download file</a><br> {{end}} <h3>Tags</h3> <ul> -{{range $k, $v := .File.Tags}} +{{range $k, $v := .Data.File.Tags}} <li>{{$k}}: {{$v}} - <form style="display:inline" method="post" action="/file/{{$.File.ID}}/tag/{{$k}}/{{$v}}/delete"> + <form style="display:inline" method="post" action="/file/{{$.Data.File.ID}}/tag/{{$k}}/{{$v}}/delete"> <button type="submit">Remove</button> </form> </li> @@ -35,7 +29,7 @@ <form method="post"> Category: <input type="text" name="category" list="categories"><br> <datalist id="categories"> - {{range .Categories}} + {{range .Data.Categories}} <option value="{{.}}"> {{end}} </datalist> @@ -44,5 +38,4 @@ </form> <p><a href="/">← Back to list</a></p> -</body> -</html> +{{template "_footer"}} +\ No newline at end of file diff --git a/templates/list.html b/templates/list.html @@ -1,17 +1,10 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Files</title> - <link rel="stylesheet" type="text/css" href="/static/style.css"> -</head> -<body> +{{template "_header" .}} <h1>Files</h1> <p><a href="/upload">Upload new file</a> | <a href="/tags">Browse tags</a> | <a href="/untagged">Untagged files</a></p> <h2>Tagged Files</h2> <ul> -{{range .Tagged}} +{{range .Data.Tagged}} <li> <a href="/file/{{.ID}}">{{.Filename}}</a><br> {{if hasAnySuffix .Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}} @@ -29,7 +22,7 @@ <h2>Untagged Files</h2> <ul> -{{range .Untagged}} +{{range .Data.Untagged}} <li> <a href="/file/{{.ID}}">{{.Filename}}</a><br> {{if hasAnySuffix .Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}} @@ -44,5 +37,4 @@ <li>No untagged files.</li> {{end}} </ul> -</body> -</html> +{{template "_footer"}} diff --git a/templates/tags.html b/templates/tags.html @@ -1,16 +1,9 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Tags</title> - <link rel="stylesheet" type="text/css" href="/static/style.css"> -</head> -<body> +{{template "_header" .}} <h1>All Tags</h1> <p><a href="/">Back to files</a></p> <ul class="tag-menu"> -{{range $cat, $tags := .}} +{{range $cat, $tags := .Data}} <li> <a href="#">{{$cat}}</a> <ul> @@ -21,5 +14,4 @@ </li> {{end}} </ul> -</body> -</html> +{{template "_footer"}} +\ No newline at end of file diff --git a/templates/untagged.html b/templates/untagged.html @@ -1,16 +1,9 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Untagged Files</title> - <link rel="stylesheet" type="text/css" href="/static/style.css"> -</head> -<body> +{{template "_header" .}} <h1>Untagged Files</h1> <p><a href="/">Back to all files</a> | <a href="/upload">Upload new file</a></p> <ul> -{{range .}} +{{range .Data}} <li> <a href="/file/{{.ID}}">{{.Filename}}</a><br> {{if hasAnySuffix .Filename ".jpg" ".jpeg" ".png" ".gif" ".webp"}} @@ -25,5 +18,4 @@ <li>No untagged files.</li> {{end}} </ul> -</body> -</html> +{{template "_footer"}} diff --git a/templates/upload.html b/templates/upload.html @@ -1,9 +1,4 @@ -<!DOCTYPE html> -<html> -<head> - <link rel="stylesheet" type="text/css" href="/static/style.css"> -</head> -<body> +{{template "_header" .}} <h2>Upload File</h2> <form method="post" enctype="multipart/form-data"> <input type="file" name="file"> @@ -17,5 +12,4 @@ </form> <a href="/">Back to files</a> -</body> -</html> -\ No newline at end of file +{{template "_footer"}} +\ No newline at end of file