WIP Bindata stuff
This commit is contained in:
parent
445fffdf2b
commit
6a36c0ed76
8
Makefile
8
Makefile
|
@ -18,6 +18,14 @@ build:
|
|||
gofmt -w .
|
||||
go build $(LDFLAGS) -i -o bin/blog cmd/blog/main.go
|
||||
|
||||
# `make bindata` to make the bindata module.
|
||||
# `make bindata-dev` for debug mode module for editing files locally.
|
||||
.PHONY: bindata bindata-dev
|
||||
bindata:
|
||||
go-bindata -pkg root -prefix root/ -o src/root/bundle.go root/...
|
||||
bindata-dev:
|
||||
go-bindata -debug -pkg root -prefix root/ -o src/root/bundle.go root/...
|
||||
|
||||
# `make run` to run it in debug mode.
|
||||
.PHONY: run
|
||||
run:
|
||||
|
|
42
pages.go
42
pages.go
|
@ -3,7 +3,9 @@ package blog
|
|||
import (
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/kirsle/blog/src/controllers/posts"
|
||||
|
@ -11,6 +13,7 @@ import (
|
|||
"github.com/kirsle/blog/src/markdown"
|
||||
"github.com/kirsle/blog/src/render"
|
||||
"github.com/kirsle/blog/src/responses"
|
||||
"github.com/kirsle/blog/src/root"
|
||||
)
|
||||
|
||||
// PageHandler is the catch-all route handler, for serving static web pages.
|
||||
|
@ -31,7 +34,7 @@ func (b *Blog) PageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// Search for a file that matches their URL.
|
||||
filepath, err := render.ResolvePath(path)
|
||||
fp, err := render.ResolvePath(path)
|
||||
if err != nil {
|
||||
// See if it resolves as a blog entry.
|
||||
err = postctl.ViewPost(w, r, strings.TrimLeft(path, "/"))
|
||||
|
@ -43,19 +46,32 @@ func (b *Blog) PageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// Is it a template file?
|
||||
if strings.HasSuffix(filepath.URI, ".gohtml") {
|
||||
render.Template(w, r, filepath.URI, nil)
|
||||
if strings.HasSuffix(fp.URI, ".gohtml") {
|
||||
render.Template(w, r, fp.URI, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Is it a Markdown file?
|
||||
if strings.HasSuffix(filepath.URI, ".md") || strings.HasSuffix(filepath.URI, ".markdown") {
|
||||
source, err := ioutil.ReadFile(filepath.Absolute)
|
||||
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)
|
||||
|
@ -64,10 +80,22 @@ func (b *Blog) PageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
render.Template(w, r, ".markdown", map[string]interface{}{
|
||||
"Title": title,
|
||||
"HTML": template.HTML(html),
|
||||
"MarkdownPath": filepath.URI,
|
||||
"MarkdownPath": fp.URI,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
http.ServeFile(w, r, filepath.Absolute)
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,12 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/kirsle/blog/models/comments"
|
||||
"github.com/kirsle/blog/models/settings"
|
||||
"github.com/kirsle/blog/src/log"
|
||||
"github.com/kirsle/blog/src/markdown"
|
||||
"github.com/kirsle/blog/src/render"
|
||||
"github.com/kirsle/blog/models/comments"
|
||||
"github.com/kirsle/blog/models/settings"
|
||||
"github.com/kirsle/blog/src/root"
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
gomail "gopkg.in/gomail.v2"
|
||||
)
|
||||
|
@ -51,10 +52,21 @@ func SendEmail(email Email) {
|
|||
// Render the template to HTML.
|
||||
var html bytes.Buffer
|
||||
t := template.New(tmpl.Basename)
|
||||
t, err = template.ParseFiles(tmpl.Absolute)
|
||||
|
||||
// Load it from bindata or filesystem.
|
||||
if tmpl.BindataKey != "" {
|
||||
log.Debug("Parse %s from bindata", tmpl.BindataKey)
|
||||
asset, _ := root.Asset(tmpl.BindataKey)
|
||||
t, err = t.Parse(string(asset))
|
||||
} else {
|
||||
log.Debug("Parse %s from file", tmpl.Absolute)
|
||||
t, err = t.ParseFiles(tmpl.Absolute)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error("SendEmail: template parsing error: %s", err.Error())
|
||||
}
|
||||
|
||||
err = t.ExecuteTemplate(&html, tmpl.Basename, email)
|
||||
if err != nil {
|
||||
log.Error("SendEmail: template execution error: %s", err.Error())
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/kirsle/blog/src/log"
|
||||
"github.com/kirsle/blog/src/root"
|
||||
)
|
||||
|
||||
// Blog configuration bindings.
|
||||
|
@ -37,6 +38,10 @@ type Filepath struct {
|
|||
Basename string
|
||||
Relative string // Relative path including document root (i.e. "root/about.html")
|
||||
Absolute string // Absolute path on disk (i.e. "/opt/blog/root/about.html")
|
||||
|
||||
// If file was resolved to embedded bindata, this is the bindata key name.
|
||||
// Zero value means it resolved to a file on filesystem.
|
||||
BindataKey string
|
||||
}
|
||||
|
||||
func (f Filepath) String() string {
|
||||
|
@ -55,39 +60,78 @@ func ResolvePath(path string) (Filepath, error) {
|
|||
|
||||
// If you need to debug this function, edit this block.
|
||||
debug := func(tmpl string, args ...interface{}) {
|
||||
if false {
|
||||
if true { // edit this to enable
|
||||
log.Debug(tmpl, args...)
|
||||
}
|
||||
}
|
||||
|
||||
debug("Resolving filepath for URI: %s", path)
|
||||
for _, root := range []string{*UserRoot, *DocumentRoot} {
|
||||
if len(root) == 0 {
|
||||
continue
|
||||
}
|
||||
debug("ResolvePath(%s) called", path)
|
||||
|
||||
if len(*UserRoot) > 0 {
|
||||
debug("1. Resolving filepath for URI in user root: %s", path)
|
||||
|
||||
// Resolve the file path.
|
||||
relPath := filepath.Join(root, path)
|
||||
relPath := filepath.Join(*UserRoot, path)
|
||||
absPath, err := filepath.Abs(relPath)
|
||||
basename := filepath.Base(relPath)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
}
|
||||
|
||||
debug("Expected filepath: %s", absPath)
|
||||
debug(" Expected filepath: %s", absPath)
|
||||
|
||||
// Found an exact hit?
|
||||
if stat, err := os.Stat(absPath); !os.IsNotExist(err) && !stat.IsDir() {
|
||||
debug("Exact filepath found: %s", absPath)
|
||||
return Filepath{path, basename, relPath, absPath}, nil
|
||||
debug(" + Exact filepath found: %s", absPath)
|
||||
return Filepath{
|
||||
URI: path,
|
||||
Basename: basename,
|
||||
Relative: relPath,
|
||||
Absolute: absPath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Try some supported suffixes.
|
||||
for _, suffix := range hiddenSuffixes {
|
||||
test := absPath + suffix
|
||||
if stat, err := os.Stat(test); !os.IsNotExist(err) && !stat.IsDir() {
|
||||
debug("Filepath found via suffix %s: %s", suffix, test)
|
||||
return Filepath{path + suffix, basename + suffix, relPath + suffix, test}, nil
|
||||
debug(" + Filepath found via suffix %s: %s", suffix, test)
|
||||
return Filepath{
|
||||
URI: path + suffix,
|
||||
Basename: basename + suffix,
|
||||
Relative: relPath + suffix,
|
||||
Absolute: test,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug("2. Not found in filesystem, checking bindata for: %s", path)
|
||||
{
|
||||
// Exact hit?
|
||||
if _, err := root.Asset(path); err == nil {
|
||||
debug(" Found in bindata as: %s", path)
|
||||
return Filepath{
|
||||
URI: path,
|
||||
Basename: filepath.Base(path),
|
||||
Relative: path,
|
||||
Absolute: path,
|
||||
BindataKey: path,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Try some supported suffixes.
|
||||
for _, suffix := range hiddenSuffixes {
|
||||
test := path + suffix
|
||||
if _, err := root.Asset(test); err == nil {
|
||||
debug(" Filepath found via suffix %s: %s", suffix, test)
|
||||
return Filepath{
|
||||
URI: test,
|
||||
Basename: filepath.Base(test),
|
||||
Relative: test,
|
||||
Absolute: test,
|
||||
BindataKey: test,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ import (
|
|||
"time"
|
||||
|
||||
gorilla "github.com/gorilla/sessions"
|
||||
"github.com/kirsle/blog/models/settings"
|
||||
"github.com/kirsle/blog/models/users"
|
||||
"github.com/kirsle/blog/src/log"
|
||||
"github.com/kirsle/blog/src/middleware"
|
||||
"github.com/kirsle/blog/src/middleware/auth"
|
||||
"github.com/kirsle/blog/src/root"
|
||||
"github.com/kirsle/blog/src/sessions"
|
||||
"github.com/kirsle/blog/src/types"
|
||||
"github.com/kirsle/blog/models/settings"
|
||||
"github.com/kirsle/blog/models/users"
|
||||
)
|
||||
|
||||
// Vars is an interface to implement by the templates to pass their own custom
|
||||
|
@ -113,19 +114,19 @@ func Template(w io.Writer, r *http.Request, path string, data interface{}) error
|
|||
// Get the layout template.
|
||||
if !isPartial {
|
||||
templateName = "layout"
|
||||
layout, err = ResolvePath(".layout")
|
||||
layout, err = ResolvePath(".layout.gohtml")
|
||||
if err != nil {
|
||||
log.Error("RenderTemplate(%s): layout template not found", path)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
templateName = filepath.Basename
|
||||
templateName = filepath.Absolute
|
||||
}
|
||||
|
||||
// The comment entry partial.
|
||||
commentEntry, err := ResolvePath("comments/entry.partial")
|
||||
commentEntry, err := ResolvePath("comments/entry.partial.gohtml")
|
||||
if err != nil {
|
||||
log.Error("RenderTemplate(%s): comments/entry.partial not found")
|
||||
log.Error("RenderTemplate: comments/entry.partial not found")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -135,17 +136,28 @@ func Template(w io.Writer, r *http.Request, path string, data interface{}) error
|
|||
// and allows the filepath template to set the page title.
|
||||
var templates []string
|
||||
if !isPartial {
|
||||
templates = append(templates, layout.Absolute)
|
||||
templates = append(templates, layout.Absolute, commentEntry.Absolute, filepath.Absolute)
|
||||
}
|
||||
t, err = t.ParseFiles(append(templates, commentEntry.Absolute, filepath.Absolute)...)
|
||||
|
||||
for _, filename := range templates {
|
||||
|
||||
if asset, err2 := root.Asset(filename); err2 == nil {
|
||||
log.Debug("Parse %s from bindata", filename)
|
||||
t, err = t.Parse(string(asset))
|
||||
} else {
|
||||
log.Debug("Parse %s from file", filename)
|
||||
t, err = t.ParseFiles(filename)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = t.ExecuteTemplate(w, templateName, v)
|
||||
if err != nil {
|
||||
log.Error("Template parsing error: %s", err)
|
||||
log.Error("Template parsing error(tmpl name: %s; ): %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user