aboutsummaryrefslogtreecommitdiff
path: root/page
diff options
context:
space:
mode:
authorMitchell Riedstra <mitch@riedstra.dev>2022-06-19 23:57:04 -0400
committerMitchell Riedstra <mitch@riedstra.dev>2022-06-19 23:57:04 -0400
commitbf7d9c79cae53f64fcd04527248987bd4e7ca3c4 (patch)
tree0c763f6545cee4a287f5e6fa0a45489a85454325 /page
parent235b8f871fdfa35f9595268d194d28a3de655ec0 (diff)
downloadgo-website-bf7d9c79cae53f64fcd04527248987bd4e7ca3c4.tar.gz
go-website-bf7d9c79cae53f64fcd04527248987bd4e7ca3c4.tar.xz
0.0.17a / Alpha. Introduce users and page editing.v0.0.17a
Breaking changes: inc/base.html is now tpl/base.md by default. This can be overridden on the command line. 404.md is now tpl/404.md. This can be overridden with templatedirectory in the configuration file. Additional files: `auth.json` file that stores credentials and settings for authorization cookie. Further notes: This will likely receive some major updates and changes over the next few commits. The scaffolidng is now in place for user accounts, login handling, and page editing. It's all extremely basic at the moment, on the idea list: Listing of all markdown files File uploader and general content management Flags to turn on/off git integration for edits. Download / Upload of all markdown files as a backup/restore. It's of course, all subject to change.
Diffstat (limited to 'page')
-rw-r--r--page/page.go58
-rw-r--r--page/render.go137
2 files changed, 160 insertions, 35 deletions
diff --git a/page/page.go b/page/page.go
index b2cc3e1..adb2362 100644
--- a/page/page.go
+++ b/page/page.go
@@ -46,11 +46,11 @@ import (
// The exported fields can be filled in the yaml at the top of a page and
// utilized within.
type Page struct {
- path string
- Title string
- Description string
- AuthorName string
- AuthorEmail string
+ path string
+ DefaultTitle string `yaml:"title"`
+ DefaultDescription string `yaml:"description"`
+ AuthorName string
+ AuthorEmail string
// Tags to apply to the page in question. Useful for Index()
Tags map[string]interface{}
Date *PageTime
@@ -76,8 +76,14 @@ var CacheIndex = true
// backend.
var FileSystem = os.DirFS(".")
+// TemplateDirectory is the parent directory which templates are stored,
+// usually the BaseTemplate is stored here as well, though it does not
+// have to be. Currently this is used for the 4xx and 5xx pages. ( 4xx.md
+// and 5xx.md respectively.
+var TemplateDirectory = "tpl"
+
// BaseTemplate can be adjusted to change the base template used in rendering.
-var BaseTemplate = "inc/base.html"
+var BaseTemplate = "tpl/base.md"
// Suffix is applied to all pages for reading off of the disk.
var Suffix = ".md"
@@ -107,6 +113,46 @@ func (p Page) Path() string {
return filepath.ToSlash(p.path)
}
+// Title returns `DefaultTitle` unless `.Vars.Title` is
+// set, then it returns that instead.
+func (p Page) Title() string {
+ if p.Vars == nil {
+ return p.DefaultTitle
+ }
+
+ t, ok := p.Vars["Title"]
+ if !ok {
+ return p.DefaultTitle
+ }
+
+ nt, ok := t.(string)
+ if !ok {
+ return p.DefaultTitle
+ }
+
+ return nt
+}
+
+// Description returns `DefaultDescription` unless `.Vars.Description` is
+// set, then it returns that instead.
+func (p Page) Description() string {
+ if p.Vars == nil {
+ return p.DefaultDescription
+ }
+
+ t, ok := p.Vars["Description"]
+ if !ok {
+ return p.DefaultDescription
+ }
+
+ nt, ok := t.(string)
+ if !ok {
+ return p.DefaultDescription
+ }
+
+ return nt
+}
+
// Global is specifically for use inside of a page markdown file or
// in a base template. This simply returns the package Global variable.
func (p *Page) Global() interface{} {
diff --git a/page/render.go b/page/render.go
index 6cbabf9..d35ba38 100644
--- a/page/render.go
+++ b/page/render.go
@@ -1,20 +1,104 @@
package page
import (
+ "bytes"
"net/http"
"path/filepath"
"strings"
)
-// Render is a lower level option, allowing you to specify local
-// variables and the status code in which to return.
-func Render(w http.ResponseWriter, r *http.Request,
- path string, vars map[string]interface{}, statusCode int) {
+func getURLPath(r *http.Request) string {
u := r.URL.Path
if u == "/" {
u = "/index"
}
+ return u
+}
+
+// Render5xx is automatically called if any render fails,
+// additionally you can call it for your own uses. It will
+// try to use the 5xx template but will fall back to a plain
+// page if that fails.
+func Render5xx(w http.ResponseWriter, r *http.Request,
+ vars map[string]interface{}, statusCode int) {
+ u := getURLPath(r)
+
+ Logger.Printf("%s %s %d %s",
+ r.RemoteAddr,
+ r.Method,
+ statusCode,
+ u)
+
+ p := NewPage(TemplateDirectory + "/5xx")
+
+ buf := &bytes.Buffer{}
+
+ err := p.Render(buf)
+ if err != nil {
+ Logger.Printf("%s %s path: %s while trying 5xx: %s",
+ r.RemoteAddr,
+ r.Method,
+ u,
+ err)
+ http.Error(w, "Internal server error", statusCode)
+
+ return
+ }
+
+ w.WriteHeader(statusCode)
+
+ _, _ = w.Write(buf.Bytes())
+
+ Logger.Printf("%s %s %d %s", r.RemoteAddr, r.Method, statusCode, u)
+}
+
+// Render4xx is mostly used to render a 404 page, pulls from 404 template.
+// automatically called by Render if a page is missing.
+func Render4xx(w http.ResponseWriter, r *http.Request,
+ vars map[string]interface{}, statusCode int) {
+ u := getURLPath(r)
+
+ Logger.Printf("%s %s %d %s",
+ r.RemoteAddr,
+ r.Method,
+ statusCode,
+ u)
+
+ p := NewPage(TemplateDirectory + "/4xx")
+
+ buf := &bytes.Buffer{}
+
+ err := p.Render(buf)
+ if err != nil {
+ Logger.Printf("%s %s path: %s while trying 404: %s",
+ r.RemoteAddr,
+ r.Method,
+ u,
+ err)
+ Render5xx(w, r, vars, http.StatusInternalServerError)
+
+ return
+ }
+
+ w.WriteHeader(statusCode)
+
+ _, err = w.Write(buf.Bytes())
+ if err != nil {
+ Render5xx(w, r, nil, http.StatusInternalServerError)
+
+ return
+ }
+
+ Logger.Printf("%s %s %d %s", r.RemoteAddr, r.Method, statusCode, u)
+}
+
+// Render is a lower level option, allowing you to specify local
+// variables and the status code in which to return.
+func Render(w http.ResponseWriter, r *http.Request,
+ path string, vars map[string]interface{}, statusCode int) {
+ u := getURLPath(r)
+
u = filepath.Join(".", u)
// Sepcifically use the specified path for the page
@@ -24,42 +108,37 @@ func Render(w http.ResponseWriter, r *http.Request,
p.Vars = vars
}
- err := p.Render(w)
+ buf := &bytes.Buffer{}
+
+ err := p.Render(buf)
if err != nil {
if strings.HasSuffix(err.Error(), "no such file or directory") {
- Logger.Printf("%s %s %d %s",
- r.RemoteAddr,
- r.Method,
- http.StatusNotFound,
- u)
+ Render4xx(w, r, vars, http.StatusNotFound)
- p = NewPage("404")
-
- w.WriteHeader(http.StatusNotFound)
+ return
+ }
- err := p.Render(w)
- if err != nil {
- Logger.Printf("%s %s path: %s while trying 404: %s",
- r.RemoteAddr,
- r.Method,
- u,
- err)
- http.Error(w, "Internal server error",
- http.StatusInternalServerError)
+ Logger.Printf("%s %s path: %s rendering encountered: %s",
+ r.RemoteAddr,
+ r.Method,
+ u,
+ err)
+ Render5xx(w, r, vars, http.StatusInternalServerError)
- return
- }
+ return
+ }
- return
- }
+ w.WriteHeader(statusCode)
- Logger.Printf("%s %s path: %s encountered: %s",
+ _, err = w.Write(buf.Bytes())
+ if err != nil {
+ Logger.Printf("%s %s %d %s: while writing buf: %s",
r.RemoteAddr,
r.Method,
+ statusCode,
u,
err)
- http.Error(w, "Internal server error",
- http.StatusInternalServerError)
+ Render5xx(w, r, nil, http.StatusInternalServerError)
return
}