aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE2
-rw-r--r--cmd/server/app.go42
-rw-r--r--cmd/server/edit.go130
-rw-r--r--cmd/server/handlers.go130
-rw-r--r--cmd/server/main.go17
-rw-r--r--cmd/server/middleware.go140
-rw-r--r--example-site/index.md2
-rw-r--r--example-site/login.md21
-rw-r--r--example-site/tpl/dashboard.md62
-rw-r--r--example-site/tpl/edit.md27
-rw-r--r--example-site/tpl/new-template.md55
-rw-r--r--page/page.go12
-rw-r--r--page/renderJson.go108
-rw-r--r--page/renderMarkdown.go61
14 files changed, 70 insertions, 739 deletions
diff --git a/LICENSE b/LICENSE
index b10b656..d938a85 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2021 Mitchell Riedstra
+Copyright 2026 Mitchell Riedstra
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
diff --git a/cmd/server/app.go b/cmd/server/app.go
index c694753..a8d1ce8 100644
--- a/cmd/server/app.go
+++ b/cmd/server/app.go
@@ -39,25 +39,7 @@ type App struct {
FeedPrefix string
}
-func newApp() *App {
- return &App{}
-}
-
-func loadConf(fn string) (*App, error) {
- fh, err := os.Open(fn)
- if err != nil {
- return nil, fmt.Errorf("loading config: %w", err)
- }
-
- dec := yaml.NewDecoder(fh)
-
- app := newApp()
-
- err = dec.Decode(app)
- if err != nil {
- return nil, fmt.Errorf("decoding yaml: %w", err)
- }
-
+func (app *App) setDefaults() {
if app.StaticDirectory == "" {
app.StaticDirectory = "static"
}
@@ -85,8 +67,28 @@ func loadConf(fn string) (*App, error) {
page.Global = map[string]interface{}{
"App": app,
}
+}
+
+func loadConf(fn string) (*App, error) {
+ var dec *yaml.Decoder
+ app := &App{}
+
+ fh, err := os.Open(fn)
+ if err != nil {
+ err = fmt.Errorf("loading config: %w", err)
+ goto loadConfRet
+ }
+
+ dec = yaml.NewDecoder(fh)
+
+ err = dec.Decode(app)
+ if err != nil {
+ err = fmt.Errorf("decoding yaml: %w", err)
+ }
- return app, nil
+loadConfRet:
+ app.setDefaults()
+ return app, err
}
func (a *App) ClearCache() error {
diff --git a/cmd/server/edit.go b/cmd/server/edit.go
deleted file mode 100644
index 5b40f51..0000000
--- a/cmd/server/edit.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package main
-
-import (
- "bytes"
- "errors"
- "html"
- "io"
- "io/fs"
- "log"
- "net/http"
- "os"
- "path/filepath"
-
- "riedstra.dev/mitch/go-website/page"
-)
-
-const editFileMode = 0644
-
-func (a *App) EditPage() http.Handler {
- getFunc := a.GetEditPage().ServeHTTP
- postFunc := a.SaveEditPage().ServeHTTP
-
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- switch r.Method {
- case "GET": //nolint:goconst
- getFunc(w, r)
-
- return
- case "POST": //nolint:goconst
- postFunc(w, r)
-
- return
- default:
- a.Err500Default(w, r)
-
- return
- }
- })
-}
-
-func (a *App) GetEditPage() http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method != "GET" {
- page.Render(w, r, page.TemplateDirectory+"/4xx", map[string]interface{}{
- "Title": "Method Not allowed",
- "Description": "Method not allowed",
- "LoggedIn": a.IsLoggedIn(r),
- }, http.StatusMethodNotAllowed)
-
- return
- }
-
- p := r.URL.Path
-
- p = filepath.Clean(p)
-
- fh, err := os.Open("./" + p + page.Suffix)
- if err != nil && errors.Is(err, fs.ErrNotExist) {
- fh, err = os.Open("./" + page.TemplateDirectory +
- "/new-template" + page.Suffix)
- }
-
- if err != nil {
- log.Printf("opening page: %s", err)
- a.Err500Default(w, r)
-
- return
- }
- defer fh.Close()
-
- b, err := io.ReadAll(fh)
- if err != nil {
- log.Printf("opening page: %s", err)
- a.Err500Default(w, r)
-
- return
- }
-
- page.Render(w, r, page.TemplateDirectory+"/edit", map[string]interface{}{
- "Page": p,
- "Content": html.EscapeString(string(b)),
- "LoggedIn": a.IsLoggedIn(r),
- }, http.StatusOK)
- })
-}
-
-func (a *App) SaveEditPage() http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method != "POST" {
- a.Err500Default(w, r)
-
- return
- }
-
- p := r.URL.Path
- content := r.FormValue("content")
-
- content = html.UnescapeString(content)
- p = filepath.Clean(p)
-
- fn := "./" + p + page.Suffix
-
- fh, err := os.OpenFile(fn, os.O_RDWR|os.O_CREATE|os.O_TRUNC,
- editFileMode)
- if err != nil {
- log.Printf("opening file %s for writing: %s", fn, err)
- a.Err500Default(w, r)
-
- return
- }
- defer fh.Close()
-
- c := bytes.ReplaceAll([]byte(content), []byte{'\r'}, []byte{})
-
- _, err = fh.Write(c)
- if err != nil {
- log.Printf("opening file %s for writing: %s", fn, err)
- a.Err500Default(w, r)
-
- return
- }
-
- http.Redirect(w, r, "/"+r.URL.Path, http.StatusFound)
-
- err = a.ClearCache() // Clear out the cache if any
- if err != nil {
- log.Printf("after editing %s: %s", fn, err)
- }
- })
-}
diff --git a/cmd/server/handlers.go b/cmd/server/handlers.go
index 010705e..49f2039 100644
--- a/cmd/server/handlers.go
+++ b/cmd/server/handlers.go
@@ -1,127 +1,81 @@
package main
import (
- "fmt"
"net/http"
"path/filepath"
"strings"
+ "fmt"
"riedstra.dev/mitch/go-website/mapcache"
"riedstra.dev/mitch/go-website/page"
"riedstra.dev/mitch/go-website/rediscache"
)
-func (a *App) baseRouter() *http.ServeMux {
- r := http.NewServeMux()
- r.Handle(a.ReIndexPath, a.RebuildIndexHandler())
- r.Handle("/static/", a.StaticHandler())
- r.Handle("/login", a.LoginHandler())
- r.Handle("/logout", a.RequiresLogin(a.LogoutHandler()))
- r.Handle("/edit/", a.RequiresLogin(
- http.StripPrefix("/edit/", a.EditPage())))
-
- return r
-}
-
-func (a *App) addCacheableRoutes(r *http.ServeMux) *http.ServeMux {
- // make sure it always has a trailing slash and starts with a slash
- a.FeedPrefix = fmt.Sprintf("/%s/",
- strings.TrimSuffix(strings.TrimPrefix(a.FeedPrefix, "/"), "/"))
+func (a *App) Handler() http.Handler {
+ mux := http.NewServeMux()
- routes := map[string]http.Handler{
- "/_json/": http.StripPrefix("/_json/", a.PageJSONHandler()),
- "/_md/": http.StripPrefix("/_md/", a.PageMarkdownHandler()),
- a.FeedPrefix: http.StripPrefix(a.FeedPrefix, a.FeedHandler()),
- "/": a.PageHandler(),
+ type route struct {
+ path string
+ handler http.Handler
}
- if a.cache == nil {
- a.cache = mapcache.New()
+ routes := []route{
+ {a.ReIndexPath, a.RebuildIndexHandler()},
+ {"/static/", a.StaticHandler()},
}
-
- for route, handler := range routes {
- switch {
- case a.mapCache:
- r.Handle(route, conditionalMiddleware(
- a.IsLoggedIn,
- handler,
- a.cache.Handle(handler)))
- case a.redisPool != nil:
- r.Handle(route, conditionalMiddleware(
- a.IsLoggedIn,
- handler,
- rediscache.Handle(a.redisPool, a.RedisKey, handler)))
- default:
- r.Handle(route, handler)
- }
+ cacheableRoutes := []route{
+ {a.FeedPrefix, http.StripPrefix(a.FeedPrefix, a.FeedHandler())},
+ {"/", a.PageHandler()},
}
- return r
-}
-
-func (a *App) Handler() http.Handler {
- return a.addCacheableRoutes(a.baseRouter())
-}
-
-func (a *App) PageHandler() http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- u := page.GetURLPath(r)
+ for _, route := range routes {
+ mux.Handle(route.path, route.handler)
+ }
- loggedIn := a.IsLoggedIn(r)
+ if a.cache == nil && a.RedisKey != "" {
+ a.cache = mapcache.New()
+ }
- if u == "/dashboard" && loggedIn {
- u = page.TemplateDirectory + "/dashboard"
+ var cacheHandler func(http.Handler) http.Handler = nil
+ switch {
+ case a.mapCache:
+ cacheHandler = a.cache.Handle
+ case a.redisPool != nil:
+ cacheHandler = func(h http.Handler) http.Handler {
+ return rediscache.Handle(a.redisPool, a.RedisKey, h)
}
-
- // Render nothing inside of the template directory if we're not logged in
- if strings.HasPrefix(u[1:], filepath.Clean(page.TemplateDirectory)) &&
- !loggedIn {
- page.Render4xx(w, r, map[string]interface{}{
- "LoggedIn": loggedIn,
- }, http.StatusNotFound)
-
- return
+ default:
+ // No caching middleware
+ cacheHandler = func(h http.Handler) http.Handler {
+ return h
}
+ }
- u = filepath.Join(".", u)
-
- page.RenderWithVars(w, r, u, map[string]interface{}{
- "LoggedIn": loggedIn,
- })
- })
-}
-
-func (a *App) PageJSONHandler() http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- u := page.GetURLPath(r)
-
- // Skip template directory
- if strings.HasPrefix(u[1:], filepath.Clean(page.TemplateDirectory)) {
- page.Render4xx(w, r, map[string]interface{}{}, http.StatusNotFound)
-
- return
- }
+ if cacheHandler == nil {
+ panic("cacheHandler cannot be nil")
+ }
- u = filepath.Join(".", u)
+ for _, r := range cacheableRoutes {
+ fmt.Printf("Calling mux.Handle(r.path(%s), cacheHandler(r.handler(%v)))\n",
+ r.path, r.handler)
+ mux.Handle(r.path, cacheHandler(r.handler))
+ }
- page.RenderJSON(w, r, u, map[string]interface{}{}, http.StatusOK)
- })
+ return mux
}
-func (a *App) PageMarkdownHandler() http.Handler {
+func (a *App) PageHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u := page.GetURLPath(r)
- // Skip template directory
+ // Render nothing inside of the template directory
if strings.HasPrefix(u[1:], filepath.Clean(page.TemplateDirectory)) {
- page.Render4xx(w, r, map[string]interface{}{}, http.StatusNotFound)
-
return
}
u = filepath.Join(".", u)
- page.RenderMarkdown(w, r, u, map[string]interface{}{}, http.StatusOK)
+ page.RenderWithVars(w, r, u, map[string]interface{}{})
})
}
diff --git a/cmd/server/main.go b/cmd/server/main.go
index 10bbbf0..1b59bbe 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -36,15 +36,14 @@ func main() { //nolint:funlen
directory = "."
version = false
confFn = "conf.yml"
- authConfFn = "auth.json"
verbose = false
defaultIndexPath = "/reIndex"
indexPath = "/reIndex"
- redisAddr = "127.0.0.1:6379"
+ redisAddr = ""
redisKey = "go-website"
pageTimeout = 15
genhash = false
- mapcache = false
+ mapcache = true
)
fl := flag.NewFlagSet("Website", flag.ExitOnError)
@@ -56,8 +55,6 @@ func main() { //nolint:funlen
"print version and exit"))
envflag.String(fl, &confFn, "c", "CONFIG_FILE",
"Location for configuration file")
- envflag.String(fl, &authConfFn, "ac", "AUTH_CONFIG",
- "location for the authorization config")
logIfErr(envflag.Bool(fl, &verbose, "V", "VERBOSE",
"Be more verbose, dump config and such"))
envflag.String(fl, &page.TimeFormat, "T", "TIME_FORMAT",
@@ -94,20 +91,14 @@ func main() { //nolint:funlen
app, err := loadConf(confFn)
if err != nil {
- logger.Println(err)
-
- app = &App{}
+ logger.Print(err)
+ logger.Fatal("A configuration file must be supplied. No valid config read")
}
if mapcache {
app.mapCache = true
}
- err = app.ReadAuth(authConfFn)
- if err != nil {
- logger.Println(err)
- }
-
if app.ReIndexPath == "" || indexPath != defaultIndexPath {
app.ReIndexPath = indexPath
}
diff --git a/cmd/server/middleware.go b/cmd/server/middleware.go
index 17717c2..991aa8c 100644
--- a/cmd/server/middleware.go
+++ b/cmd/server/middleware.go
@@ -1,20 +1,12 @@
package main
import (
- "errors"
- "fmt"
- "log"
"net/http"
- "net/url"
"time"
- jwt "github.com/golang-jwt/jwt/v4"
"riedstra.dev/mitch/go-website/page"
- "riedstra.dev/mitch/go-website/users"
)
-var ErrInvalidJWTToken = errors.New("invalid JWT token")
-
func (a *App) Err5xx(w http.ResponseWriter, r *http.Request,
statusCode int, title, desc string) {
page.Render5xx(w, r, map[string]interface{}{
@@ -42,135 +34,3 @@ func (a *App) LogoutHandler() http.Handler {
http.Redirect(w, r, "/", http.StatusFound)
})
}
-
-func (a *App) LoginHandler() http.Handler { //nolint
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- loggedIn := a.IsLoggedIn(r)
-
- next, _ := url.Parse(r.URL.Query().Get("next"))
-
- if r.Method == "GET" && !loggedIn {
- page.RenderForPath(w, r, "login")
-
- return
- }
-
- if r.Method == "GET" && loggedIn {
- if next.Path != "" {
- http.Redirect(w, r, next.Path, http.StatusFound)
-
- return
- }
-
- http.Redirect(w, r, "/dashboard", http.StatusFound)
-
- return
- }
-
- if r.Method != "POST" {
- a.Err500Default(w, r)
-
- return
- }
-
- username := r.FormValue("username")
- password := r.FormValue("password")
-
- var (
- err error
- u *users.SiteUser
- found = false
- )
-
- for _, u = range a.auth.Users {
- if u.Username == username {
- err = u.CheckPassword(password)
- found = true
- }
- }
-
- if err != nil || !found {
- page.Render(w, r, "login", map[string]interface{}{
- "Error": "Invalid username or password",
- "Username": username,
- }, http.StatusUnauthorized)
-
- return
- }
-
- token := jwt.NewWithClaims(jwt.SigningMethodHS512, &jwt.StandardClaims{
- ExpiresAt: time.Now().Add(
- time.Hour * time.Duration(a.auth.LoginHours)).Unix(),
- Id: u.Username,
- })
-
- ss, err := token.SignedString([]byte(a.auth.TokenKey))
- if err != nil {
- log.Println("login: encountered while setting up JWT: ", err)
- a.Err500Default(w, r)
-
- return
- }
-
- http.SetCookie(w, &http.Cookie{
- Name: "Auth",
- HttpOnly: a.auth.HTTPOnly,
- SameSite: a.auth.SameSiteStrict,
- Secure: a.auth.Secure,
- Value: ss,
- })
-
- http.Redirect(w, r, "/login", http.StatusFound)
- })
-}
-
-func (a *App) IsLoggedIn(r *http.Request) bool {
- _, err := a.GetAuthToken(r)
- if err != nil {
- log.Printf("%s IsLoggedIn: false", r.URL.Path)
-
- return false
- }
-
- log.Printf("%s IsLoggedIn: true", r.URL.Path)
-
- return true
-}
-
-func (a *App) GetAuthToken(r *http.Request) (*jwt.Token, error) {
- c, err := r.Cookie("Auth")
- if err != nil {
- return nil, fmt.Errorf("getting auth token: %w", err)
- }
-
- token, err := jwt.Parse(c.Value,
- func(token *jwt.Token) (interface{}, error) {
- return []byte(a.auth.TokenKey), nil
- },
- )
-
- if err != nil {
- return nil, fmt.Errorf("while parsing jwt %w", err)
- }
-
- if !token.Valid {
- return token, ErrInvalidJWTToken
- }
-
- return token, nil
-}
-
-func (a *App) RequiresLogin(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if !a.IsLoggedIn(r) {
- log.Printf("Unauthorized request %s %s", r.Method, r.URL.Path)
- page.Render(w, r, "login", map[string]interface{}{
- "Error": "You must login to view this page",
- }, http.StatusUnauthorized)
-
- return
- }
-
- next.ServeHTTP(w, r)
- })
-}
diff --git a/example-site/index.md b/example-site/index.md
index 7d51067..451f36e 100644
--- a/example-site/index.md
+++ b/example-site/index.md
@@ -24,7 +24,7 @@ it.
{{range $val := .Index.Blog.SortDate}}
* [{{$val.Date.Time.Format "2006-01-02"}} {{$val.Title}}]({{$val.Path}}){{end}}
-## Published Blog Entries:
+## Only Published Blog Entries:
{{range $val := .Index.Blog.SortDate}}{{if $val.Published}}
* [{{$val.Date.Time.Format "2006-01-02"}} {{$val.Title}}]({{$val.Path}}){{end}}{{end}}
diff --git a/example-site/login.md b/example-site/login.md
deleted file mode 100644
index 1b29ddd..0000000
--- a/example-site/login.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: Login
-description: Login page
-|---
-
-<form action="/login" method="POST">
-<label for="username">Username:</label>
-<input type="text" id="username" name="username" />
-
-<label for="password">Password:</label>
-<input type="password" id="password" name="password" />
-
-<input type="submit" value="submit">
-</form>
-
-
-{{if .Vars}}
-```
-{{.Vars}}
-```
-{{else}}{{end}}
diff --git a/example-site/tpl/dashboard.md b/example-site/tpl/dashboard.md
deleted file mode 100644
index 4b18b98..0000000
--- a/example-site/tpl/dashboard.md
+++ /dev/null
@@ -1,62 +0,0 @@
----
-title: Website Dashboard
-description: Website dashboard
-|---
-
-# Dashboard page ( File: `tpl/dashboard.md` )
-
-Almost every page on the website can be edited by simply adding `edit/` before
-the path, for instance if we want to edit our `/reIndex` page, we simply go to
-`/edit/reIndex`
-
-There are a few pages where this is not possible, such as with the dashboard and
-other templated pages like 404's and 5xx's. That being said, you can still edit
-them by referencing their path on disk.
-
-You can create new pages that way too, the new page template is
-`tpl/new-template.md` if you wish to change what the defaults are.
-
-You'll also notice there's an `edit` button in the navbar, that's a little bit
-of Javascript trickery that you'll have to edit if you wish to change the
-template directory from `tpl` to anything else.
-
-Some useful edit links:
-
- * 4xx page [visit](/some/path/that/does/not/exist) [edit](/edit/tpl/4xx)
- * 5xx page [visit](/tpl/5xx) [edit](/edit/tpl/5xx)
- * New page template [visit](/tpl/new-template) [edit](/edit/tpl/new-template)
- * Edit page [visit](/tpl/edit) [edit](/edit/tpl/edit)
- * Login page [visit](/login) [edit](/edit/login)
- * Base template [edit](/edit/tpl/base)
-
-A note about the base template page, editing works, but viewing does not.
-
-Pages by tags:
-
-{{range $key, $val := .Index}}
-### {{$key}}:
-
-{{range $v2 := $val}}
- * {{$v2.Path}} [visit](/{{$v2.Path}}) [edit](/edit/{{$v2.Path}}){{end}}
-
-
-
-{{end}}
-
-
-It can also be a good idea to clear the cache on the dashboard page:
-
-```
-{{.Global.App.ClearCache}}
-```
-
-The element can be hidden, if you'd like.
-
-<script>
-/*
-window.addEventListener('load', (event) => {
- document.querySelector("#edit").remove();
-});
-*/
-</script>
-
diff --git a/example-site/tpl/edit.md b/example-site/tpl/edit.md
deleted file mode 100644
index 4e55f82..0000000
--- a/example-site/tpl/edit.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: Editing Page
-description: Editor
-|---
-
-<form action="/edit/{{.Vars.Page}}" method="POST">
-<br />
-<label for="content">Page content:</label><br />
-<br />
-
-
-<textarea id="content" name="content" rows="24" cols="80">
-{{.Vars.Content}}
-</textarea>
-
-<br />
-<input type="submit" value="save">
-</form>
-
-
-<!-- test -->
-
-<script>
-window.addEventListener('load', (event) => {
- document.querySelector("#edit").remove();
-});
-</script>
diff --git a/example-site/tpl/new-template.md b/example-site/tpl/new-template.md
deleted file mode 100644
index c4fdd95..0000000
--- a/example-site/tpl/new-template.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-# This is the contents of the `tpl/new-template.md` file. You're likely seeing
-# This because you've created a new page, or are trying to edit a page that
-# does not exist. To save yourself some confusion in the future, if you save
-# This page it may be helpful to delete this first paragraph, as it will no
-# longer be true.
-
-# This top section is YAML, this sets up a few of the variables for rendering
-# a web page. Below is also some markdown that's executed as a go template
-# for the page's content
-
-# You can edit this page by editing `tpl/new-template` If you changed the
-# template directory, take that into account.
-
-# Controls whether or not the page is published, this includes the
-# Atom/RSS feed
-published: false
-# What tags should be applied to this page?
-# The default index/home page shows a list of published blog pages
-tags:
- Blog:
-# This is the meta description, i.e. what you're going to seeing the little blurb
-# if you post the link to in say a discord chat. It's also what shows up in
-# Google and other search engines
-description: >-
- This is an example description. Note that the line starts with spaces, and
- not tabs.
-title: New page from `new-template`
-# Used for the RSS/Atom feed, you can also use it in the template below
-date: 09.11.2022 09:59:00 EDT
-
-# This line tells our server to stop parsing yaml and start processing
-# the rest of the text file as a markdown template
-|---
-
-{{/* This is a comment inside of the template */}}
-
-{{/*
- Print out the date, format information can be found here:
- https://pkg.go.dev/time#pkg-constants
-*/}}
-`{{.Date.Time.Format "Monday January 2 2006"}}`
-
-# {{.Title}}
-
-Some documentation on the templating language can be found [here](
-https://pkg.go.dev/text/template)
-
-
-A nice markdown reference can be found
-[here](https://www.markdownguide.org/basic-syntax/)
-
-
-Additionally <span style="color: red;">html tags</span> can be used in here as well.
-
diff --git a/page/page.go b/page/page.go
index 03d1f1e..b0fcfc7 100644
--- a/page/page.go
+++ b/page/page.go
@@ -284,15 +284,3 @@ func (p *Page) GetMarkdown() (string, error) {
func (p Page) String() string {
return fmt.Sprintf("Page: %s", p.path)
}
-
-// setRenderingMarkdownOnly simply sets the special vars field,
-// "RenderingMarkdownOnly" to be true.
-func (p *Page) setRenderingMarkdownOnly() {
- if p.Vars != nil {
- p.Vars["RenderingMarkdownOnly"] = true
- } else {
- p.Vars = map[string]interface{}{
- "RenderingMarkdownOnly": true,
- }
- }
-}
diff --git a/page/renderJson.go b/page/renderJson.go
deleted file mode 100644
index 4c03e12..0000000
--- a/page/renderJson.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package page
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "io/fs"
- "net/http"
-)
-
-// RenderJSON is analogous to Render, though it renders the page,
-// as a JSON key "content", optionally from the YAML it'll include
-// additional keys in the json if specified under the 'pageJson' key.
-// E.g.
-//
-// ---
-// title: Some page
-// description: Some page desc
-// jsonvars:
-// - includeMeInJSON
-// vars:
-// notIncluded: some value
-// includeMeInJSON:
-// some: arbitrary
-// data: to
-// send: down
-// |--
-// My page content, wee!
-func RenderJSON(w http.ResponseWriter, r *http.Request, //nolint:funlen
- path string, vars map[string]interface{}, statusCode int) {
- // Sepcifically use the specified path for the page
- p := NewPage(path)
-
- if vars != nil {
- p.Vars = vars
- }
-
- out := map[string]interface{}{}
- buf := &bytes.Buffer{}
-
- err := p.Render(buf)
- if err != nil {
- if errors.Is(err, fs.ErrNotExist) {
- renderJSONErr(w, "Not found", http.StatusNotFound)
-
- return
- }
-
- logErr(r, "rendering JSON encountered", err)
- renderJSONErr(w, "Internal server error",
- http.StatusInternalServerError)
-
- return
- }
-
- if r.URL.Query().Get("content") == "1" {
- out["Content"] = buf.String()
- }
-
- if r.URL.Query().Get("markdown") == "1" {
- p.setRenderingMarkdownOnly()
- // Tossing the error, since it would've been revealed above
- md, _ := p.GetMarkdown()
- out["Markdown"] = md
- }
-
- // Make a "set" of keys
- keys := map[string]struct{}{}
- for _, k := range p.JSONVars {
- keys[k] = struct{}{}
- }
-
- // And chuck the keys specified into the output
- for k, v := range p.Vars {
- _, ok := keys[k]
- if ok {
- out[k] = v
- }
- }
-
- w.WriteHeader(statusCode)
-
- enc := json.NewEncoder(w)
- enc.SetIndent("", " ")
- enc.SetEscapeHTML(false)
-
- err = enc.Encode(out)
- if err != nil {
- logErr(r, "while writing to buf", err)
-
- return
- }
-
- logReq(r, statusCode)
-}
-
-func renderJSONErr(w http.ResponseWriter, msg string, statusCode int) {
- enc := json.NewEncoder(w)
- w.WriteHeader(statusCode)
-
- _ = enc.Encode(&struct {
- StatusCode int
- Msg string
- }{
- StatusCode: statusCode,
- Msg: msg,
- })
-}
diff --git a/page/renderMarkdown.go b/page/renderMarkdown.go
deleted file mode 100644
index 8356e55..0000000
--- a/page/renderMarkdown.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package page
-
-import (
- "bytes"
- "errors"
- "io/fs"
- "net/http"
-)
-
-// RenderMarkdown is analogous to Render, except it spits out rendered markdown
-// as text/plain. It also sets .Vars.RenderingMarkdownOnly so templates can
-// vary on whether or not they're plain markdown. For instance, not including
-// some HTML tags.
-func RenderMarkdown(w http.ResponseWriter, r *http.Request,
- path string, vars map[string]interface{}, statusCode int) {
- // Sepcifically use the specified path for the page
- p := NewPage(path)
-
- if vars != nil {
- p.Vars = vars
- }
-
- if p.Vars != nil {
- p.Vars["RenderingMarkdownOnly"] = true
- } else {
- p.Vars = map[string]interface{}{
- "RenderingMarkdownOnly": true,
- }
- }
-
- buf := &bytes.Buffer{}
-
- err := p.Render(buf)
- if err != nil {
- if errors.Is(err, fs.ErrNotExist) {
- plainResp(w, http.StatusNotFound, "Not found")
-
- return
- }
-
- logErr(r, "while rendering", err)
- plainResp(w, http.StatusInternalServerError, "Internal server error")
-
- return
- }
-
- // Error was handled above
- md, _ := p.GetMarkdown()
-
- w.Header().Set("Content-type", "text/plain")
- w.WriteHeader(statusCode)
-
- _, err = w.Write([]byte(md))
- if err != nil {
- logErr(r, "while writing buf", err)
-
- return
- }
-
- logReq(r, statusCode)
-}