blog/pages.go

102 lines
2.5 KiB
Go
Raw Normal View History

package blog
2017-10-08 04:48:58 +00:00
import (
"html/template"
"io/ioutil"
2020-10-29 01:56:09 +00:00
"mime"
2017-10-08 04:48:58 +00:00
"net/http"
2020-10-29 01:56:09 +00:00
"path/filepath"
2017-10-08 04:48:58 +00:00
"strings"
2018-12-24 00:21:50 +00:00
"github.com/kirsle/blog/src/controllers/posts"
"github.com/kirsle/blog/src/log"
"github.com/kirsle/blog/src/markdown"
"github.com/kirsle/blog/src/render"
"github.com/kirsle/blog/src/responses"
2020-10-29 01:56:09 +00:00
"github.com/kirsle/blog/src/root"
2017-10-08 04:48:58 +00:00
)
// PageHandler is the catch-all route handler, for serving static web pages.
func (b *Blog) PageHandler(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
2017-12-23 02:34:58 +00:00
// log.Debug("Catch-all page handler invoked for request URI: %s", path)
2017-10-08 04:48:58 +00:00
// Remove trailing slashes by redirecting them away.
if len(path) > 1 && path[len(path)-1] == '/' {
responses.Redirect(w, strings.TrimRight(path, "/"))
return
}
// Restrict special paths.
if strings.HasPrefix(strings.ToLower(path), "/.") {
responses.Forbidden(w, r, "Forbidden")
2017-10-08 04:48:58 +00:00
return
}
// Search for a file that matches their URL.
2020-10-29 01:56:09 +00:00
fp, err := render.ResolvePath(path)
if err != nil {
// See if it resolves as a blog entry.
err = postctl.ViewPost(w, r, strings.TrimLeft(path, "/"))
if err != nil {
2018-02-10 23:16:30 +00:00
log.Error("Post by fragment %s not found: %s", path, err)
responses.NotFound(w, r, "The page you were looking for was not found.")
}
return
}
// Is it a template file?
2020-10-29 01:56:09 +00:00
if strings.HasSuffix(fp.URI, ".gohtml") {
render.Template(w, r, fp.URI, nil)
return
}
// Is it a Markdown file?
2020-10-29 01:56:09 +00:00
if strings.HasSuffix(fp.URI, ".md") || strings.HasSuffix(fp.URI, ".markdown") {
var source []byte
if len(fp.BindataKey) > 0 {
data, err := root.Asset(fp.BindataKey)
if err != nil {
responses.Error(w, r, "Couldn't read bindata key: "+fp.BindataKey)
return
}
source = data
} else {
data, err := ioutil.ReadFile(fp.Absolute)
if err != nil {
responses.Error(w, r, "Couldn't read Markdown source!")
return
}
source = data
}
// Render it to HTML and find out its title.
body := string(source)
html := markdown.RenderTrustedMarkdown(body)
title, _ := markdown.TitleFromMarkdown(body)
render.Template(w, r, ".markdown", map[string]interface{}{
2017-12-23 23:29:38 +00:00
"Title": title,
"HTML": template.HTML(html),
2020-10-29 01:56:09 +00:00
"MarkdownPath": fp.URI,
})
return
}
2020-10-29 01:56:09 +00:00
// It's a regular static file we can serve directly.
{
// Check if we have bindata for it.
if fp.BindataKey != "" {
data, _ := root.Asset(fp.BindataKey)
w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(fp.URI)))
w.Write(data)
return
}
// Try the filesystem.
http.ServeFile(w, r, fp.Absolute)
}
}