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 package archetype
type EditMode int
const (
EditModeLiteralTextArea EditMode = iota
EditModeEscapedContentEditable
)
type Adapter interface { type Adapter interface {
Init(cfg *Config) Init(cfg *Config)
Name() string Name() string
EditMode() EditMode EditableSlugs() bool
GetConfig(key string) (interface{}, error) GetConfig(key string) (interface{}, error)
SetConfig(key string, value interface{}) error SetConfig(key string, value interface{}) error
ListPages() map[string]string ListPages() map[string]string
GetPage(string) (Page, error) GetPage(string) (Page, error)
FormatPage(string) string FormatPage(string) string
FormattingHelp() string FormattingHelp() string
CreatePage(page Page) error CreatePage(slug, title, content string) error
EditPage(old Page, new Page) error SavePage(oldSlug, newSlug, title, content string) error
DeletePage(page Page) error DeletePage(slug string) error
Build() string Build() (bool, string)
} }

View file

@ -27,8 +27,8 @@ func (self *EurekaAdapter) Name() string {
return "eureka" return "eureka"
} }
func (self *EurekaAdapter) EditMode() EditMode { func (self *EurekaAdapter) EditableSlugs() bool {
return EditModeLiteralTextArea return false
} }
func (self *EurekaAdapter) GetConfig(key string) (interface{}, error) { func (self *EurekaAdapter) GetConfig(key string) (interface{}, error) {
@ -77,6 +77,7 @@ func (self *EurekaAdapter) GetPage(filename string) (Page, error) {
return Page{ return Page{
Title: title, Title: title,
Slug: filename,
Content: content, Content: content,
Edited: fileInfo.ModTime(), Edited: fileInfo.ModTime(),
}, nil }, nil
@ -90,18 +91,18 @@ func (self *EurekaAdapter) FormattingHelp() string {
return "help!" return "help!"
} }
func (self *EurekaAdapter) CreatePage(page Page) error { func (self *EurekaAdapter) CreatePage(slug, title, content string) error {
return nil return nil
} }
func (self *EurekaAdapter) EditPage(old Page, new Page) error { func (self *EurekaAdapter) SavePage(oldSlug, newSlug, title, content string) error {
return nil return nil
} }
func (self *EurekaAdapter) DeletePage(page Page) error { func (self *EurekaAdapter) DeletePage(slug string) error {
return nil return nil
} }
func (self *EurekaAdapter) Build() string { func (self *EurekaAdapter) Build() (bool, string) {
return "Build successful" return true, "Build successful"
} }

View file

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

2
go.mod
View file

@ -2,6 +2,6 @@ module nilfm.cc/git/nirvash
go 1.17 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 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.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 h1:G+f/UnGpm5FAEqaY3Lj5UHvq0eB5sytM5s4FLesLC3E=
nilfm.cc/git/quartzgun v0.1.0/go.mod h1:/DDvt1DtzNuUf3HHaP29WMei/kkdaRW+ySmEzybvVto= 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 ( import (
"context" "context"
"strings"
"net/http" "net/http"
core "nilfm.cc/git/nirvash/archetype" core "nilfm.cc/git/nirvash/archetype"
) )
@ -15,14 +16,21 @@ func WithAdapter(next http.Handler, adapter core.Adapter) http.Handler {
return http.HandlerFunc(handlerFunc) return http.HandlerFunc(handlerFunc)
} }
func WithEditModes(next http.Handler) http.Handler { func EnsurePageData(next http.Handler) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) { handlerFunc := func(w http.ResponseWriter, req *http.Request) {
*req = *req.WithContext(context.WithValue(req.Context(), "edit-modes", map[string]core.EditMode{ pageTitle := req.FormValue("title")
"Literal": core.EditModeLiteralTextArea, pageContent := req.FormValue("content")
"Escaped": core.EditModeEscapedContentEditable,
})) if pageTitle == "" || pageContent == "" {
next.ServeHTTP(w, req) newUri := "/edit/"
} slug := strings.Join(strings.Split(req.URL.Path, "/")[2:], "/")
newUri += slug
return http.HandlerFunc(handlerFunc) 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")) "templates/login.html"))
rtr.Post("/login", middleware.Authorize("/", udb, "/login?tryagain=1")) rtr.Post("/login", middleware.Authorize("/", udb, "/login?tryagain=1"))
@ -45,12 +45,20 @@ func main() {
"templates/header.html", "templates/header.html",
"templates/footer.html"), cfg.Adapter), http.MethodGet, udb, "/login")) "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( shell.WithAdapter(
renderer.Template( renderer.Template(
"templates/cms_edit.html", "templates/cms_edit.html",
"templates/header.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) http.ListenAndServe(":8080", rtr)
} }

View file

@ -1,19 +1,18 @@
{{ $slug := ((.Context).Value "params").Slug }} {{ $slug := ((.Context).Value "params").Slug }}
{{ $page := ((.Context).Value "adapter").GetPage $slug }} {{ $page := ((.Context).Value "adapter").GetPage $slug }}
{{ $editMode := ((.Context).Value "adapter").EditMode }} {{ $editableSlugs := ((.Context).Value "adapter").EditableSlugs }}
{{ $editModes := (.Context).Value "edit-modes" }}
{{ template "header" . }} {{ template "header" . }}
<a href="/">&laquo;</a>
<form method="POST" action="/save/{{$slug}}"> <form method="POST" action="/save/{{($page).Slug}}">
<textarea name="title">{{($page).Title}}</textarea> <input hidden name="oldSlug" value="{{($page).Slug}}">
<span>last edited {{($page).Edited}}</span> {{ if $editableSlugs }}
{{ if eq $editMode 0 }} <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> <textarea name="content">{{($page).Content}}</textarea>
{{ else }} <input type="submit" value="Save"/>
<div contenteditable>{{($page).Content}}</div>
{{ end }}
<input type="submit" value="Save"/>
</form> </form>
{{ template "footer" . }} {{ 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> <title>Nirvash &mdash; CMS</title>
</head> </head>
<body> <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}} {{end}}