bootstraping page save process

This commit is contained in:
Iris Lightshard 2022-06-04 22:34:20 -06:00
parent 358d4fb2af
commit 59c7fbcc74
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
10 changed files with 67 additions and 45 deletions

View file

@ -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)
}

View file

@ -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 @@ func (self *EurekaAdapter) GetPage(filename string) (Page, error) {
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"
}

View file

@ -6,6 +6,7 @@ import (
type Page struct {
Title string
Slug string
Content string
Edited time.Time
}

2
go.mod
View file

@ -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

4
go.sum
View file

@ -23,3 +23,7 @@ nilfm.cc/git/quartzgun v0.0.0-20220516061509-0e5a81f27b63 h1:HlIWrDDJjOFLrxPQzld
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=

View file

@ -2,6 +2,7 @@ package lfo
import (
"context"
"strings"
"net/http"
core "nilfm.cc/git/nirvash/archetype"
)
@ -15,14 +16,21 @@ func WithAdapter(next http.Handler, adapter core.Adapter) http.Handler {
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)
}

View file

@ -33,7 +33,7 @@ func main() {
},
}
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 @@ func main() {
"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)
}

View file

@ -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" . }}

1
templates/cms_save.html Normal file
View file

@ -0,0 +1 @@
<p>Nothing here yet</p>

View file

@ -8,4 +8,11 @@
<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}}