standardize templates a bit, add strong types to build options

This commit is contained in:
Iris Lightshard 2022-06-18 00:17:08 -06:00
parent ae1606081f
commit 2833ba2574
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
20 changed files with 147 additions and 44 deletions

View file

@ -21,11 +21,13 @@ type ConfigOption struct {
Type string Type string
} }
type BuildOption ConfigOption
type Adapter interface { type Adapter interface {
Init(cfg *Config) Init(cfg *Config)
Name() string Name() string
EditableSlugs() bool EditableSlugs() bool
BuildOptions() []string BuildOptions() []BuildOption
GetConfig() map[ConfigOption]string GetConfig() map[ConfigOption]string
SetConfig(map[ConfigOption]string) error SetConfig(map[ConfigOption]string) error
ListPages() map[string]string ListPages() map[string]string
@ -35,5 +37,5 @@ type Adapter interface {
CreatePage(slug, title, content string) error CreatePage(slug, title, content string) error
SavePage(oldSlug, newSlug, title, content string) error SavePage(oldSlug, newSlug, title, content string) error
DeletePage(slug string) error DeletePage(slug string) error
Build(buildOptions map[string][]string) BuildStatus Build(buildOptions map[BuildOption]string) BuildStatus
} }

View file

@ -40,8 +40,21 @@ func (self *EurekaAdapter) EditableSlugs() bool {
return false return false
} }
func (self *EurekaAdapter) BuildOptions() []string { func (self *EurekaAdapter) BuildOptions() []BuildOption {
return []string{"twtxt"} return []BuildOption{
BuildOption{
Name: "twtxt",
Type: "string",
},
BuildOption{
Name: "remove newest twtxt",
Type: "bool",
},
BuildOption{
Name: "clear thumbnail cache",
Type: "bool",
},
}
} }
func (self *EurekaAdapter) GetConfig() map[ConfigOption]string { func (self *EurekaAdapter) GetConfig() map[ConfigOption]string {
@ -249,8 +262,11 @@ func (self *EurekaAdapter) DeletePage(slug string) error {
return os.Remove(filepath.Join(self.Root, "inc", slug)) return os.Remove(filepath.Join(self.Root, "inc", slug))
} }
func (self *EurekaAdapter) Build(buildOptions map[string][]string) BuildStatus { func (self *EurekaAdapter) Build(buildOptions map[BuildOption]string) BuildStatus {
twtxt := strings.Join(buildOptions["twtxt"], " ") twtxt := buildOptions[BuildOption{
Name: "twtxt",
Type: "string",
}]
cmdArgs := []string{} cmdArgs := []string{}
if twtxt != "" { if twtxt != "" {
cmdArgs = append(cmdArgs, "-t") cmdArgs = append(cmdArgs, "-t")

View file

@ -55,7 +55,7 @@ func SanitizeFormMap(next http.Handler) http.Handler {
return http.HandlerFunc(handlerFunc) return http.HandlerFunc(handlerFunc)
} }
func FormMapToAdapterConfig(next http.Handler, adapter core.Adapter) http.Handler { func FormMapToAdapterConfig(next http.Handler) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) { handlerFunc := func(w http.ResponseWriter, req *http.Request) {
cfg := make(map[core.ConfigOption]string) cfg := make(map[core.ConfigOption]string)
for k, arr := range req.PostForm { for k, arr := range req.PostForm {
@ -75,6 +75,26 @@ func FormMapToAdapterConfig(next http.Handler, adapter core.Adapter) http.Handle
return http.HandlerFunc(handlerFunc) return http.HandlerFunc(handlerFunc)
} }
func FormMapToBuildOptions(next http.Handler) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) {
options := make(map[core.BuildOption]string)
for k, arr := range req.PostForm {
v := strings.Join(arr, "")
optNameAndType := strings.Split(k, ":")
optName := optNameAndType[0]
optType := optNameAndType[1]
options[core.BuildOption{
Name: optName,
Type: optType,
}] = v
}
*req = *req.WithContext(context.WithValue(req.Context(), "build-options", options))
next.ServeHTTP(w, req)
}
return http.HandlerFunc(handlerFunc)
}
func PrepareForUpload(next http.Handler, fileManager core.FileManager) http.Handler { func PrepareForUpload(next http.Handler, fileManager core.FileManager) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) { handlerFunc := func(w http.ResponseWriter, req *http.Request) {
req.ParseMultipartForm(fileManager.MaxUploadMB() << 20) req.ParseMultipartForm(fileManager.MaxUploadMB() << 20)

View file

@ -148,12 +148,13 @@ func main() {
Defend( Defend(
Protected( Protected(
SanitizeFormMap( SanitizeFormMap(
WithAdapter( FormMapToBuildOptions(
renderer.Template( WithAdapter(
pathConcat(templateRoot, "build_run.html"), renderer.Template(
pathConcat(templateRoot, "header.html"), pathConcat(templateRoot, "build_run.html"),
pathConcat(templateRoot, "footer.html")), pathConcat(templateRoot, "header.html"),
cfg.Adapter)), pathConcat(templateRoot, "footer.html")),
cfg.Adapter))),
http.MethodGet, http.MethodGet,
udb, udb,
"/login"), "/login"),
@ -201,8 +202,7 @@ func main() {
pathConcat(templateRoot, "config_set.html"), pathConcat(templateRoot, "config_set.html"),
pathConcat(templateRoot, "header.html"), pathConcat(templateRoot, "header.html"),
pathConcat(templateRoot, "footer.html")), pathConcat(templateRoot, "footer.html")),
cfg.Adapter), cfg.Adapter))),
cfg.Adapter)),
http.MethodGet, http.MethodGet,
udb, udb,
"/login"), "/login"),

