diff options
| author | grm <grm@eyesin.space> | 2026-09-17 21:47:37 +0300 |
|---|---|---|
| committer | grm <grm@eyesin.space> | 2026-09-17 21:47:37 +0300 |
| commit | eaa6dc04d05ad24dea5a7b211928cddb6db5aa73 (patch) | |
| tree | e5f54fc6543fb968265ed6a04bad9b45c7c070a8 | |
| parent | 2a347ced1b4ea8c24440f646df35207c3a3597ac (diff) | |
| download | blogspace-eaa6dc04d05ad24dea5a7b211928cddb6db5aa73.tar.gz blogspace-eaa6dc04d05ad24dea5a7b211928cddb6db5aa73.tar.bz2 blogspace-eaa6dc04d05ad24dea5a7b211928cddb6db5aa73.zip | |
Add a colons kind to the rule under titles, and stop its label wrapping
The design form's hint on "Rule under titles" wrapped to three lines and
pushed the select below its neighbours; it is a note under the row now.
"Colons" is a row of ":" (a long string in an ::after, clipped to the
title's width), the look of the reference site's dotted borders in text.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
| -rw-r--r-- | AGENTS.md | 4 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | internal/i18n/el.go | 3 | ||||
| -rw-r--r-- | internal/web/static/blog.css | 4 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/design.html | 4 | ||||
| -rw-r--r-- | internal/web/theme.go | 4 | ||||
| -rw-r--r-- | internal/web/web_test.go | 3 |
7 files changed, 16 insertions, 8 deletions
@@ -184,8 +184,8 @@ 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). `TitleRule` (`none` | `line` | `dots` | `stripes`) is the same - rule under page and post titles (`.page-title`, `.post-title`): a body + them bold). `TitleRule` (`none` | `line` | `dots` | `colons` | `stripes`) is the header + rule's kinds, plus a row of ":" (an `::after` with a long clipped string), under page and post titles (`.page-title`, `.post-title`): a body class from `Theme.TitleRuleClass` (`titles-<kind>`) 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 @@ -25,7 +25,7 @@ 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 (dates, summaries, a rule under titles — line, dots or stripes — and + content (dates, summaries, a rule under titles — line, dots, colons 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, diff --git a/internal/i18n/el.go b/internal/i18n/el.go index a8a1bde..4375419 100644 --- a/internal/i18n/el.go +++ b/internal/i18n/el.go @@ -388,7 +388,8 @@ var el = map[string]string{ "Show the date on posts": "Εμφάνιση ημερομηνίας στις δημοσιεύσεις", "Show tags with a # in front": "Εμφάνιση των ετικετών με # μπροστά", "Rule under titles": "Γραμμή κάτω από τους τίτλους", - "page and post titles, in the link colour": "τίτλοι σελίδων και δημοσιεύσεων, στο χρώμα των συνδέσμων", + "The rule goes under page and post titles, in the link colour.": "Η γραμμή μπαίνει κάτω από τους τίτλους σελίδων και δημοσιεύσεων, στο χρώμα των συνδέσμων.", + "Colons": "Άνω-κάτω τελείες", "Date format": "Μορφή ημερομηνίας", "Logo & site icon": "Λογότυπο & εικονίδιο ιστολογίου", "Logo size": "Μέγεθος λογότυπου", diff --git a/internal/web/static/blog.css b/internal/web/static/blog.css index 155269d..30b1612 100644 --- a/internal/web/static/blog.css +++ b/internal/web/static/blog.css @@ -39,10 +39,12 @@ img { max-width: 100%; height: auto; } .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, .titles-dots .page-title, .titles-dots .post-title, .titles-colons .page-title, .titles-colons .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); } +/* colons: a row of ":" clipped to the title's width (the string is long enough for any screen) */ +.titles-colons .page-title::after, .titles-colons .post-title::after { content: "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"; display: block; overflow: hidden; white-space: nowrap; margin-top: 0.15em; font-size: 0.7em; font-weight: normal; line-height: 1; letter-spacing: 0.04em; } .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/dashboard/design.html b/internal/web/templates/dashboard/design.html index 798a0d0..0ce7c6d 100644 --- a/internal/web/templates/dashboard/design.html +++ b/internal/web/templates/dashboard/design.html @@ -187,10 +187,11 @@ <label class="check"><input type="checkbox" name="show_dates"{{if $t.ShowDates}} checked{{end}}> {{t "Show the date on posts"}}</label> <label class="check"><input type="checkbox" name="tag_hash"{{if $t.TagHash}} checked{{end}}> {{t "Show tags with a # in front"}} <span class="muted">(#garden)</span></label> <div class="row"> - <label>{{t "Rule under titles"}} <span class="muted">({{t "page and post titles, in the link colour"}})</span><br><select name="title_rule"> + <label>{{t "Rule under titles"}}<br><select name="title_rule"> <option value="none"{{if eq $t.TitleRule "none"}} selected{{end}}>{{t "None"}}</option> <option value="line"{{if eq $t.TitleRule "line"}} selected{{end}}>{{t "Line"}}</option> <option value="dots"{{if eq $t.TitleRule "dots"}} selected{{end}}>{{t "Dots"}}</option> + <option value="colons"{{if eq $t.TitleRule "colons"}} selected{{end}}>{{t "Colons"}} (::::)</option> <option value="stripes"{{if eq $t.TitleRule "stripes"}} selected{{end}}>{{t "Stripes"}}</option> </select></label> <label>{{t "Date format"}}<br><select name="date_format"> @@ -202,6 +203,7 @@ {{range .Data.perPage}}<option value="{{.}}"{{if eq . $t.PostsPerPage}} selected{{end}}>{{.}}</option>{{end}} </select></label> </div> + <p class="muted small">{{t "The rule goes under page and post titles, in the link colour."}}</p> <div class="row"> <label>{{t "On listings show"}}<br><select name="list_style"> <option value="full"{{if eq $t.ListStyle "full"}} selected{{end}}>{{t "The whole post"}}</option> diff --git a/internal/web/theme.go b/internal/web/theme.go index 0dc8eff..8d9bf98 100644 --- a/internal/web/theme.go +++ b/internal/web/theme.go @@ -53,7 +53,7 @@ type Theme struct { PostsPerPage int `json:"posts_per_page"` // on listings and tag pages; one of postsPerPageChoices ListStyle string `json:"list_style"` // full | summary (see summary.go) PostImage string `json:"post_image"` // where the post page shows the featured image: top | bottom | list (listings only) - TitleRule string `json:"title_rule"` // none | line | dots | stripes, drawn under page and post titles in the link colour + TitleRule string `json:"title_rule"` // none | line | dots | colons | stripes, drawn under page and post titles in the link colour TagHash bool `json:"tag_hash"` // tags are listed as #name FooterBg string `json:"footer_bg"` @@ -190,7 +190,7 @@ func (t *Theme) normalize() { t.PostsPerPage = pickInt(t.PostsPerPage, postsPerPageChoices...) t.ListStyle = pick(t.ListStyle, "full", "summary") t.PostImage = pick(t.PostImage, "top", "bottom", "list") - t.TitleRule = pick(t.TitleRule, "none", "line", "dots", "stripes") + t.TitleRule = pick(t.TitleRule, "none", "line", "dots", "colons", "stripes") t.FooterBg = color(t.FooterBg, d.FooterBg) t.FooterColor = color(t.FooterColor, d.FooterColor) t.FooterAlign = pick(t.FooterAlign, "center", "left") diff --git a/internal/web/web_test.go b/internal/web/web_test.go index 205e42f..c0a68c5 100644 --- a/internal/web/web_test.go +++ b/internal/web/web_test.go @@ -144,6 +144,9 @@ func TestTitleRuleAndTagHash(t *testing.T) { if th.TitleRuleClass() != "titles-dots" || !th.TagHash || !strings.Contains(th.CSS(), ".page-title, .post-title { border-color:#b03a48; }") { t.Errorf("from form: %+v\n%s", th, th.CSS()) } + if th = ThemeFromForm(th, url.Values{"title_rule": {"colons"}}); th.TitleRuleClass() != "titles-colons" { + t.Errorf("colons: %+v", th) + } th = ThemeFromForm(th, url.Values{"title_rule": {"neon"}}) if th.TitleRuleClass() != "" || th.TagHash { t.Errorf("junk rule falls back, unticked box is off: %+v", th) |
