all repos — nirvash @ e7456651350df48a7093462997489ef02f2b4fda

modular CMS using the quartzgun library

create, edit, and logout functionality all working
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAmKdkMMACgkQO3+8IhRO
Y5iFog/9EzjGVmT8F4EHINsoY2E+jUdvmLpKnT9N0xfwIOx+ffcRnbpAT0u6BjqQ
azJuDQzjEJWNKKiFHAqHe1NgrtxLzTtFDh9F8OWDJ91w/DiSZR50QNsZUdxRHpqm
U7OpXvDDnn4gwowlX77/O+247NICABE4uJGx2hkE4Y9F6SPDMLRPyzQ4OdzUylsx
C9q6iE399eCm+rI7BiyXQug+OI6L9V0UIS3zHFUgFL5LO+Z5FKwitZckdRBwgOcj
SujrEY5PJJpAxqm0SRVPBpbmAw7EtQmrsgaxY0NpZPUF6mU3OCT0CedVZuPCyH41
mCyENUWkKKJR0x85mc5lSrVbjjULZqMZmJSRWMUZFMz16EfKgpFqK5ux9l3vbsNw
v8gkxICqAvbbmlm86J8DaLb7m3NXgU89EEw2zLeAfI99UrXn6SFbiuADmP6lAoJ+
EDS5kNAnEmnQo6AWQCq2UDKD1Bh34PSGZMwfAzHMQA66uEYDN9AzzwfsJMhu6Od/
yoP8/mKbLo3ciEOKbFpVl1gy2/bCKHCyNkrCFcfC5hCiyfbQwGgRw/H0s0vdm1hv
GEbwzYdreZFDn4qYjtFCClHhpjMTk4r9lQqLRQXoAy76eHkFWocJGQTCaWwWqBdt
qCLW2EDx5fPCrqI3rkXZQj3jj6bfXQ6fyEyXBirr3TjS8qPk3k0=
=PnJW
-----END PGP SIGNATURE-----
commit

e7456651350df48a7093462997489ef02f2b4fda

parent

b9d971140a92f8738c6ba1fa59577843e4a120b0

M archetype/eureka.goarchetype/eureka.go

@@ -101,8 +101,15 @@ return "help!"

} func (self *EurekaAdapter) CreatePage(slug, title, content string) error { - // eureka makes titles from slugs, so we don't use title here - f, err := os.Create(filepath.Join(self.Root, "inc", newSlug)) + // eureka creates titles from slugs, so we transform the title into the slug + slug = strings.ReplaceAll(title, " ", "_") + ".htm" + path := filepath.Join(self.Root, "inc", slug) + + _, err := os.Stat(path) + if err == nil || !os.IsNotExist(err) { + return errors.New("File already exists") + } + f, err := os.Create(path) if err != nil { return err }

@@ -112,7 +119,8 @@ return nil

} func (self *EurekaAdapter) SavePage(oldSlug, newSlug, title, content string) error { - // eureka makes titles from slugs, so we don't use title here + // eureka creates titles from slugs, so we transform the title into the slug + newSlug = strings.ReplaceAll(title, " ", "_") + ".htm" f, err := os.Create(filepath.Join(self.Root, "inc", newSlug)) if err != nil { return err
M lfo/middleware.golfo/middleware.go

@@ -16,15 +16,17 @@

return http.HandlerFunc(handlerFunc) } -func EnsurePageData(next http.Handler) http.Handler { +func EnsurePageData(next http.Handler, adapter core.Adapter) http.Handler { handlerFunc := func(w http.ResponseWriter, req *http.Request) { pageTitle := req.FormValue("title") pageContent := req.FormValue("content") + newSlug := req.FormValue("slug") - if pageTitle == "" || pageContent == "" { + if pageTitle == "" || pageContent == "" || (adapter.EditableSlugs() && newSlug == "") { newUri := "/edit/" slug := strings.Join(strings.Split(req.URL.Path, "/")[2:], "/") newUri += slug + newUri += "?no-empty=1" req.Method = http.MethodGet http.Redirect(w, req, newUri, http.StatusSeeOther) } else {
M nirvash.gonirvash.go

@@ -38,27 +38,84 @@ "templates/login.html"))

rtr.Post("/login", middleware.Authorize("/", udb, "/login?tryagain=1")) - rtr.Get("/", middleware.Protected( - shell.WithAdapter( - renderer.Template( - "templates/cms_list.html", - "templates/header.html", - "templates/footer.html"), cfg.Adapter), http.MethodGet, udb, "/login")) - - 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"))) + rtr.Get("/logout", middleware.Bunt("/", udb, "/login?tryagain=1")) - rtr.Post(`/save/(?P<Slug>\S+)`, middleware.Defend(middleware.Protected( - shell.WithAdapter( - shell.EnsurePageData( + rtr.Get( + "/", + middleware.Protected( + shell.WithAdapter( renderer.Template( - "templates/cms_save.html", + "templates/cms_list.html", "templates/header.html", - "templates/footer.html")), cfg.Adapter), http.MethodGet, udb, "/login"), udb, "/")) + "templates/footer.html"), + cfg.Adapter), + http.MethodGet, + udb, + "/login")) + + 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"))) + + 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), + cfg.Adapter), + http.MethodGet, + udb, + "/login"), + udb, + "/")) + + rtr.Get( + `/new`, + middleware.Fortify( + middleware.Protected( + shell.WithAdapter( + renderer.Template( + "templates/cms_new.html", + "templates/header.html", + "templates/footer.html"), + cfg.Adapter), + http.MethodGet, + udb, + "/login"))) + + rtr.Post( + `/create`, + middleware.Defend( + middleware.Protected( + shell.WithAdapter( + shell.EnsurePageData( + renderer.Template( + "templates/cms_create.html", + "templates/header.html", + "templates/footer.html"), + cfg.Adapter), + cfg.Adapter), + http.MethodGet, + udb, + "/login"), + udb, + "/")) http.ListenAndServe(":8080", rtr) }
A templates/cms_create.html

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

