all repos — nirvash @ 59c7fbcc741b86cdca442dccbe9dba3869771930

modular CMS using the quartzgun library

bootstraping page save process
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmKcMkwACgkQO3+8IhRO
Y5jVmxAAialwgk9+gDLnZU5tnyPo7I4fSiSXD9OpFSKYnqKsB+iu+YeUuCuKMSmV
peEnNN5BKOWgMginG5H0t6x+PsjKAcpbO+YaukOgEqS2RAasnBfw04gNKXRmhz8/
Tf2kUhv+h9X8OpLEfrGXzO+vyRTzjZWe2DgDhDkTwJfdWqGr7ruqdk8vpzgTIXy+
vjd3ZqS/tnvnzsj3riojaFNv75Pnd+szr8/+klr683e9rCRWmDijXDg3/LjqX3s2
1KHjayyZiCl21iTJ4YxG7n9pnddLdfekw/PK3FQCcwHU8SvSR0fWBYJ78nqlsPmt
3OqKqSRn6jQP2Tw1IwmCdgfW0gTuZjPetzWb4DleOfi1iDm9RuGfDLKP6xPKPJRW
sjk+icfyVOIIj3FP3dRV4uwTufOHgTQHJuz/B4ajpgukC9R3TRTTzBdKn86hhCbj
Tvqwzf120IwS+fEFdaurgZ/ODZ2YAVZMOT6A88fZt12ui664aWG442WWrNKTOeYS
z14rOUK/PscgJbj4tyIuItL0TGJqSG9o5gCj8Pr/B7pIHNpTRztRh9sb66c/Oe34
V3S1r9Z0SkRR9OEkPFKIn0vaZGa9jVUFlz4hQzonSN7DHETLJoBSpGlof8wrHus9
cltFwO46NrDRck/skDYiJbJvHfXbkUZ5vHs2hSjqS8yb0/HwQk8=
=JyHV
-----END PGP SIGNATURE-----
commit

59c7fbcc741b86cdca442dccbe9dba3869771930

parent

358d4fb2af62189b913432997462a71b61090eb4

M archetype/adapter.goarchetype/adapter.go

@@ -1,24 +1,17 @@

package archetype -type EditMode int - -const ( - EditModeLiteralTextArea EditMode = iota - EditModeEscapedContentEditable -) - type Adapter interface { Init(cfg *Config) Name() string - EditMode() EditMode + EditableSlugs() bool GetConfig(key string) (interface{}, error) SetConfig(key string, value interface{}) error ListPages() map[string]string GetPage(string) (Page, error) FormatPage(string) string FormattingHelp() string - CreatePage(page Page) error - EditPage(old Page, new Page) error - DeletePage(page Page) error - Build() string + CreatePage(slug, title, content string) error + SavePage(oldSlug, newSlug, title, content string) error + DeletePage(slug string) error + Build() (bool, string) }
M archetype/eureka.goarchetype/eureka.go

@@ -27,8 +27,8 @@ func (self *EurekaAdapter) Name() string {

return "eureka" } -func (self *EurekaAdapter) EditMode() EditMode { - return EditModeLiteralTextArea +func (self *EurekaAdapter) EditableSlugs() bool { + return false } func (self *EurekaAdapter) GetConfig(key string) (interface{}, error) {

@@ -77,6 +77,7 @@ content := string(f[:])

return Page{ Title: title, + Slug: filename, Content: content, Edited: fileInfo.ModTime(), }, nil

@@ -90,18 +91,18 @@ func (self *EurekaAdapter) FormattingHelp() string {

return "help!" } -func (self *EurekaAdapter) CreatePage(page Page) error { +func (self *EurekaAdapter) CreatePage(slug, title, content string) error { return nil } -func (self *EurekaAdapter) EditPage(old Page, new Page) error { +func (self *EurekaAdapter) SavePage(oldSlug, newSlug, title, content string) error { return nil } -func (self *EurekaAdapter) DeletePage(page Page) error { +func (self *EurekaAdapter) DeletePage(slug string) error { return nil } -func (self *EurekaAdapter) Build() string { - return "Build successful" +func (self *EurekaAdapter) Build() (bool, string) { + return true, "Build successful" }
M archetype/page.goarchetype/page.go

@@ -6,6 +6,7 @@ )

type Page struct { Title string + Slug string Content string Edited time.Time }
M go.modgo.mod

@@ -2,6 +2,6 @@ module nilfm.cc/git/nirvash

go 1.17 -require nilfm.cc/git/quartzgun v0.1.0 +require nilfm.cc/git/quartzgun v0.1.2 require golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 // indirect
M go.sumgo.sum

@@ -23,3 +23,7 @@ nilfm.cc/git/quartzgun v0.0.0-20220516061509-0e5a81f27b63 h1:HlIWrDDJjOFLrxPQzldzDz78K8Z5NDtTCoYkmmI8/JA=

nilfm.cc/git/quartzgun v0.0.0-20220516061509-0e5a81f27b63/go.mod h1:/DDvt1DtzNuUf3HHaP29WMei/kkdaRW+ySmEzybvVto= nilfm.cc/git/quartzgun v0.1.0 h1:G+f/UnGpm5FAEqaY3Lj5UHvq0eB5sytM5s4FLesLC3E= nilfm.cc/git/quartzgun v0.1.0/go.mod h1:/DDvt1DtzNuUf3HHaP29WMei/kkdaRW+ySmEzybvVto= +nilfm.cc/git/quartzgun v0.1.1 h1:swJg3im4YsD64MnfJHa2Bxm0adGT/ArAMHLAPeEjuS0= +nilfm.cc/git/quartzgun v0.1.1/go.mod h1:/DDvt1DtzNuUf3HHaP29WMei/kkdaRW+ySmEzybvVto= +nilfm.cc/git/quartzgun v0.1.2 h1:B0IN24Y1Bg2IVvKxXXVtTUNFdVL8h3k/r0+LFAyqtMI= +nilfm.cc/git/quartzgun v0.1.2/go.mod h1:/DDvt1DtzNuUf3HHaP29WMei/kkdaRW+ySmEzybvVto=
M lfo/middleware.golfo/middleware.go

@@ -2,6 +2,7 @@ package lfo

import ( "context" + "strings" "net/http" core "nilfm.cc/git/nirvash/archetype" )

@@ -15,14 +16,21 @@

return http.HandlerFunc(handlerFunc) } -func WithEditModes(next http.Handler) http.Handler { - handlerFunc := func(w http.ResponseWriter, req *http.Request) { - *req = *req.WithContext(context.WithValue(req.Context(), "edit-modes", map[string]core.EditMode{ - "Literal": core.EditModeLiteralTextArea, - "Escaped": core.EditModeEscapedContentEditable, - })) - next.ServeHTTP(w, req) - } - - return http.HandlerFunc(handlerFunc) -} +func EnsurePageData(next http.Handler) http.Handler { + handlerFunc := func(w http.ResponseWriter, req *http.Request) { + pageTitle := req.FormValue("title") + pageContent := req.FormValue("content") + + if pageTitle == "" || pageContent == "" { + newUri := "/edit/" + slug := strings.Join(strings.Split(req.URL.Path, "/")[2:], "/") + newUri += slug + req.Method = http.MethodGet + http.Redirect(w, req, newUri, http.StatusSeeOther) + } else { + next.ServeHTTP(w, req) + } + } + + return http.HandlerFunc(handlerFunc) +}
M nirvash.gonirvash.go

@@ -33,7 +33,7 @@ "/static": cfg.AssetRoot,

}, } - rtr.Get("/login", renderer.Template( + rtr.Get("/login",renderer.Template( "templates/login.html")) rtr.Post("/login", middleware.Authorize("/", udb, "/login?tryagain=1"))

@@ -45,12 +45,20 @@ "templates/cms_list.html",

"templates/header.html", "templates/footer.html"), cfg.Adapter), http.MethodGet, udb, "/login")) - rtr.Get(`/edit/(?P<Slug>\S+)`, middleware.Protected( + rtr.Get(`/edit/(?P<Slug>\S+)`, middleware.Fortify(middleware.Protected( shell.WithAdapter( renderer.Template( "templates/cms_edit.html", "templates/header.html", - "templates/footer.html"), cfg.Adapter), http.MethodGet, udb, "/login")) + "templates/footer.html"), cfg.Adapter), http.MethodGet, udb, "/login"))) + + rtr.Post(`/save/(?P<Slug>\S+)`, middleware.Defend(middleware.Protected( + shell.WithAdapter( + shell.EnsurePageData( + renderer.Template( + "templates/cms_save.html", + "templates/header.html", + "templates/footer.html")), cfg.Adapter), http.MethodGet, udb, "/login"), udb, "/")) http.ListenAndServe(":8080", rtr) }
M templates/cms_edit.htmltemplates/cms_edit.html

@@ -1,19 +1,18 @@

{{ $slug := ((.Context).Value "params").Slug }} {{ $page := ((.Context).Value "adapter").GetPage $slug }} -{{ $editMode := ((.Context).Value "adapter").EditMode }} -{{ $editModes := (.Context).Value "edit-modes" }} +{{ $editableSlugs := ((.Context).Value "adapter").EditableSlugs }} {{ template "header" . }} - -<form method="POST" action="/save/{{$slug}}"> -<textarea name="title">{{($page).Title}}</textarea> -<span>last edited {{($page).Edited}}</span> -{{ if eq $editMode 0 }} +<a href="/">&laquo;</a> +<form method="POST" action="/save/{{($page).Slug}}"> + <input hidden name="oldSlug" value="{{($page).Slug}}"> + {{ if $editableSlugs }} + <input type="text" name="slug" value="{{($page).Slug}}"> + {{ end }} + <textarea name="title">{{($page).Title}}</textarea> + <span>last edited {{($page).Edited}}</span> <textarea name="content">{{($page).Content}}</textarea> -{{ else }} - <div contenteditable>{{($page).Content}}</div> -{{ end }} -<input type="submit" value="Save"/> + <input type="submit" value="Save"/> </form> {{ template "footer" . }}
A templates/cms_save.html

@@ -0,0 +1,1 @@

+<p>Nothing here yet</p>
M templates/header.htmltemplates/header.html

@@ -8,4 +8,11 @@ <meta name='viewport' content='width=device-width,initial-scale=1'>

<title>Nirvash &mdash; CMS</title> </head> <body> + <nav> + <ul> + <li><a href="/">Pages</a></li> + <li><a href="/static-mgr/">Static Files</a></li> + <li><a href="/build/">Build</a></li> + </ul> + </nav> {{end}}