View file

@ -7,16 +7,35 @@
<form class="build" method="POST" action="/build-run"> <form class="build" method="POST" action="/build-run">
<input hidden type="text" name="csrfToken" value="{{$csrfToken}}"/> <input hidden type="text" name="csrfToken" value="{{$csrfToken}}"/>
<details><summary>Build Options</summary>
{{ if $buildOpts }} {{ if $buildOpts }}
{{ range $optName := $buildOpts }} <details><summary>Build Options</summary>
<label>{{$optName}} <input type="text" name="{{$optName}}"/></label> {{ range $opt := $buildOpts }}
{{ if eq ($opt).Type "bool" }}
<label>{{($opt).Name}} <input type="checkbox" name="{{($opt).Name}}:{{($opt).Type}}"/></label><br/>
{{ end }}
{{ end }}
{{ range $opt := $buildOpts }}
{{ if eq ($opt).Type "int" }}
<label>{{($opt).Name}} <input type="number" step="1" name="{{($opt).Name}}:{{($opt).Type}}"/></label><br/>
{{ end }}
{{ end }}
{{ range $opt := $buildOpts }}
{{ if eq ($opt).Type "float" }}
<label>{{($opt).Name}} <input type="number" step="0.00000001" name="{{($opt).Name}}:{{($opt).Type}}"/></label><br/>
{{ end }}
{{ end }}
{{ range $opt := $buildOpts }}
{{ if eq ($opt).Type "string" }}
<label>{{($opt).Name}} <input type="text" name="{{($opt).Name}}:{{($opt).Type}}"/></label><br/>
{{ end }}
{{ end }}
{{ range $opt := $buildOpts }}
{{ if eq ($opt).Type "multilinestring" }}
<label>{{($opt).Name}} <textarea name="{{($opt).Name}}:{{($opt).Type}}"></textarea></label><br/>
{{ end }}
{{ end }} {{ end }}
{{ else }}
<span>There are no build options for this adapter.</span>
{{ end }}
</details> </details>
{{ end }}
<input type="submit" value="Build"/> <input type="submit" value="Build"/>
</form> </form>

View file

@ -1,14 +1,18 @@
{{ $buildOpts := .PostForm }} {{ $buildOpts := (.Context).Value "build-options" }}
{{ $status := ((.Context).Value "adapter").Build $buildOpts }} {{ $status := ((.Context).Value "adapter").Build $buildOpts }}
{{ template "header" . }} {{ template "header" . }}
{{ if ne ($status).Success true }} {{ if ne ($status).Success true }}
<h2>Build Error</h2> <h2>Build Error</h2>
<span class="adapter-error"><pre>{{($status).Message}}</pre></span> <span class="adapter-error"><pre>{{($status).Message}}</pre></span>
{{ else }} {{ else }}
<h2>Build Successful</h2> <h2>Build Successful</h2>
<span class="adapter-success"><pre>{{($status).Message}}</pre></span> <span class="adapter-success"><pre>{{($status).Message}}</pre></span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -6,11 +6,15 @@
{{ template "header" . }} {{ template "header" . }}
{{ if $createErr }} {{ if $createErr }}
<h2>Page Creation Error</h2> <h2>Page Creation Error</h2>
<span class="adapter-error">There was an error creating the page: {{ ($createErr).Error }}</span> <span class="adapter-error">{{ ($createErr).Error }}</span>
{{ else }} {{ else }}
<h2>Page Created</h2> <h2>Page Created</h2>
<span class="adapter-success">Page '{{ $title }}' created successfully</span> <span class="adapter-success">Page '{{ $title }}' created successfully</span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -7,9 +7,10 @@
{{ template "header" . }} {{ template "header" . }}
{{ if ($page).Error }} {{ if ($page).Error }}
<h2>Page Error</h2>
<h2>Page Error</h2>
<span class="adapter-error">{{($page).Error}}</span> <span class="adapter-error">{{($page).Error}}</span>
{{ else }} {{ else }}
<h2>Edit Page</h2> <h2>Edit Page</h2>

