mirror of
https://github.com/caddyserver/caddy.git
synced 2025-02-24 23:57:05 -05:00
markdown: template integration done. awaiting documentation and test
This commit is contained in:
parent
0bfdb50ade
commit
ba613a1567
3 changed files with 93 additions and 10 deletions
|
@ -2,11 +2,12 @@ package setup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/mholt/caddy/middleware"
|
"github.com/mholt/caddy/middleware"
|
||||||
"github.com/mholt/caddy/middleware/markdown"
|
"github.com/mholt/caddy/middleware/markdown"
|
||||||
"github.com/russross/blackfriday"
|
"github.com/russross/blackfriday"
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Markdown configures a new Markdown middleware instance.
|
// Markdown configures a new Markdown middleware instance.
|
||||||
|
@ -37,6 +38,7 @@ func markdownParse(c *Controller) ([]markdown.Config, error) {
|
||||||
Renderer: blackfriday.HtmlRenderer(0, "", ""),
|
Renderer: blackfriday.HtmlRenderer(0, "", ""),
|
||||||
Templates: make(map[string]string),
|
Templates: make(map[string]string),
|
||||||
StaticFiles: make(map[string]string),
|
StaticFiles: make(map[string]string),
|
||||||
|
StaticDir: path.Join(c.Root, markdown.StaticDir),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the path scope
|
// Get the path scope
|
||||||
|
|
|
@ -31,6 +31,16 @@ type Markdown struct {
|
||||||
IndexFiles []string
|
IndexFiles []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to check if a file is an index file
|
||||||
|
func (m Markdown) IsIndexFile(file string) bool {
|
||||||
|
for _, f := range m.IndexFiles {
|
||||||
|
if f == file {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Config stores markdown middleware configurations.
|
// Config stores markdown middleware configurations.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Markdown renderer
|
// Markdown renderer
|
||||||
|
@ -53,6 +63,9 @@ type Config struct {
|
||||||
|
|
||||||
// Static files
|
// Static files
|
||||||
StaticFiles map[string]string
|
StaticFiles map[string]string
|
||||||
|
|
||||||
|
// Static files directory
|
||||||
|
StaticDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeHTTP implements the http.Handler interface.
|
// ServeHTTP implements the http.Handler interface.
|
||||||
|
@ -77,18 +90,37 @@ func (md Markdown) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
|
||||||
return http.StatusNotFound, nil
|
return http.StatusNotFound, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fs, err := f.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusNotFound, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// if static site is generated, attempt to use it
|
||||||
|
if filepath, ok := m.StaticFiles[fpath]; ok {
|
||||||
|
if fs1, err := os.Stat(filepath); err == nil {
|
||||||
|
// if markdown has not been modified
|
||||||
|
// since static page generation,
|
||||||
|
// serve the static page
|
||||||
|
if fs.ModTime().UnixNano() < fs1.ModTime().UnixNano() {
|
||||||
|
if html, err := ioutil.ReadFile(filepath); err == nil {
|
||||||
|
w.Write(html)
|
||||||
|
return http.StatusOK, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(f)
|
body, err := ioutil.ReadAll(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
html, err := Process(md, fpath, body)
|
html, err := md.process(m, fpath, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write([]byte(html))
|
w.Write(html)
|
||||||
|
|
||||||
return http.StatusOK, nil
|
return http.StatusOK, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,19 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/russross/blackfriday"
|
"github.com/russross/blackfriday"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Process the contents of a page.
|
const (
|
||||||
|
DefaultTemplate = "defaultTemplate"
|
||||||
|
StaticDir = ".caddy_static"
|
||||||
|
)
|
||||||
|
|
||||||
|
// process the contents of a page.
|
||||||
// It parses the metadata if any and uses the template if found
|
// It parses the metadata if any and uses the template if found
|
||||||
func Process(c Config, fpath string, b []byte) ([]byte, error) {
|
func (md Markdown) process(c Config, fpath string, b []byte) ([]byte, error) {
|
||||||
metadata, markdown, err := extractMetadata(b)
|
metadata, markdown, err := extractMetadata(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -42,7 +49,7 @@ func Process(c Config, fpath string, b []byte) ([]byte, error) {
|
||||||
// set it as body for template
|
// set it as body for template
|
||||||
metadata.Variables["body"] = string(markdown)
|
metadata.Variables["body"] = string(markdown)
|
||||||
|
|
||||||
return processTemplate(c, fpath, tmpl, metadata)
|
return md.processTemplate(c, fpath, tmpl, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
// extractMetadata extracts metadata content from a page.
|
// extractMetadata extracts metadata content from a page.
|
||||||
|
@ -104,7 +111,7 @@ func findParser(line []byte) MetadataParser {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func processTemplate(c Config, fpath string, tmpl []byte, metadata Metadata) ([]byte, error) {
|
func (md Markdown) processTemplate(c Config, fpath string, tmpl []byte, metadata Metadata) ([]byte, error) {
|
||||||
// if template is specified
|
// if template is specified
|
||||||
// replace parse the template
|
// replace parse the template
|
||||||
if tmpl != nil {
|
if tmpl != nil {
|
||||||
|
@ -119,6 +126,14 @@ func processTemplate(c Config, fpath string, tmpl []byte, metadata Metadata) ([]
|
||||||
if err = t.Execute(b, metadata.Variables); err != nil {
|
if err = t.Execute(b, metadata.Variables); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate static page
|
||||||
|
if err = md.generatePage(c, fpath, b.Bytes()); err != nil {
|
||||||
|
// if static page generation fails,
|
||||||
|
// nothing fatal, only log the error.
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
return b.Bytes(), nil
|
return b.Bytes(), nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -154,6 +169,42 @@ func defaultTemplate(c Config, metadata Metadata, fpath string) []byte {
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (md Markdown) generatePage(c Config, fpath string, content []byte) error {
|
||||||
|
// should not happen
|
||||||
|
// must be set on init
|
||||||
|
if c.StaticDir == "" {
|
||||||
|
return fmt.Errorf("Static directory not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := filepath.Join(c.StaticDir, fpath)
|
||||||
|
|
||||||
|
// If it is index file, use the directory instead
|
||||||
|
if md.IsIndexFile(filepath.Base(fpath)) {
|
||||||
|
filePath, _ = filepath.Split(filePath)
|
||||||
|
}
|
||||||
|
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[fpath] = filePath
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
htmlTemplate = `<!DOCTYPE html>
|
htmlTemplate = `<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
@ -169,6 +220,4 @@ const (
|
||||||
</html>`
|
</html>`
|
||||||
cssTemplate = `<link rel="stylesheet" href="{{url}}">`
|
cssTemplate = `<link rel="stylesheet" href="{{url}}">`
|
||||||
jsTemplate = `<script src="{{url}}"></script>`
|
jsTemplate = `<script src="{{url}}"></script>`
|
||||||
|
|
||||||
DefaultTemplate = "defaultTemplate"
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue