From b233445a73168994087356d45b5dc7dd6a07aa8e Mon Sep 17 00:00:00 2001 From: grm Date: Thu, 17 Sep 2026 21:37:46 +0300 Subject: Add a rule under page and post titles, and tags shown with a # in front MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two Design tab options in the Posts section. The title rule reuses the header rule's kinds (line, dots, stripes): a body class blog.css draws from — width and style only, so the theme CSS's link colour is not reset — ending at a floated thumbnail instead of running under it. The tag hash is applied everywhere tags are listed: under posts, in both tag modules and in the tag page's title. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A --- AGENTS.md | 10 +++++++++- README.md | 3 ++- internal/i18n/el.go | 17 ++++++++++------- internal/web/static/blog.css | 6 ++++++ internal/web/templates.go | 7 +++++++ internal/web/templates/blog/post.html | 2 +- internal/web/templates/blog/tag.html | 4 ++-- internal/web/templates/dashboard/design.html | 7 +++++++ internal/web/templates/layouts/blog.html | 6 +++--- internal/web/templates/partials/postlist.html | 5 +++-- internal/web/theme.go | 19 ++++++++++++++++++- internal/web/web_test.go | 17 +++++++++++++++++ 12 files changed, 85 insertions(+), 18 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d4a9284..bfed5cb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -184,7 +184,15 @@ internal/web/ server.go (host router, middleware, render helpers) as tall as the brand and old browsers agree) in `currentColor`, i.e. the header text colour; hidden on phones so a long title can wrap. `NavStyle` `plain` is regular weight + underline for the menu links (blog.css makes - them bold). + them bold). `TitleRule` (`none` | `line` | `dots` | `stripes`) is the same + rule under page and post titles (`.page-title`, `.post-title`): a body + class from `Theme.TitleRuleClass` (`titles-`) that blog.css draws + (border width/style only — never the shorthand, or it would reset the + colour; stripes are an `::after` gradient in `currentColor`), coloured + by the theme CSS in the link colour; `overflow:hidden` ends it at a floated + thumbnail. `TagHash` lists tags as `#name` wherever they appear: the + `posttags` partial (takes `dict "tags" … "hash" …`), the two tag modules + and the tag page title (`tagname` template func). **Custom fonts** (`CustomFont`, `CustomHeadingFont`: font file ids or ""): a chosen file is declared as `@font-face` (`"BlogFont"` / `"BlogHeadingFont"`, `src:url(/media/)`, same-origin so no CORS) and put first in the stack, diff --git a/README.md b/README.md index b6adffe..800c30d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,8 @@ Server-rendered HTML, no JavaScript required, works on old browsers and phones. - **Design** tab: one form, one Save, organised by part of the blog — colours & fonts (schemes, background colour/image, text and link colours, fonts — built-in stacks or your own uploaded WOFF2/WOFF/TTF/OTF files), header, menu, - content, side columns, footer, logo & site icon. The page is five areas — header, + content (dates, summaries, a rule under titles — line, dots or stripes — and + tags shown as #tag), side columns, footer, logo & site icon. The page is five areas — header, left column, main content, right column, footer — each holding modules in any order: blog title, logo, menu, archive (posts by year and month), recent posts, tags (with counts), tag cloud, a search box (finds posts by title and text, any diff --git a/internal/i18n/el.go b/internal/i18n/el.go index 852d9ab..5603659 100644 --- a/internal/i18n/el.go +++ b/internal/i18n/el.go @@ -385,13 +385,16 @@ var el = map[string]string{ "Uppercase, spaced": "Κεφαλαία, αραιά", "Plain, underlined": "Απλοί, υπογραμμισμένοι", "Show the date on posts": "Εμφάνιση ημερομηνίας στις δημοσιεύσεις", - "Date format": "Μορφή ημερομηνίας", - "Logo & site icon": "Λογότυπο & εικονίδιο ιστολογίου", - "Logo size": "Μέγεθος λογότυπου", - "Small (48 px tall)": "Μικρό (48 px ύψος)", - "Medium (80 px)": "Μεσαίο (80 px)", - "Large (140 px)": "Μεγάλο (140 px)", - "Favicon": "Εικονίδιο (favicon)", + "Show tags with a # in front": "Εμφάνιση των ετικετών με # μπροστά", + "Rule under titles": "Γραμμή κάτω από τους τίτλους", + "page and post titles, in the link colour": "τίτλοι σελίδων και δημοσιεύσεων, στο χρώμα των συνδέσμων", + "Date format": "Μορφή ημερομηνίας", + "Logo & site icon": "Λογότυπο & εικονίδιο ιστολογίου", + "Logo size": "Μέγεθος λογότυπου", + "Small (48 px tall)": "Μικρό (48 px ύψος)", + "Medium (80 px)": "Μεσαίο (80 px)", + "Large (140 px)": "Μεγάλο (140 px)", + "Favicon": "Εικονίδιο (favicon)", "The small icon browsers show in the tab. A square PNG or ICO of 32–64 px works best; pick None for the Blogspace icon.": "Το μικρό εικονίδιο που δείχνουν οι φυλλομετρητές στην καρτέλα. Ένα τετράγωνο PNG ή ICO 32–64 px είναι ιδανικό· επιλέξτε Κανένα για το εικονίδιο του Blogspace.", "Reset to defaults": "Επαναφορά προεπιλογών", "Puts every colour, font and layout option back to how a new blog starts and forgets the chosen images and fonts (they stay in your library).": "Επαναφέρει κάθε χρώμα, γραμματοσειρά και επιλογή διάταξης όπως ξεκινά ένα νέο ιστολόγιο και ξεχνά τις επιλεγμένες εικόνες και γραμματοσειρές (μένουν στη συλλογή σας).", diff --git a/internal/web/static/blog.css b/internal/web/static/blog.css index 10568fa..155269d 100644 --- a/internal/web/static/blog.css +++ b/internal/web/static/blog.css @@ -37,6 +37,12 @@ img { max-width: 100%; height: auto; } .outro { padding-top: 1em; margin-top: 1.5em; border-top: 1px solid rgba(0,0,0,0.1); } .post { margin-bottom: 2.5em; } .post-title { margin: 0 0 0.1em; font-size: 1.5em; line-height: 1.25; } +/* title rule (body.titles-*): a line under page and post titles, coloured by the + theme CSS. overflow:hidden ends it at a floated thumbnail instead of under it. */ +.titles-line .page-title, .titles-line .post-title, .titles-dots .page-title, .titles-dots .post-title, .titles-stripes .page-title, .titles-stripes .post-title { overflow: hidden; padding-bottom: 0.25em; } +.titles-line .page-title, .titles-line .post-title { border-bottom-width: 1px; border-bottom-style: solid; } /* the colour is the theme's, so no shorthand */ +.titles-dots .page-title, .titles-dots .post-title { border-bottom-width: 3px; border-bottom-style: dotted; } +.titles-stripes .page-title::after, .titles-stripes .post-title::after { content: ""; display: block; height: 0.4em; margin-top: 0.35em; background: repeating-linear-gradient(90deg, currentColor, currentColor 2px, transparent 2px, transparent 10px); } .post-title a { text-decoration: none; } .post-title a:hover { text-decoration: underline; } .post-date { margin: 0 0 0.8em; font-size: 0.85em; opacity: 0.7; } diff --git a/internal/web/templates.go b/internal/web/templates.go index c2f9847..ea39a6d 100644 --- a/internal/web/templates.go +++ b/internal/web/templates.go @@ -116,6 +116,13 @@ var funcs = template.FuncMap{ "filemd": fileMarkdown, "add": func(a, b int) int { return a + b }, "sub": func(a, b int) int { return a - b }, + // tagname is a tag as the theme lists it: with a # in front when TagHash is on + "tagname": func(t Theme, name string) string { + if t.TagHash { + return "#" + name + } + return name + }, "deref": func(p *string) string { if p == nil { return "" diff --git a/internal/web/templates/blog/post.html b/internal/web/templates/blog/post.html index 10d4c3a..d16e842 100644 --- a/internal/web/templates/blog/post.html +++ b/internal/web/templates/blog/post.html @@ -3,7 +3,7 @@

{{.Data.post.Title}}

- {{template "posttags" .Data.post.Tags}} + {{template "posttags" (dict "tags" .Data.post.Tags "hash" .Data.theme.TagHash)}} {{$img := .Data.post.Image}}{{$place := .Data.theme.PostImage}} {{if and $img (eq $place "top")}}

{{end}}
{{html .Data.post.BodyHTML}}
diff --git a/internal/web/templates/blog/tag.html b/internal/web/templates/blog/tag.html index fd3aa13..acb530b 100644 --- a/internal/web/templates/blog/tag.html +++ b/internal/web/templates/blog/tag.html @@ -1,5 +1,5 @@ -{{define "title"}}{{tf "Tagged “%s”" .Data.tag.Name}} · {{.Blog.Title}}{{end}} +{{define "title"}}{{tf "Tagged “%s”" (tagname .Data.theme .Data.tag.Name)}} · {{.Blog.Title}}{{end}} {{define "content"}} -

{{tf "Tagged “%s”" .Data.tag.Name}}

+

{{tf "Tagged “%s”" (tagname .Data.theme .Data.tag.Name)}}

{{template "postlist" .}} {{end}} diff --git a/internal/web/templates/dashboard/design.html b/internal/web/templates/dashboard/design.html index 5c79dbb..798a0d0 100644 --- a/internal/web/templates/dashboard/design.html +++ b/internal/web/templates/dashboard/design.html @@ -185,7 +185,14 @@

{{t "Posts"}}

+
+