+{{ $slug := .FormValue "slug" }} +{{ $title := .FormValue "title" }} +{{ $content := .FormValue "content" }} +{{ $createErr := ((.Context).Value "adapter").CreatePage "" $title $content }} + +{{ template "header" . }} + +{{ if $createErr }} + <span class="adapter-error">There was an error creating the page: {{ ($createErr).Error }}</span> +{{ else }} + <span class="adapter-success">Page '{{ $title }}' created successfully</span> +{{ end }} + +{{ template "footer" . }}
M templates/cms_edit.htmltemplates/cms_edit.html

@@ -1,17 +1,23 @@

{{ $slug := ((.Context).Value "params").Slug }} {{ $page := ((.Context).Value "adapter").GetPage $slug }} {{ $editableSlugs := ((.Context).Value "adapter").EditableSlugs }} +{{ $csrfToken := (.Context).Value "csrfToken" }} +{{ $noEmpty := .FormValue "no-empty" }} {{ template "header" . }} <a href="/">&laquo;</a> -<form method="POST" action="/save/{{($page).Slug}}"> - <input hidden name="oldSlug" value="{{($page).Slug}}"> +<form class="editor" method="POST" action="/save/{{$slug}}"> + {{ if $noEmpty }} + <span class="edit-error">Empty fields are not allowed - please try again</span><br/> + {{ end }} + <input hidden name="csrfToken" value="{{$csrfToken}}"/> + <input hidden name="oldSlug" value="{{$slug}}"/> {{ if $editableSlugs }} - <input type="text" name="slug" value="{{($page).Slug}}"> + <input class="slug-input" type="text" name="slug" value="{{$slug}}"/><br/> {{ end }} - <textarea name="title">{{($page).Title}}</textarea> - <span>last edited {{($page).Edited}}</span> - <textarea name="content">{{($page).Content}}</textarea> + <input class="title-input" type="text" name="title" value="{{($page).Title}}"/><br/> + <span class="edited-time">last edited {{($page).Edited}}</span><br/> + <textarea class="content-input" name="content">{{($page).Content}}</textarea><br/> <input type="submit" value="Save"/> </form>
A templates/cms_new.html

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

+{{ $editableSlugs := ((.Context).Value "adapter").EditableSlugs }} +{{ $csrfToken := (.Context).Value "csrfToken" }} +{{ $noEmpty := .FormValue "no-empty" }} + +{{ template "header" . }} +<a href="/">&laquo;</a> +<form class="editor" method="POST" action="/create"> + {{ if $noEmpty }} + <span class="edit-error">Empty fields are not allowed - please try again</span><br/> + {{ end }} + <input hidden name="csrfToken" value="{{$csrfToken}}"/> + {{ if $editableSlugs }} + <input class="slug-input" type="text" name="slug"/><br/> + {{ end }} + <input class="title-input" type="text" name="title"/><br/> + <textarea class="content-input" name="content"></textarea><br/> + <input type="submit" value="Save"/> +</form> + +{{ template "footer" . }}
M templates/cms_save.htmltemplates/cms_save.html

@@ -1,1 +1,15 @@

-<p>Nothing here yet</p>+{{ $slug := ((.Context).Value "params").Slug }} +{{ $newSlug := .FormValue "slug" }} +{{ $title := .FormValue "title" }} +{{ $content := .FormValue "content" }} +{{ $saveErr := ((.Context).Value "adapter").SavePage $slug $newSlug $title $content }} + +{{ template "header" . }} + +{{ if $saveErr }} + <span class="adapter-error">There was an error saving the page: {{ ($saveErr).Error }}</span> +{{ else }} + <span class="adapter-success">Page '{{ $title }}' saved successfully</span> +{{ end }} + +{{ template "footer" . }}
M templates/footer.htmltemplates/footer.html

@@ -1,5 +1,4 @@

{{define "footer"}} - TEST </body> </html> {{end}}
M templates/header.htmltemplates/header.html

@@ -11,8 +11,9 @@ <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> + <li><a href="/static-mgr">Static Files</a></li> + <li><a href="/build">Build</a></li> + <li><a href="/logout">Logout</a></li> </ul> </nav> {{end}}