View file

@ -7,11 +7,15 @@
{{ template "header" . }} {{ template "header" . }}
{{ if $saveErr }} {{ if $saveErr }}
<h2>Page Save Error</h2> <h2>Page Save Error</h2>
<span class="adapter-error">There was an error saving the page: {{ ($saveErr).Error }}</span> <span class="adapter-error">{{ ($saveErr).Error }}</span>
{{ else }} {{ else }}
<h2>Page Saved</h2> <h2>Page Saved</h2>
<span class="adapter-success">Page '{{ $title }}' saved successfully</span> <span class="adapter-success">Page '{{ $title }}' saved successfully</span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -7,6 +7,11 @@
<form class="configurator" method="POST" action="/config-set"> <form class="configurator" method="POST" action="/config-set">
<input hidden type="text" name="csrfToken" value="{{$csrfToken}}"/> <input hidden type="text" name="csrfToken" value="{{$csrfToken}}"/>
{{ range $opt, $val := $config }}
{{ if eq ($opt).Type "bool" }}
<label>{{($opt).Name}} <input type="checkbox" name="{{($opt).Name}}:{{($opt).Type}}" checked="{{$val}}"/></label><br/>
{{ end }}
{{ end }}
{{ range $opt, $val := $config }} {{ range $opt, $val := $config }}
{{ if eq ($opt).Type "int" }} {{ if eq ($opt).Type "int" }}
<label>{{($opt).Name}} <input type="number" step="1" name="{{($opt).Name}}:{{($opt).Type}}" value="{{$val}}"/></label><br/> <label>{{($opt).Name}} <input type="number" step="1" name="{{($opt).Name}}:{{($opt).Type}}" value="{{$val}}"/></label><br/>

View file

@ -4,11 +4,15 @@
{{ template "header" . }} {{ template "header" . }}
{{ if $cfgError }} {{ if $cfgError }}
<h2>Configuration Error</h2> <h2>Configuration Error</h2>
<span class="adapter-error">{{($cfgError).Error}}</span> <span class="adapter-error">{{($cfgError).Error}}</span>
{{ else }} {{ else }}
<h2>Configuration Saved</h2> <h2>Configuration Saved</h2>
<span class="adapter-success">The adapter configuration has been saved</span> <span class="adapter-success">The adapter configuration has been saved</span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -4,11 +4,15 @@
{{ template "header" . }} {{ template "header" . }}
{{ if $deleteErr }} {{ if $deleteErr }}
<h2>Deletion Error</h2> <h2>Deletion Error</h2>
<span class="adapter-error">There was an error deleting the page: {{ ($deleteErr).Error }}</span> <span class="adapter-error">{{ ($deleteErr).Error }}</span>
{{ else }} {{ else }}
<h2>Page Deleted</h2> <h2>Page Deleted</h2>
<span class="adapter-success">Page at '{{ $slug }}' was deleted</span> <span class="adapter-success">Page at '{{ $slug }}' was deleted</span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -4,11 +4,15 @@
{{ template "header" . }} {{ template "header" . }}
{{ if $deleteErr }} {{ if $deleteErr }}
<h2>File Deletion Error</h2> <h2>File Deletion Error</h2>
<span class="adapter-error">There was an error deleting the file: {{ ($deleteErr).Error }}</span> <span class="adapter-error">{{ ($deleteErr).Error }}</span>
{{ else }} {{ else }}
<h2>File Deleted</h2> <h2>File Deleted</h2>
<span class="adapter-success">Static file '{{ $slug }}' was deleted</span> <span class="adapter-success">'{{ $slug }}' was deleted successfully</span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -5,9 +5,10 @@
{{ if ($fileList).Error }} {{ if ($fileList).Error }}
<h2>File Listing Error</h2>
<h2>File Listing Error</h2>
<span class="adapter-error">{{($fileList).Error}}</span> <span class="adapter-error">{{($fileList).Error}}</span>
{{ else }} {{ else }}
<h2>Files: {{($fileList).Root}}</h2> <h2>Files: {{($fileList).Root}}</h2>

