aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/theme.go
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-17 21:37:46 +0300
committergrm <grm@eyesin.space>2026-09-17 21:37:46 +0300
commitb233445a73168994087356d45b5dc7dd6a07aa8e (patch)
treed08b554607c5ab2e707dd607ab5bfa88c62e5274 /internal/web/theme.go
parente96bbec551c0388e972894b349413fa6ef607352 (diff)
downloadblogspace-b233445a73168994087356d45b5dc7dd6a07aa8e.tar.gz
blogspace-b233445a73168994087356d45b5dc7dd6a07aa8e.tar.bz2
blogspace-b233445a73168994087356d45b5dc7dd6a07aa8e.zip
Add a rule under page and post titles, and tags shown with a # in front
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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/web/theme.go')
-rw-r--r--internal/web/theme.go19
1 files changed, 18 insertions, 1 deletions
diff --git a/internal/web/theme.go b/internal/web/theme.go
index 26181c2..0dc8eff 100644
--- a/internal/web/theme.go
+++ b/internal/web/theme.go
@@ -53,6 +53,8 @@ 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
+ TagHash bool `json:"tag_hash"` // tags are listed as #name
FooterBg string `json:"footer_bg"`
FooterColor string `json:"footer_color"`
@@ -99,7 +101,7 @@ func DefaultTheme() Theme {
Font: "sans", HeadingFont: "same", FontSize: "normal",
HeaderImageHeight: "medium", HeaderAlign: "left", HeaderBg: "#2f3a4a", HeaderText: "#ffffff", TitleSize: "normal", HeaderRule: "none",
NavAlign: "left", NavStyle: "normal", NavBg: "#ffffff", NavText: "#222222",
- ShowDates: true, DateFormat: "long", PostsPerPage: postsPerPageChoices[0], ListStyle: "full", PostImage: "top",
+ ShowDates: true, DateFormat: "long", PostsPerPage: postsPerPageChoices[0], ListStyle: "full", PostImage: "top", TitleRule: "none",
FooterBg: "#2f3a4a", FooterColor: "#d0d5dc", FooterAlign: "center",
LogoSize: "medium",
HeaderOn: true, LeftOn: true, RightOn: true, FooterOn: true, LeftWidth: 25, RightWidth: 25,
@@ -188,6 +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.FooterBg = color(t.FooterBg, d.FooterBg)
t.FooterColor = color(t.FooterColor, d.FooterColor)
t.FooterAlign = pick(t.FooterAlign, "center", "left")
@@ -253,6 +256,8 @@ func ThemeFromForm(cur Theme, f url.Values) Theme {
t.PostsPerPage = num("posts_per_page")
t.ListStyle = get("list_style")
t.PostImage = get("post_image")
+ t.TitleRule = get("title_rule")
+ t.TagHash = on("tag_hash")
t.FooterBg = get("footer_bg")
t.FooterColor = get("footer_color")
t.FooterAlign = get("footer_align")
@@ -455,6 +460,15 @@ func (t Theme) RuleClass() string {
return "ruled rule-" + t.HeaderRule
}
+// TitleRuleClass is the body class blog.css draws the rule under page and
+// post titles from; the theme CSS only colours it.
+func (t Theme) TitleRuleClass() string {
+ if t.TitleRule == "none" {
+ return ""
+ }
+ return "titles-" + t.TitleRule
+}
+
func (t Theme) HeaderImageMaxHeight() string {
switch t.HeaderImageHeight {
case "short":
@@ -497,6 +511,9 @@ a:hover {{"{"}}{{if .LinkHover}} color:{{.LinkHover}};{{end}}{{if eq .LinkUnderl
.content, .mod { background:{{.ContentBg}};{{if eq .ContentStyle "flat"}} border-radius:0; box-shadow:none;{{end}} }
.content {{"{"}}{{with .PaddingDesktop}} padding:{{.}};{{end}} }
.notice-gizmo { border-color:{{.LinkColor}}; }
+{{- if ne .TitleRule "none"}}
+.page-title, .post-title { border-color:{{.LinkColor}}; } .page-title::after, .post-title::after { color:{{.LinkColor}}; }
+{{- end}}
.logo { max-height:{{.LogoMaxHeight}}; }
@media (min-width: 701px) {
.col-left { width:{{.LeftWidth}}%; } .col-right { width:{{.RightWidth}}%; }