mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-23 20:33:48 +08:00
markdown: sitegen keyword and run generation at startup
Also fixed bug for markdown files that don't contain front matter
This commit is contained in:
parent
a96c4d707b
commit
4272536518
|
@ -1,9 +1,12 @@
|
|||
package setup
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/mholt/caddy/middleware"
|
||||
"github.com/mholt/caddy/middleware/markdown"
|
||||
|
@ -24,6 +27,57 @@ func Markdown(c *Controller) (middleware.Middleware, error) {
|
|||
IndexFiles: []string{"index.md"},
|
||||
}
|
||||
|
||||
// For any configs that enabled static site gen, sweep the whole path at startup
|
||||
c.Startup = append(c.Startup, func() error {
|
||||
for _, cfg := range mdconfigs {
|
||||
if cfg.StaticDir == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// If generated site already exists, clear it out
|
||||
_, err := os.Stat(cfg.StaticDir)
|
||||
if err == nil {
|
||||
err := os.RemoveAll(cfg.StaticDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fp := filepath.Join(md.Root, cfg.PathScope)
|
||||
filepath.Walk(fp, func(path string, info os.FileInfo, err error) error {
|
||||
for _, ext := range cfg.Extensions {
|
||||
if !info.IsDir() && strings.HasSuffix(info.Name(), ext) {
|
||||
// Load the file
|
||||
body, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the relative path as if it were a HTTP request,
|
||||
// then prepend with "/" (like a real HTTP request)
|
||||
reqPath, err := filepath.Rel(md.Root, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reqPath = "/" + reqPath
|
||||
|
||||
// Generate the static file
|
||||
_, err = md.Process(cfg, reqPath, body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
break // don't try other file extensions
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return func(next middleware.Handler) middleware.Handler {
|
||||
md.Next = next
|
||||
return md
|
||||
|
@ -38,7 +92,6 @@ func markdownParse(c *Controller) ([]markdown.Config, error) {
|
|||
Renderer: blackfriday.HtmlRenderer(0, "", ""),
|
||||
Templates: make(map[string]string),
|
||||
StaticFiles: make(map[string]string),
|
||||
StaticDir: path.Join(c.Root, markdown.StaticDir),
|
||||
}
|
||||
|
||||
// Get the path scope
|
||||
|
@ -83,6 +136,16 @@ func markdownParse(c *Controller) ([]markdown.Config, error) {
|
|||
default:
|
||||
return mdconfigs, c.ArgErr()
|
||||
}
|
||||
case "sitegen":
|
||||
if c.NextArg() {
|
||||
md.StaticDir = path.Join(c.Root, c.Val())
|
||||
} else {
|
||||
md.StaticDir = path.Join(c.Root, markdown.DefaultStaticDir)
|
||||
}
|
||||
if c.NextArg() {
|
||||
// only 1 argument allowed
|
||||
return mdconfigs, c.ArgErr()
|
||||
}
|
||||
default:
|
||||
return mdconfigs, c.Err("Expected valid markdown configuration property")
|
||||
}
|
||||
|
|
|
@ -105,6 +105,11 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
|
|||
if html, err := ioutil.ReadFile(filepath); err == nil {
|
||||
w.Write(html)
|
||||
return http.StatusOK, nil
|
||||
} else {
|
||||
if os.IsPermission(err) {
|
||||
return http.StatusForbidden, err
|
||||
}
|
||||
return http.StatusNotFound, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +120,7 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
|
|||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
html, err := md.process(m, fpath, body)
|
||||
html, err := md.Process(m, fpath, body)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package markdown
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -14,13 +13,13 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
DefaultTemplate = "defaultTemplate"
|
||||
StaticDir = ".caddy_static"
|
||||
DefaultTemplate = "defaultTemplate"
|
||||
DefaultStaticDir = "generated_site"
|
||||
)
|
||||
|
||||
// process processes the contents of a page.
|
||||
// It parses the metadata (if any) and uses the template (if found)
|
||||
func (md Markdown) process(c Config, requestPath string, b []byte) ([]byte, error) {
|
||||
// Process processes the contents of a page in b. It parses the metadata
|
||||
// (if any) and uses the template (if found).
|
||||
func (md Markdown) Process(c Config, requestPath string, b []byte) ([]byte, error) {
|
||||
var metadata = Metadata{Variables: make(map[string]interface{})}
|
||||
var markdown []byte
|
||||
var err error
|
||||
|
@ -28,8 +27,11 @@ func (md Markdown) process(c Config, requestPath string, b []byte) ([]byte, erro
|
|||
// find parser compatible with page contents
|
||||
parser := findParser(b)
|
||||
|
||||
// if found, assume metadata present and parse.
|
||||
if parser != nil {
|
||||
if parser == nil {
|
||||
// if not found, assume whole file is markdown (no front matter)
|
||||
markdown = b
|
||||
} else {
|
||||
// if found, assume metadata present and parse.
|
||||
markdown, err = parser.Parse(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -74,7 +76,7 @@ func (md Markdown) processTemplate(c Config, requestPath string, tmpl []byte, me
|
|||
}
|
||||
|
||||
// process the template
|
||||
b := &bytes.Buffer{}
|
||||
b := new(bytes.Buffer)
|
||||
t, err := template.New("").Parse(string(tmpl))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -87,6 +89,7 @@ func (md Markdown) processTemplate(c Config, requestPath string, tmpl []byte, me
|
|||
if err = md.generatePage(c, requestPath, b.Bytes()); err != nil {
|
||||
// if static page generation fails,
|
||||
// nothing fatal, only log the error.
|
||||
// TODO: Report this non-fatal error, but don't log it here
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
|
@ -94,42 +97,41 @@ func (md Markdown) processTemplate(c Config, requestPath string, tmpl []byte, me
|
|||
|
||||
}
|
||||
|
||||
// generatePage generates a static html page from the markdown in content.
|
||||
// generatePage generates a static html page from the markdown in content if c.StaticDir
|
||||
// is a non-empty value, meaning that the user enabled static site generation.
|
||||
func (md Markdown) generatePage(c Config, requestPath string, content []byte) error {
|
||||
// should not happen,
|
||||
// must be set on Markdown init.
|
||||
if c.StaticDir == "" {
|
||||
return fmt.Errorf("Static directory not set")
|
||||
}
|
||||
// Only generate the page if static site generation is enabled
|
||||
if c.StaticDir != "" {
|
||||
// if static directory is not existing, create it
|
||||
if _, err := os.Stat(c.StaticDir); err != nil {
|
||||
err := os.MkdirAll(c.StaticDir, os.FileMode(0755))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// if static directory is not existing, create it
|
||||
if _, err := os.Stat(c.StaticDir); err != nil {
|
||||
err := os.MkdirAll(c.StaticDir, os.FileMode(0755))
|
||||
filePath := filepath.Join(c.StaticDir, requestPath)
|
||||
|
||||
// If it is index file, use the directory instead
|
||||
if md.IsIndexFile(filepath.Base(requestPath)) {
|
||||
filePath, _ = filepath.Split(filePath)
|
||||
}
|
||||
|
||||
// Create the directory in case it is not existing
|
||||
if err := os.MkdirAll(filePath, os.FileMode(0744)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// generate index.html file in the directory
|
||||
filePath = filepath.Join(filePath, "index.html")
|
||||
err := ioutil.WriteFile(filePath, content, os.FileMode(0664))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.StaticFiles[requestPath] = filePath
|
||||
}
|
||||
|
||||
filePath := filepath.Join(c.StaticDir, requestPath)
|
||||
|
||||
// If it is index file, use the directory instead
|
||||
if md.IsIndexFile(filepath.Base(requestPath)) {
|
||||
filePath, _ = filepath.Split(filePath)
|
||||
}
|
||||
|
||||
// Create the directory in case it is not existing
|
||||
if err := os.MkdirAll(filePath, os.FileMode(0755)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// generate index.html file in the directory
|
||||
filePath = filepath.Join(filePath, "index.html")
|
||||
err := ioutil.WriteFile(filePath, content, os.FileMode(0755))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.StaticFiles[requestPath] = filePath
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user