mirror of
https://github.com/kataras/iris.git
synced 2025-01-24 19:21:03 +01:00
156 lines
3.3 KiB
Go
156 lines
3.3 KiB
Go
package markdown
|
|
|
|
import (
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
|
|
"fmt"
|
|
|
|
"github.com/kataras/iris/config"
|
|
"github.com/microcosm-cc/bluemonday"
|
|
"github.com/russross/blackfriday"
|
|
)
|
|
|
|
// Supports RAW markdown only, no context binding or layout, to use dynamic markdown with other template engine use the context.Markdown/MarkdownString
|
|
|
|
type (
|
|
// Engine the jade engine
|
|
Engine struct {
|
|
Config *config.Template
|
|
templateCache map[string][]byte
|
|
mu sync.Mutex
|
|
}
|
|
)
|
|
|
|
// New creates and returns a Pongo template engine
|
|
func New(c config.Template) *Engine {
|
|
return &Engine{Config: &c, templateCache: make(map[string][]byte)}
|
|
}
|
|
|
|
// BuildTemplates builds the templates
|
|
func (e *Engine) BuildTemplates() error {
|
|
if e.Config.Asset == nil || e.Config.AssetNames == nil {
|
|
return e.buildFromDir()
|
|
}
|
|
return e.buildFromAsset()
|
|
|
|
}
|
|
|
|
func (e *Engine) buildFromDir() (templateErr error) {
|
|
if e.Config.Directory == "" {
|
|
return nil //we don't return fill error here(yet)
|
|
}
|
|
dir := e.Config.Directory
|
|
|
|
// Walk the supplied directory and compile any files that match our extension list.
|
|
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
|
|
|
if info == nil || info.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
rel, err := filepath.Rel(dir, path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ext := ""
|
|
if strings.Index(rel, ".") != -1 {
|
|
ext = filepath.Ext(rel)
|
|
}
|
|
|
|
for _, extension := range e.Config.Extensions {
|
|
if ext == extension {
|
|
buf, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
templateErr = err
|
|
break
|
|
}
|
|
|
|
buf = blackfriday.MarkdownCommon(buf)
|
|
if e.Config.Markdown.Sanitize {
|
|
buf = bluemonday.UGCPolicy().SanitizeBytes(buf)
|
|
}
|
|
|
|
if err != nil {
|
|
templateErr = err
|
|
break
|
|
}
|
|
name := filepath.ToSlash(rel)
|
|
e.templateCache[name] = buf
|
|
break
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
func (e *Engine) buildFromAsset() error {
|
|
var templateErr error
|
|
dir := e.Config.Directory
|
|
for _, path := range e.Config.AssetNames() {
|
|
if !strings.HasPrefix(path, dir) {
|
|
continue
|
|
}
|
|
|
|
rel, err := filepath.Rel(dir, path)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
ext := ""
|
|
if strings.Index(rel, ".") != -1 {
|
|
ext = "." + strings.Join(strings.Split(rel, ".")[1:], ".")
|
|
}
|
|
|
|
for _, extension := range e.Config.Extensions {
|
|
if ext == extension {
|
|
|
|
buf, err := e.Config.Asset(path)
|
|
if err != nil {
|
|
templateErr = err
|
|
break
|
|
}
|
|
b := blackfriday.MarkdownCommon(buf)
|
|
if e.Config.Markdown.Sanitize {
|
|
b = bluemonday.UGCPolicy().SanitizeBytes(b)
|
|
}
|
|
name := filepath.ToSlash(rel)
|
|
e.templateCache[name] = b
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return templateErr
|
|
}
|
|
|
|
func (e *Engine) fromCache(relativeName string) []byte {
|
|
e.mu.Lock()
|
|
|
|
tmpl, ok := e.templateCache[relativeName]
|
|
|
|
if ok {
|
|
e.mu.Unlock() // defer is slow
|
|
return tmpl
|
|
}
|
|
e.mu.Unlock() // defer is slow
|
|
return nil
|
|
}
|
|
|
|
// ExecuteWriter executes a templates and write its results to the out writer
|
|
// layout here is useless
|
|
func (e *Engine) ExecuteWriter(out io.Writer, name string, binding interface{}, layout string) error {
|
|
if tmpl := e.fromCache(name); tmpl != nil {
|
|
_, err := out.Write(tmpl)
|
|
return err
|
|
}
|
|
|
|
return fmt.Errorf("[IRIS TEMPLATES] Template with name %s doesn't exists in the dir %s", name, e.Config.Directory)
|
|
}
|