View file

@ -1,8 +1,16 @@
{{ $slug := ((.Context).Value "params").Slug }} {{ $slug := ((.Context).Value "params").Slug }}
{{ $fileData := ((.Context).Value "file-manager").GetFileData $slug }}
{{ $csrfToken := (.Context).Value "csrfToken" }} {{ $csrfToken := (.Context).Value "csrfToken" }}
{{ template "header" . }} {{ template "header" . }}
{{ if ($fileData).Error }}
<h2>Error</h2>
<span class="adapter-error">{{($fileData).Error}}</span>
{{ else }}
<h2>Directory Creation</h2> <h2>Directory Creation</h2>
<form class="mkdir" method="POST" action="/mkdir-process/{{$slug}}"> <form class="mkdir" method="POST" action="/mkdir-process/{{$slug}}">
@ -15,4 +23,6 @@
<input type="submit" value="Create"/> <input type="submit" value="Create"/>
</form> </form>
{{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -5,11 +5,15 @@
{{ template "header" . }} {{ template "header" . }}
{{ if $mkdirError }} {{ if $mkdirError }}
<h2>Directory Creation Error</h2>
<span class="adapter-error">{{($mkdirError).Error}}</span> <h2>Directory Creation Error</h2>
<span class="adapter-error">{{($mkdirError).Error}}</span>
{{ else }} {{ else }}
<h2>Directory Created</h2>
<span class="adapter-success">The directory has been created successfully</span> <h2>Directory Created</h2>
<span class="adapter-success">The directory has been created successfully</span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}

View file

@ -15,10 +15,10 @@
{{ else if ($fileData).Error }} {{ else if ($fileData).Error }}
<h2>File Listing Error</h2> <h2>File Listing Error</h2>
<span class="adapter-error">{{($fileData).Error}}</span> <span class="adapter-error">{{($fileData).Error}}</span>
{{ else }} {{ else }}
<h2>Moving {{($fileData).Name}}: {{($fileList).Root}}</h2> <h2>Moving {{($fileData).Name}}: {{($fileList).Root}}</h2>
<form class="move-rename-file" method="POST" action="/file-move-process/{{($fileData).Path}}"> <form class="move-rename-file" method="POST" action="/file-move-process/{{($fileData).Path}}">

View file

@ -8,13 +8,11 @@
{{ if $moveError }} {{ if $moveError }}
<h2>File Move/Rename Error</h2> <h2>File Move/Rename Error</h2>
<span class="adapter-error">{{$moveError}}</span> <span class="adapter-error">{{$moveError}}</span>
{{ else }} {{ else }}
<h2>File Move/Rename Success</h2> <h2>File Move/Rename Success</h2>
<span class="adapter-success">File moved from /{{$slug}} to {{$dest}}{{$name}} </span> <span class="adapter-success">File moved from /{{$slug}} to {{$dest}}{{$name}} </span>
{{ end }} {{ end }}

View file

@ -5,12 +5,11 @@
{{ template "header" . }} {{ template "header" . }}
{{ if ($fileData).Error }} {{ if ($fileData).Error }}
<h2>Error</h2>
<h2>Filesystem Error</h2>
<span class="adapter-error">{{($fileData).Error}}</span> <span class="adapter-error">{{($fileData).Error}}</span>
{{ else }} {{ else }}
<h2>File Upload</h2> <h2>File Upload</h2>
<form class="uploader" enctype="multipart/form-data" method="POST" action="/upload-process/{{$slug}}"> <form class="uploader" enctype="multipart/form-data" method="POST" action="/upload-process/{{$slug}}">

View file

@ -4,11 +4,15 @@
{{ template "header" . }} {{ template "header" . }}
{{ if $uploadError }} {{ if $uploadError }}
<h2>Upload Error</h2>
<span class="adapter-error">{{($uploadError).Error}}</span> <h2>Upload Error</h2>
<span class="adapter-error">{{($uploadError).Error}}</span>
{{ else }} {{ else }}
<h2>Upload Successful</h2>
<span class="adapter-success">The file has been uploaded successfuly</span> <h2>Upload Successful</h2>
<span class="adapter-success">The file has been uploaded successfuly</span>
{{ end }} {{ end }}
{{ template "footer" . }} {{ template "footer" . }}