create, edit, and logout functionality all working

This commit is contained in:
Iris Lightshard 2022-06-05 23:29:39 -06:00
parent b9d971140a
commit e745665135
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
9 changed files with 155 additions and 34 deletions

View file

@ -101,8 +101,15 @@ func (self *EurekaAdapter) FormattingHelp() string {
}
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 @@ func (self *EurekaAdapter) CreatePage(slug, title, content string) error {
}
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

View file

@ -16,15 +16,17 @@ func WithAdapter(next http.Handler, adapter core.Adapter) http.Handler {
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 {

View file

@ -38,27 +38,84 @@ func main() {
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("/logout", middleware.Bunt("/", udb, "/login?tryagain=1"))
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(
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)
}

14
templates/cms_create.html Normal file
View file

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

View file

@ -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}}">
{{ if $editableSlugs }}
<input type="text" name="slug" 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 }}
<textarea name="title">{{($page).Title}}</textarea>
<span>last edited {{($page).Edited}}</span>
<textarea name="content">{{($page).Content}}</textarea>
<input hidden name="csrfToken" value="{{$csrfToken}}"/>
<input hidden name="oldSlug" value="{{$slug}}"/>
{{ if $editableSlugs }}
<input class="slug-input" type="text" name="slug" value="{{$slug}}"/><br/>
{{ end }}
<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>

20
templates/cms_new.html Normal file
View file

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

View file

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

View file

@ -1,5 +1,4 @@
{{define "footer"}}
TEST
</body>
</html>
{{end}}

View file

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