From 2178b2e2231895c8dd05c42d923155d2c6ca4688 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Sun, 17 Jul 2022 08:36:10 +0200 Subject: [PATCH] Allow to change default section via ui --- Dockerfile | 2 +- config.go | 54 +++++++++++++++++++++++++++++++------------- go.mod | 2 +- go.sum | 4 ++-- httpRouters.go | 1 + settings.go | 30 ++++++++++++++++++++---- settingsDb.go | 35 +++++++++++++++------------- strings/de.yaml | 1 + strings/default.yaml | 1 + ui.go | 24 ++++++++++++++++++-- 10 files changed, 112 insertions(+), 42 deletions(-) diff --git a/Dockerfile b/Dockerfile index c457fbb..0f108e0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,7 @@ RUN go build -ldflags '-w -s' -o GoBlog FROM build as test -RUN go test -timeout 60s -cover ./... +RUN go test -timeout 300s -failfast -cover ./... FROM alpine:3.16 as base diff --git a/config.go b/config.go index 6135182..4304b66 100644 --- a/config.go +++ b/config.go @@ -384,12 +384,8 @@ func (a *goBlog) initConfig(logging bool) error { } // Check if default blog is set if a.cfg.DefaultBlog == "" { - if len(a.cfg.Blogs) == 1 { - // Set default blog to the only blog that is configured - a.cfg.DefaultBlog = lo.Keys(a.cfg.Blogs)[0] - } else { - return errors.New("no default blog configured") - } + // Set default blog to the only blog that is configured + a.cfg.DefaultBlog = lo.Keys(a.cfg.Blogs)[0] } // Check if default blog exists if a.cfg.Blogs[a.cfg.DefaultBlog] == nil { @@ -423,13 +419,37 @@ func (a *goBlog) initConfig(logging bool) error { return err } // Check config for each blog - for _, blog := range a.cfg.Blogs { + for blog, bc := range a.cfg.Blogs { + // Check sections and add section if none exists + if len(bc.Sections) == 0 { + bc.Sections = createDefaultSections() + if err = a.saveAllSections(); err != nil { + return err + } + } + // Check default section + if defaultSection, err := a.getSettingValue(settingNameWithBlog(blog, defaultSectionSetting)); err != nil { + // Failed to read value + return err + } else if defaultSection == "" { + // No value defined in database + if _, ok := bc.Sections[bc.DefaultSection]; !ok { + bc.DefaultSection = lo.Keys(bc.Sections)[0] + } + // Save to database + if err = a.saveSettingValue(settingNameWithBlog(blog, defaultSectionSetting), bc.DefaultSection); err != nil { + return err + } + } else { + // Set value from database + bc.DefaultSection = defaultSection + } // Check if language is set - if blog.Lang == "" { - blog.Lang = "en" + if bc.Lang == "" { + bc.Lang = "en" } // Blogroll - if br := blog.Blogroll; br != nil && br.Enabled && br.Opml == "" { + if br := bc.Blogroll; br != nil && br.Enabled && br.Opml == "" { br.Enabled = false } } @@ -484,18 +504,20 @@ func createDefaultBlog() *configBlog { Lang: "en", Title: "My Blog", Description: "Welcome to my blog.", - Sections: map[string]*configSection{ - "posts": { - Title: "Posts", - }, - }, Taxonomies: []*configTaxonomy{ { Name: "tags", Title: "Tags", }, }, - DefaultSection: "posts", + } +} + +func createDefaultSections() map[string]*configSection { + return map[string]*configSection{ + "posts": { + Title: "Posts", + }, } } diff --git a/go.mod b/go.mod index a218a27..15441a9 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b github.com/carlmjohnson/requests v0.22.3 github.com/cretz/bine v0.2.0 - github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f + github.com/dchest/captcha v1.0.0 github.com/dgraph-io/ristretto v0.1.0 github.com/disintegration/imaging v1.6.2 github.com/dmulholl/mp3lib v1.0.0 diff --git a/go.sum b/go.sum index 94cc5ae..b44b29c 100644 --- a/go.sum +++ b/go.sum @@ -120,8 +120,8 @@ github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbe github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M= -github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY= +github.com/dchest/captcha v1.0.0 h1:vw+bm/qMFvTgcjQlYVTuQBJkarm5R0YSsDKhm1HZI2o= +github.com/dchest/captcha v1.0.0/go.mod h1:7zoElIawLp7GUMLcj54K9kbw+jEyvz2K0FDdRRYhvWo= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= diff --git a/httpRouters.go b/httpRouters.go index 3804cfe..1badaa9 100644 --- a/httpRouters.go +++ b/httpRouters.go @@ -454,5 +454,6 @@ func (a *goBlog) blogSettingsRouter(_ *configBlog) func(r chi.Router) { r.Post(settingsDeleteSectionPath, a.settingsDeleteSection) r.Post(settingsCreateSectionPath, a.settingsCreateSection) r.Post(settingsUpdateSectionPath, a.settingsUpdateSection) + r.Post(settingsUpdateDefaultSectionPath, a.settingsUpdateDefaultSection) } } diff --git a/settings.go b/settings.go index 40ce3c2..6d79119 100644 --- a/settings.go +++ b/settings.go @@ -17,8 +17,9 @@ func (a *goBlog) serveSettings(w http.ResponseWriter, r *http.Request) { a.render(w, r, a.renderSettings, &renderData{ Data: &settingsRenderData{ - blog: blog, - sections: sections, + blog: blog, + sections: sections, + defaultSection: bc.DefaultSection, }, }) } @@ -74,7 +75,7 @@ func (a *goBlog) settingsCreateSection(w http.ResponseWriter, r *http.Request) { Name: sectionName, Title: sectionTitle, } - err := a.addSection(blog, section) + err := a.saveSection(blog, section) if err != nil { a.serveError(w, r, "Failed to insert section into database", http.StatusInternalServerError) return @@ -112,7 +113,7 @@ func (a *goBlog) settingsUpdateSection(w http.ResponseWriter, r *http.Request) { PathTemplate: sectionPathTemplate, ShowFull: sectionShowFull, } - err := a.updateSection(blog, sectionName, section) + err := a.saveSection(blog, section) if err != nil { a.serveError(w, r, "Failed to update section in database", http.StatusInternalServerError) return @@ -127,3 +128,24 @@ func (a *goBlog) settingsUpdateSection(w http.ResponseWriter, r *http.Request) { a.cache.purge() http.Redirect(w, r, bc.getRelativePath(settingsPath), http.StatusFound) } + +const settingsUpdateDefaultSectionPath = "/updatedefaultsection" + +func (a *goBlog) settingsUpdateDefaultSection(w http.ResponseWriter, r *http.Request) { + blog, bc := a.getBlog(r) + // Read values + newDefaultSection := r.FormValue("defaultsection") + // Check plausibility + if _, ok := bc.Sections[newDefaultSection]; !ok { + a.serveError(w, r, "Section unknown", http.StatusBadRequest) + return + } + // Update + err := a.saveSettingValue(settingNameWithBlog(blog, defaultSectionSetting), newDefaultSection) + if err != nil { + a.serveError(w, r, "Failed to update default section in database", http.StatusInternalServerError) + return + } + bc.DefaultSection = newDefaultSection + http.Redirect(w, r, bc.getRelativePath(settingsPath), http.StatusFound) +} diff --git a/settingsDb.go b/settingsDb.go index 560f06c..9260e18 100644 --- a/settingsDb.go +++ b/settingsDb.go @@ -3,6 +3,15 @@ package main import ( "database/sql" "errors" + "fmt" +) + +func settingNameWithBlog(blog, name string) string { + return fmt.Sprintf("%s---%s", blog, name) +} + +const ( + defaultSectionSetting = "defaultsection" ) func (a *goBlog) getSettingValue(name string) (string, error) { @@ -63,7 +72,7 @@ func (a *goBlog) saveAllSections() error { for blog, bc := range a.cfg.Blogs { for k, s := range bc.Sections { s.Name = k - if err := a.addSection(blog, s); err != nil { + if err := a.saveSection(blog, s); err != nil { return err } } @@ -71,15 +80,22 @@ func (a *goBlog) saveAllSections() error { return nil } -func (a *goBlog) addSection(blog string, section *configSection) error { +func (a *goBlog) saveSection(blog string, section *configSection) error { _, err := a.db.exec( - "insert into sections (blog, name, title, description, pathtemplate, showfull) values (@blog, @name, @title, @description, @pathtemplate, @showfull)", + ` + insert into sections (blog, name, title, description, pathtemplate, showfull) values (@blog, @name, @title, @description, @pathtemplate, @showfull) + on conflict (blog, name) do update set title = @title2, description = @description2, pathtemplate = @pathtemplate2, showfull = @showfull2 + `, sql.Named("blog", blog), sql.Named("name", section.Name), sql.Named("title", section.Title), sql.Named("description", section.Description), sql.Named("pathtemplate", section.PathTemplate), sql.Named("showfull", section.ShowFull), + sql.Named("title2", section.Title), + sql.Named("description2", section.Description), + sql.Named("pathtemplate2", section.PathTemplate), + sql.Named("showfull2", section.ShowFull), ) return err } @@ -88,16 +104,3 @@ func (a *goBlog) deleteSection(blog string, name string) error { _, err := a.db.exec("delete from sections where blog = @blog and name = @name", sql.Named("blog", blog), sql.Named("name", name)) return err } - -func (a *goBlog) updateSection(blog string, name string, section *configSection) error { - _, err := a.db.exec( - "update sections set title = @title, description = @description, pathtemplate = @pathtemplate, showfull = @showfull where blog = @blog and name = @name", - sql.Named("title", section.Title), - sql.Named("description", section.Description), - sql.Named("pathtemplate", section.PathTemplate), - sql.Named("showfull", section.ShowFull), - sql.Named("blog", blog), - sql.Named("name", section.Name), - ) - return err -} diff --git a/strings/de.yaml b/strings/de.yaml index 3328664..182350b 100644 --- a/strings/de.yaml +++ b/strings/de.yaml @@ -9,6 +9,7 @@ connectviator: "Über Tor verbinden." contactagreesend: "Akzeptieren & Senden" contactsend: "Senden" create: "Erstellen" +default: "Standard" delete: "Löschen" deleteall: "Alle löschen" deletedposts: "Gelöschte Posts" diff --git a/strings/default.yaml b/strings/default.yaml index e754533..68689d1 100644 --- a/strings/default.yaml +++ b/strings/default.yaml @@ -12,6 +12,7 @@ connectviator: "Connect via Tor." contactagreesend: "Accept & Send" contactsend: "Send" create: "Create" +default: "Default" delete: "Delete" deleteall: "Delete all" deletedposts: "Deleted posts" diff --git a/ui.go b/ui.go index 0fc95eb..0ea1d07 100644 --- a/ui.go +++ b/ui.go @@ -1486,8 +1486,9 @@ func (a *goBlog) renderEditor(hb *htmlBuilder, rd *renderData) { } type settingsRenderData struct { - blog string - sections []*configSection + blog string + sections []*configSection + defaultSection string } func (a *goBlog) renderSettings(hb *htmlBuilder, rd *renderData) { @@ -1513,6 +1514,25 @@ func (a *goBlog) renderSettings(hb *htmlBuilder, rd *renderData) { 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")