From ef722789ac185485689f11bc5ee544d03f5e12e3 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Thu, 21 Jul 2022 19:09:50 +0200 Subject: [PATCH] Add setting to hide old content warning (fix #12) --- config.go | 48 +++++++++-------- go.mod | 7 +-- go.sum | 17 +++--- httpRouters.go | 1 + settings.go | 24 +++++++-- settingsDb.go | 20 ++++++- strings/de.yaml | 3 ++ strings/default.yaml | 3 ++ ui.go | 102 ++++++------------------------------ uiComponents.go | 121 ++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 221 insertions(+), 125 deletions(-) diff --git a/config.go b/config.go index 4304b66..4f719ac 100644 --- a/config.go +++ b/config.go @@ -75,27 +75,28 @@ type configCache struct { } type configBlog struct { - Path string `mapstructure:"path"` - Lang string `mapstructure:"lang"` - Title string `mapstructure:"title"` - Description string `mapstructure:"description"` - Pagination int `mapstructure:"pagination"` - DefaultSection string `mapstructure:"defaultsection"` - Sections map[string]*configSection `mapstructure:"sections"` - Taxonomies []*configTaxonomy `mapstructure:"taxonomies"` - Menus map[string]*configMenu `mapstructure:"menus"` - Photos *configPhotos `mapstructure:"photos"` - Search *configSearch `mapstructure:"search"` - BlogStats *configBlogStats `mapstructure:"blogStats"` - Blogroll *configBlogroll `mapstructure:"blogroll"` - Telegram *configTelegram `mapstructure:"telegram"` - PostAsHome bool `mapstructure:"postAsHome"` - RandomPost *configRandomPost `mapstructure:"randomPost"` - OnThisDay *configOnThisDay `mapstructure:"onThisDay"` - Comments *configComments `mapstructure:"comments"` - Map *configGeoMap `mapstructure:"map"` - Contact *configContact `mapstructure:"contact"` - Announcement *configAnnouncement `mapstructure:"announcement"` + Path string `mapstructure:"path"` + Lang string `mapstructure:"lang"` + Title string `mapstructure:"title"` + Description string `mapstructure:"description"` + Pagination int `mapstructure:"pagination"` + DefaultSection string `mapstructure:"defaultsection"` + Sections map[string]*configSection `mapstructure:"sections"` + Taxonomies []*configTaxonomy `mapstructure:"taxonomies"` + Menus map[string]*configMenu `mapstructure:"menus"` + Photos *configPhotos `mapstructure:"photos"` + Search *configSearch `mapstructure:"search"` + BlogStats *configBlogStats `mapstructure:"blogStats"` + Blogroll *configBlogroll `mapstructure:"blogroll"` + Telegram *configTelegram `mapstructure:"telegram"` + PostAsHome bool `mapstructure:"postAsHome"` + RandomPost *configRandomPost `mapstructure:"randomPost"` + OnThisDay *configOnThisDay `mapstructure:"onThisDay"` + Comments *configComments `mapstructure:"comments"` + Map *configGeoMap `mapstructure:"map"` + Contact *configContact `mapstructure:"contact"` + Announcement *configAnnouncement `mapstructure:"announcement"` + hideOldContentWarning bool } type configSection struct { @@ -452,6 +453,11 @@ func (a *goBlog) initConfig(logging bool) error { if br := bc.Blogroll; br != nil && br.Enabled && br.Opml == "" { br.Enabled = false } + // Load other settings from database + bc.hideOldContentWarning, err = a.getBooleanSettingValue(settingNameWithBlog(blog, hideOldContentWarningSetting), false) + if err != nil { + return err + } } // Log success a.cfg.initialized = true diff --git a/go.mod b/go.mod index 15441a9..14879ef 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/jlelse/feeds v1.2.1-0.20210704161900-189f94254ad4 github.com/justinas/alice v1.2.0 github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9 - github.com/klauspost/compress v1.15.8 + github.com/klauspost/compress v1.15.9 github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible github.com/lopezator/migrator v0.3.1 github.com/mattn/go-sqlite3 v1.14.14 @@ -63,7 +63,7 @@ require ( golang.org/x/text v0.3.7 gopkg.in/yaml.v3 v3.0.1 nhooyr.io/websocket v1.8.7 - tailscale.com v1.26.2 + tailscale.com v1.28.0 // main willnorris.com/go/microformats v1.1.2-0.20210827044458-ff2a6ae41971 ) @@ -147,7 +147,8 @@ require ( golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect + golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 // indirect diff --git a/go.sum b/go.sum index b44b29c..25139f9 100644 --- a/go.sum +++ b/go.sum @@ -329,8 +329,8 @@ github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9 h1:+9REu9CK9D1AQ github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9/go.mod h1:OvY5ZBrAC9kOvM2PZs9Lw0BH+5K7tjrT6T7SFhn27OA= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.15.8 h1:JahtItbkWjf2jzm/T+qgMxkP9EMHsqEUA6vCMGmXvhA= -github.com/klauspost/compress v1.15.8/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -570,7 +570,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -698,8 +698,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= @@ -767,12 +767,11 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.11-0.20220413170336-afc6aad76eb1 h1:Z3vE1sGlC7qiyFJkkDcZms8Y3+yV8+W7HmDSmuf71tM= +golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20210905140043-2ef39d47540c/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= @@ -909,8 +908,8 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78 h1:SqYE5+A2qvRhErbsXFfUEUmpWEKxxRSMgGLkvRAFOV4= -tailscale.com v1.26.2 h1:EBR0DXblI2Rx3mPe/YU29oZbQLnC8BtJYUTufmEygUY= -tailscale.com v1.26.2/go.mod h1:KM47Ct0eNTFJqoazXV5XRdMnnWtD2HHDciY9RwyqweE= +tailscale.com v1.28.0 h1:eW5bJMqw6eu7YUjBcgJY94uIcm5Zv+xpyTxxa7ztZOM= +tailscale.com v1.28.0/go.mod h1:T9uKhlkxVPdSu1Qvp882evcS/hQ1+TAyZ7sJ/VACGRI= willnorris.com/go/microformats v1.1.2-0.20210827044458-ff2a6ae41971 h1:b4juh5znIpBA1KnzHMP0UB4Cs+3/0b0XfchkWE81FXw= willnorris.com/go/microformats v1.1.2-0.20210827044458-ff2a6ae41971/go.mod h1:kvVnWrkkEscVAIITCEoiTX66Hcyg59C7q0E49mb9TJ0= willnorris.com/go/webmention v0.0.0-20220108183051-4a23794272f0 h1:V5+O+YZHchEwu6ZmPcqT1dQ+mHgE356Q+w9SVOQ+QZg= diff --git a/httpRouters.go b/httpRouters.go index 1badaa9..43ef2d5 100644 --- a/httpRouters.go +++ b/httpRouters.go @@ -455,5 +455,6 @@ func (a *goBlog) blogSettingsRouter(_ *configBlog) func(r chi.Router) { r.Post(settingsCreateSectionPath, a.settingsCreateSection) r.Post(settingsUpdateSectionPath, a.settingsUpdateSection) r.Post(settingsUpdateDefaultSectionPath, a.settingsUpdateDefaultSection) + r.Post(settingsHideOldContentWarningPath, a.settingsHideOldContentWarning) } } diff --git a/settings.go b/settings.go index 6d79119..ab3e979 100644 --- a/settings.go +++ b/settings.go @@ -17,9 +17,10 @@ func (a *goBlog) serveSettings(w http.ResponseWriter, r *http.Request) { a.render(w, r, a.renderSettings, &renderData{ Data: &settingsRenderData{ - blog: blog, - sections: sections, - defaultSection: bc.DefaultSection, + blog: blog, + sections: sections, + defaultSection: bc.DefaultSection, + hideOldContentWarning: bc.hideOldContentWarning, }, }) } @@ -149,3 +150,20 @@ func (a *goBlog) settingsUpdateDefaultSection(w http.ResponseWriter, r *http.Req bc.DefaultSection = newDefaultSection http.Redirect(w, r, bc.getRelativePath(settingsPath), http.StatusFound) } + +const settingsHideOldContentWarningPath = "/oldcontentwarning" + +func (a *goBlog) settingsHideOldContentWarning(w http.ResponseWriter, r *http.Request) { + blog, bc := a.getBlog(r) + // Read values + hideOldContentWarning := r.FormValue(hideOldContentWarningSetting) == "on" + // Update + err := a.saveBooleanSettingValue(settingNameWithBlog(blog, hideOldContentWarningSetting), hideOldContentWarning) + if err != nil { + a.serveError(w, r, "Failed to update default section in database", http.StatusInternalServerError) + return + } + bc.hideOldContentWarning = hideOldContentWarning + a.cache.purge() + http.Redirect(w, r, bc.getRelativePath(settingsPath), http.StatusFound) +} diff --git a/settingsDb.go b/settingsDb.go index 9260e18..0a35822 100644 --- a/settingsDb.go +++ b/settingsDb.go @@ -4,6 +4,8 @@ import ( "database/sql" "errors" "fmt" + + "github.com/samber/lo" ) func settingNameWithBlog(blog, name string) string { @@ -11,7 +13,8 @@ func settingNameWithBlog(blog, name string) string { } const ( - defaultSectionSetting = "defaultsection" + defaultSectionSetting = "defaultsection" + hideOldContentWarningSetting = "hideoldcontentwarning" ) func (a *goBlog) getSettingValue(name string) (string, error) { @@ -30,6 +33,17 @@ func (a *goBlog) getSettingValue(name string) (string, error) { return value, nil } +func (a *goBlog) getBooleanSettingValue(name string, defaultValue bool) (bool, error) { + stringValue, err := a.getSettingValue(name) + if err != nil { + return defaultValue, err + } + if stringValue == "" { + return defaultValue, nil + } + return stringValue == "1", nil +} + func (a *goBlog) saveSettingValue(name, value string) error { _, err := a.db.exec( "insert into settings (name, value) values (@name, @value) on conflict (name) do update set value = @value2", @@ -40,6 +54,10 @@ func (a *goBlog) saveSettingValue(name, value string) error { return err } +func (a *goBlog) saveBooleanSettingValue(name string, value bool) error { + return a.saveSettingValue(name, lo.If(value, "1").Else("0")) +} + func (a *goBlog) loadSections() error { for blog, bc := range a.cfg.Blogs { sections, err := a.getSections(blog) diff --git a/strings/de.yaml b/strings/de.yaml index 182350b..3119fb3 100644 --- a/strings/de.yaml +++ b/strings/de.yaml @@ -22,9 +22,12 @@ editor: "Editor" editorpostdesc: "💡 Leere Parameter werden automatisch entfernt. Mehr mögliche Parameter: %s. Mögliche Zustände für `%s`: %s." emailopt: "E-Mail (optional)" fileuses: "Datei-Verwendungen" +general: "Allgemein" gentts: "Text-To-Speech-Audio erzeugen" gpxhelper: "GPX-Helfer" gpxhelperdesc: "💡 GPX minimieren und YAML für das Frontmatter generieren." +hideoldcontentwarningdesc: "Die Warnung für alte Posts (älter als 1 Jahr) ausblenden" +hideoldcontentwarningtitle: "Warnung vor altem Inhalt" interactions: "Interaktionen & Kommentare" interactionslabel: "Hast du eine Antwort hierzu veröffentlicht? Füge hier die URL ein." kilometers: "Kilometer" diff --git a/strings/default.yaml b/strings/default.yaml index 68689d1..770c9f4 100644 --- a/strings/default.yaml +++ b/strings/default.yaml @@ -26,9 +26,12 @@ editorpostdesc: "💡 Empty parameters are removed automatically. More possible emailopt: "Email (optional)" feed: "Feed" fileuses: "file uses" +general: "General" gentts: "Generate Text-To-Speech audio" gpxhelper: "GPX helper" gpxhelperdesc: "💡 Minify GPX and generate YAML for the frontmatter." +hideoldcontentwarningdesc: "Hide the warning for old posts (older than 1 year)" +hideoldcontentwarningtitle: "Old content warning" indieauth: "IndieAuth" interactions: "Interactions & Comments" interactionslabel: "Have you published a response to this? Paste the URL here." diff --git a/ui.go b/ui.go index edf1644..9095f4d 100644 --- a/ui.go +++ b/ui.go @@ -1486,9 +1486,10 @@ func (a *goBlog) renderEditor(hb *htmlBuilder, rd *renderData) { } type settingsRenderData struct { - blog string - sections []*configSection - defaultSection string + blog string + sections []*configSection + defaultSection string + hideOldContentWarning bool } func (a *goBlog) renderSettings(hb *htmlBuilder, rd *renderData) { @@ -1509,95 +1510,22 @@ func (a *goBlog) renderSettings(hb *htmlBuilder, rd *renderData) { hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "settings")) hb.writeElementClose("h1") - // Post sections + // General hb.writeElementOpen("h2") - hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "postsections")) + hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "general")) hb.writeElementClose("h2") - // Update default section - hb.writeElementOpen("h3") - hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "default")) - hb.writeElementClose("h3") - - hb.writeElementOpen("form", "class", "fw p", "method", "post") - hb.writeElementOpen("select", "name", "defaultsection") - for _, section := range srd.sections { - hb.writeElementOpen("option", "value", section.Name, lo.If(section.Name == srd.defaultSection, "selected").Else(""), "") - hb.writeEscaped(section.Name) - hb.writeElementClose("option") - } - hb.writeElementClose("select") - hb.writeElementOpen( - "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"), - "formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateDefaultSectionPath), + // Hide old content warning + a.renderCollapsibleBooleanSetting(hb, rd, + rd.Blog.getRelativePath(settingsPath+settingsHideOldContentWarningPath), + a.ts.GetTemplateStringVariant(rd.Blog.Lang, "hideoldcontentwarningtitle"), + a.ts.GetTemplateStringVariant(rd.Blog.Lang, "hideoldcontentwarningdesc"), + hideOldContentWarningSetting, + srd.hideOldContentWarning, ) - hb.writeElementClose("form") - for _, section := range srd.sections { - hb.writeElementOpen("details") - - hb.writeElementOpen("summary") - hb.writeElementOpen("h3") - hb.writeEscaped(section.Name) - hb.writeElementClose("h3") - hb.writeElementClose("summary") - - hb.writeElementOpen("form", "class", "fw p", "method", "post") - - hb.writeElementOpen("input", "type", "hidden", "name", "sectionname", "value", section.Name) - - // Title - hb.writeElementOpen("input", "type", "text", "name", "sectiontitle", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiontitle"), "required", "", "value", section.Title) - // Description - hb.writeElementOpen( - "textarea", - "name", "sectiondescription", - "class", "monospace", - "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiondescription"), - ) - hb.writeEscaped(section.Description) - hb.writeElementClose("textarea") - // Path template - hb.writeElementOpen("input", "type", "text", "name", "sectionpathtemplate", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionpathtemplate"), "value", section.PathTemplate) - // Show full - hb.writeElementOpen("input", "type", "checkbox", "name", "sectionshowfull", "id", "showfull-"+section.Name, lo.If(section.ShowFull, "checked").Else(""), "") - hb.writeElementOpen("label", "for", "showfull-"+section.Name) - hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionshowfull")) - hb.writeElementClose("label") - - // Actions - hb.writeElementOpen("div", "class", "p") - // Update - hb.writeElementOpen( - "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"), - "formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateSectionPath), - ) - // Delete - hb.writeElementOpen( - "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "delete"), - "formaction", rd.Blog.getRelativePath(settingsPath+settingsDeleteSectionPath), - "class", "confirm", "data-confirmmessage", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "confirmdelete"), - ) - hb.writeElementClose("div") - - hb.writeElementClose("form") - hb.writeElementClose("details") - } - - // Create new section - hb.writeElementOpen("form", "class", "fw p", "method", "post") - // Name - hb.writeElementOpen("input", "type", "text", "name", "sectionname", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionname"), "required", "") - // Title - hb.writeElementOpen("input", "type", "text", "name", "sectiontitle", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiontitle"), "required", "") - // Create button - hb.writeElementOpen("div") - hb.writeElementOpen( - "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "create"), - "formaction", rd.Blog.getRelativePath(settingsPath+settingsCreateSectionPath), - ) - hb.writeElementClose("div") - hb.writeElementClose("form") + // Post sections + a.renderPostSectionSettings(hb, rd, srd) // Scripts hb.writeElementOpen("script", "src", a.assetFileName("js/formconfirm.js"), "defer", "") diff --git a/uiComponents.go b/uiComponents.go index 4277eac..3443b94 100644 --- a/uiComponents.go +++ b/uiComponents.go @@ -5,6 +5,7 @@ import ( "strings" "time" + "github.com/samber/lo" "go.goblog.app/app/pkgs/bufferpool" ) @@ -250,7 +251,7 @@ func (a *goBlog) renderPostMeta(hb *htmlBuilder, p *post, b *configBlog, typ str // warning for old posts func (a *goBlog) renderOldContentWarning(hb *htmlBuilder, p *post, b *configBlog) { - if b == nil || p == nil || !p.Old() { + if b == nil || b.hideOldContentWarning || p == nil || !p.Old() { return } hb.writeElementOpen("strong", "class", "p border-top border-bottom") @@ -493,3 +494,121 @@ func (a *goBlog) renderPostVideo(hb *htmlBuilder, p *post) { hb.writeElementOpen("script", "defer", "", "src", a.assetFileName("js/video.js")) hb.writeElementClose("script") } + +func (a *goBlog) renderPostSectionSettings(hb *htmlBuilder, rd *renderData, srd *settingsRenderData) { + hb.writeElementOpen("h2") + hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "postsections")) + hb.writeElementClose("h2") + + // Update default section + hb.writeElementOpen("h3") + hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "default")) + hb.writeElementClose("h3") + + hb.writeElementOpen("form", "class", "fw p", "method", "post") + hb.writeElementOpen("select", "name", "defaultsection") + for _, section := range srd.sections { + hb.writeElementOpen("option", "value", section.Name, lo.If(section.Name == srd.defaultSection, "selected").Else(""), "") + hb.writeEscaped(section.Name) + hb.writeElementClose("option") + } + hb.writeElementClose("select") + hb.writeElementOpen( + "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"), + "formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateDefaultSectionPath), + ) + hb.writeElementClose("form") + + for _, section := range srd.sections { + hb.writeElementOpen("details") + + hb.writeElementOpen("summary") + hb.writeElementOpen("h3") + hb.writeEscaped(section.Name) + hb.writeElementClose("h3") + hb.writeElementClose("summary") + + hb.writeElementOpen("form", "class", "fw p", "method", "post") + + hb.writeElementOpen("input", "type", "hidden", "name", "sectionname", "value", section.Name) + + // Title + hb.writeElementOpen("input", "type", "text", "name", "sectiontitle", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiontitle"), "required", "", "value", section.Title) + // Description + hb.writeElementOpen( + "textarea", + "name", "sectiondescription", + "class", "monospace", + "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiondescription"), + ) + hb.writeEscaped(section.Description) + hb.writeElementClose("textarea") + // Path template + hb.writeElementOpen("input", "type", "text", "name", "sectionpathtemplate", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionpathtemplate"), "value", section.PathTemplate) + // Show full + hb.writeElementOpen("input", "type", "checkbox", "name", "sectionshowfull", "id", "showfull-"+section.Name, lo.If(section.ShowFull, "checked").Else(""), "") + hb.writeElementOpen("label", "for", "showfull-"+section.Name) + hb.writeEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionshowfull")) + hb.writeElementClose("label") + + // Actions + hb.writeElementOpen("div", "class", "p") + // Update + hb.writeElementOpen( + "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"), + "formaction", rd.Blog.getRelativePath(settingsPath+settingsUpdateSectionPath), + ) + // Delete + hb.writeElementOpen( + "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "delete"), + "formaction", rd.Blog.getRelativePath(settingsPath+settingsDeleteSectionPath), + "class", "confirm", "data-confirmmessage", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "confirmdelete"), + ) + hb.writeElementClose("div") + + hb.writeElementClose("form") + hb.writeElementClose("details") + } + + // Create new section + hb.writeElementOpen("form", "class", "fw p", "method", "post") + // Name + hb.writeElementOpen("input", "type", "text", "name", "sectionname", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectionname"), "required", "") + // Title + hb.writeElementOpen("input", "type", "text", "name", "sectiontitle", "placeholder", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "sectiontitle"), "required", "") + // Create button + hb.writeElementOpen("div") + hb.writeElementOpen( + "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "create"), + "formaction", rd.Blog.getRelativePath(settingsPath+settingsCreateSectionPath), + ) + hb.writeElementClose("div") + hb.writeElementClose("form") +} + +func (a *goBlog) renderCollapsibleBooleanSetting(hb *htmlBuilder, rd *renderData, path, title, description, name string, value bool) { + hb.writeElementOpen("details") + + hb.writeElementOpen("summary") + hb.writeElementOpen("h3") + hb.writeEscaped(title) + hb.writeElementClose("h3") + hb.writeElementClose("summary") + + hb.writeElementOpen("form", "class", "fw p", "method", "post") + + hb.writeElementOpen("input", "type", "checkbox", "name", name, "id", "cb-"+name, lo.If(value, "checked").Else(""), "") + hb.writeElementOpen("label", "for", "cb-"+name) + hb.writeEscaped(description) + hb.writeElementClose("label") + + hb.writeElementOpen("div", "class", "p") + hb.writeElementOpen( + "input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"), "formaction", path, + ) + hb.writeElementClose("div") + + hb.writeElementClose("form") + + hb.writeElementClose("details") +}