Skip to content

Commit

Permalink
Merge pull request #22 from Fenny/master
Browse files Browse the repository at this point in the history
Bump dependencies
  • Loading branch information
Fenny authored Jun 28, 2020
2 parents 18838e8 + fad4629 commit 464e5bf
Show file tree
Hide file tree
Showing 10 changed files with 345 additions and 19 deletions.
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ require (
github.com/aymerick/raymond v2.0.2+incompatible
github.com/cbroglie/mustache v1.1.0
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385
github.com/flosch/pongo2 v0.0.0-20200518135938-dfb43dbdc22a
github.com/mattn/go-slim v0.0.0-20190926010428-236f1c35e4e6
github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915
github.com/mattn/go-slim v0.0.0-20200618151855-bde33eecb5ee
github.com/valyala/bytebufferpool v1.0.0
github.com/yosssi/ace v0.0.5
gopkg.in/yaml.v2 v2.3.0 // indirect
)
22 changes: 6 additions & 16 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet v2.1.2+incompatible h1:ybZoYzMBdoijK6I+Ke3vg9GZsmlKo/ZhKdNMWz0P26c=
github.com/CloudyKit/jet v2.1.2+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w=
github.com/CloudyKit/jet/v3 v3.0.0 h1:1PwO5w5VCtlUUl+KTOBsTGZlhjWkcybsGaAau52tOy8=
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
github.com/Joker/hpp v0.0.0-20180418125244-6893e659854a h1:PiDAizhfJbwZMISZ1Itx1ZTFeOFCml89Ofmz3V8rhoU=
Expand All @@ -23,28 +21,22 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/flosch/pongo2 v0.0.0-20200518135938-dfb43dbdc22a h1:8Dw1FO25BORXdlipopkXixOKPe3qjfqfxUOb327zP48=
github.com/flosch/pongo2 v0.0.0-20200518135938-dfb43dbdc22a/go.mod h1:StS3bHLP8nf6A+gzLIW2rrGeSCZrS0DMNTrIEEPRHz0=
github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915 h1:rNVrewdFbSujcoKZifC6cHJfqCTbCIR7XTLHW5TqUWU=
github.com/flosch/pongo2 v0.0.0-20200529170236-5abacdfa4915/go.mod h1:fB4mx6dzqFinCxIf3a7Mf5yLk+18Bia9mPAnuejcvDA=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 h1:rhqTjzJlm7EbkELJDKMTU7udov+Se0xZkWmugr6zGok=
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20180524022052-584905176618 h1:MK144iBQF9hTSwBW/9eJm034bVoG30IshVm688T2hi8=
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073 h1:WQM1NildKThwdP7qWrNAFGzp4ijNLw8RlgENkaI4MJs=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-slim v0.0.0-20190926010428-236f1c35e4e6 h1:GF43XHtQ/ewS07mITQZyi9gXhWZ7x7crGWp2hvHUEkM=
github.com/mattn/go-slim v0.0.0-20190926010428-236f1c35e4e6/go.mod h1:ma9TUJeni8LGZMJvOwbAv/FOwiwqIMQN570LnpqCBSM=
github.com/mattn/go-slim v0.0.0-20200618151855-bde33eecb5ee h1:M3l0/LNEemy7ykM6qCZylkWmFPyvDLDCl7bZPLTfaBQ=
github.com/mattn/go-slim v0.0.0-20200618151855-bde33eecb5ee/go.mod h1:ma9TUJeni8LGZMJvOwbAv/FOwiwqIMQN570LnpqCBSM=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
Expand All @@ -66,6 +58,7 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA=
github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
Expand All @@ -84,9 +77,6 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
205 changes: 205 additions & 0 deletions slim/slim.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package slim

import (
"bytes"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"sync"

"github.com/gofiber/template/utils"
"github.com/mattn/go-slim"
"github.com/valyala/bytebufferpool"
)

// Engine struct
type Engine struct {
// delimiters
left string
right string
// views folder
directory string
// http.FileSystem supports embedded files
fileSystem http.FileSystem
// views extension
extension string
// layout variable name that incapsulates the template
layout string
// reload on each render
reload bool
// debug prints the parsed templates
debug bool
// lock for funcmap and templates
mutex sync.RWMutex
// template funcmap
funcmap map[string]interface{}
// templates
Templates map[string]*slim.Template
}

// New returns a Handlebar render engine for Fiber
func New(directory, extension string) *Engine {
engine := &Engine{
left: "{{",
right: "}}",
directory: directory,
extension: extension,
layout: "embed",
funcmap: make(map[string]interface{}),
}
return engine
}

func NewFileSystem(fs http.FileSystem, extension string) *Engine {
engine := &Engine{
left: "{{",
right: "}}",
directory: "/",
fileSystem: fs,
extension: extension,
layout: "embed",
funcmap: make(map[string]interface{}),
}
return engine
}

// Layout defines the variable name that will incapsulate the template
func (e *Engine) Layout(key string) *Engine {
e.layout = key
return e
}

// Delims sets the action delimiters to the specified strings, to be used in
// templates. An empty delimiter stands for the
// corresponding default: {{ or }}.
func (e *Engine) Delims(left, right string) *Engine {
fmt.Println("delims: this method is not supported for django")
return e
}

// AddFunc adds the function to the template's function map.
// It is legal to overwrite elements of the default actions
func (e *Engine) AddFunc(name string, fn interface{}) *Engine {
e.mutex.Lock()
e.funcmap[name] = fn
e.mutex.Unlock()
return e
}

// Reload if set to true the templates are reloading on each render,
// use it when you're in development and you don't want to restart
// the application when you edit a template file.
func (e *Engine) Reload(enabled bool) *Engine {
e.reload = enabled
return e
}

// Debug will print the parsed templates when Load is triggered.
func (e *Engine) Debug(enabled bool) *Engine {
e.debug = enabled
return e
}

// Parse is deprecated, please use Load() instead
func (e *Engine) Parse() error {
fmt.Println("Parse() is deprecated, please use Load() instead.")
return e.Load()
}

// Load parses the templates to the engine.
func (e *Engine) Load() error {
// race safe
e.mutex.Lock()
defer e.mutex.Unlock()

e.Templates = make(map[string]*slim.Template)

// Loop trough each directory and register template files
walkFn := func(path string, info os.FileInfo, err error) error {
// Return error if exist
if err != nil {
return err
}
// Skip file if it's a directory or has no file info
if info == nil || info.IsDir() {
return nil
}
// Get file extension of file
ext := filepath.Ext(path)
// Skip file if it does not equal the given template extension
if ext != e.extension {
return nil
}
// Get the relative file path
// ./views/html/index.tmpl -> index.tmpl
rel, err := filepath.Rel(e.directory, path)
if err != nil {
return err
}
// Reverse slashes '\' -> '/' and
// partials\footer.tmpl -> partials/footer.tmpl
name := filepath.ToSlash(rel)
// Remove ext from name 'index.tmpl' -> 'index'
name = strings.Replace(name, e.extension, "", -1)
// Read the file
// #gosec G304
buf, err := utils.ReadFile(path, e.fileSystem)
if err != nil {
return err
}
// Create new template associated with the current one
tmpl, err := slim.Parse(bytes.NewReader(buf))
if err != nil {
return err
}
// tmpl.FuncMap(e.funcmap)
e.Templates[name] = tmpl
// Debugging
if e.debug {
fmt.Printf("views: parsed template: %s\n", name)
}
return err
}
if e.fileSystem != nil {
return utils.Walk(e.fileSystem, e.directory, walkFn)
}
return filepath.Walk(e.directory, walkFn)
}

// Execute will render the template by name
func (e *Engine) Render(out io.Writer, template string, binding interface{}, layout ...string) error {
if e.reload {
if err := e.Load(); err != nil {
return err
}
}
tmpl := e.Templates[template]
if tmpl == nil {
return fmt.Errorf("render: template %s does not exist", template)
}
if len(layout) > 0 {
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
if err := tmpl.Execute(buf, binding); err != nil {
return err
}
var bind map[string]interface{}
if bind == nil {
bind = make(map[string]interface{}, 1)
} else if context, ok := binding.(map[string]interface{}); ok {
bind = context
} else {
bind = make(map[string]interface{}, 1)
}
bind[e.layout] = buf.String()
lay := e.Templates[layout[0]]
if lay == nil {
return fmt.Errorf("render: layout %s does not exist", layout[0])
}
return lay.Execute(out, bind)
}
return tmpl.Execute(out, binding)
}
119 changes: 119 additions & 0 deletions slim/slim_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package slim

// import (
// "bytes"
// "io/ioutil"
// "net/http"
// "regexp"
// "strings"
// "testing"
// )

// func trim(str string) string {
// trimmed := strings.TrimSpace(regexp.MustCompile(`\s+`).ReplaceAllString(str, " "))
// trimmed = strings.Replace(trimmed, " <", "<", -1)
// trimmed = strings.Replace(trimmed, "> ", ">", -1)
// return trimmed
// }

// func Test_Render(t *testing.T) {
// engine := New("./views", ".slim").Debug(true)
// if err := engine.Load(); err != nil {
// t.Fatalf("load: %v\n", err)
// }
// // Partials
// var buf bytes.Buffer
// if err := engine.Render(&buf, "index", map[string]interface{}{
// "Title": "Hello, World!",
// }); err != nil {
// t.Fatalf("render: %v\n", err)
// }
// expect := `<h2>Header</h2><h1>Hello, World!</h1><h2>Footer</h2>`
// result := trim(buf.String())
// if expect != result {
// t.Fatalf("Expected:\n%s\nResult:\n%s\n", expect, result)
// }
// // Single
// buf.Reset()
// engine.Render(&buf, "errors/404", map[string]interface{}{
// "title": "Hello, World!",
// })
// expect = `<h1>Hello, World!</h1>`
// result = trim(buf.String())
// if expect != result {
// t.Fatalf("Expected:\n%s\nResult:\n%s\n", expect, result)
// }
// }

// func Test_Layout(t *testing.T) {
// engine := New("./views", ".slim")
// engine.Debug(true)
// if err := engine.Load(); err != nil {
// t.Fatalf("load: %v\n", err)
// }

// var buf bytes.Buffer
// err := engine.Render(&buf, "index", map[string]interface{}{
// "Title": "Hello, World!",
// }, "layouts/main")
// if err != nil {
// t.Fatalf("render: %v", err)
// }
// expect := `<!DOCTYPE html><html><head><title>Main</title></head><body><h2>Header</h2><h1>Hello, World!</h1><h2>Footer</h2></body></html>`
// result := trim(buf.String())
// if expect != result {
// t.Fatalf("Expected:\n%s\nResult:\n%s\n", expect, result)
// }
// }

// func Test_FileSystem(t *testing.T) {
// engine := NewFileSystem(http.Dir("./views"), ".slim")
// engine.Debug(true)
// if err := engine.Load(); err != nil {
// t.Fatalf("load: %v\n", err)
// }

// var buf bytes.Buffer
// err := engine.Render(&buf, "index", map[string]interface{}{
// "Title": "Hello, World!",
// }, "layouts/main")
// if err != nil {
// t.Fatalf("render: %v", err)
// }
// expect := `<!DOCTYPE html><html><head><title>Main</title></head><body><h2>Header</h2><h1>Hello, World!</h1><h2>Footer</h2></body></html>`
// result := trim(buf.String())
// if expect != result {
// t.Fatalf("Expected:\n%s\nResult:\n%s\n", expect, result)
// }
// }

// func Test_Reload(t *testing.T) {
// engine := NewFileSystem(http.Dir("./views"), ".ace")
// engine.Reload(true) // Optional. Default: false

// engine.AddFunc("isAdmin", func(user string) bool {
// return user == "admin"
// })
// if err := engine.Load(); err != nil {
// t.Fatalf("load: %v\n", err)
// }

// if err := ioutil.WriteFile("./views/reload.ace", []byte("after reload\n"), 0644); err != nil {
// t.Fatalf("write file: %v\n", err)
// }
// defer func() {
// if err := ioutil.WriteFile("./views/reload.ace", []byte("before reload\n"), 0644); err != nil {
// t.Fatalf("write file: %v\n", err)
// }
// }()

// engine.Load()

// var buf bytes.Buffer
// engine.Render(&buf, "reload", nil)
// expect := "<after>reload</after>"
// result := trim(buf.String())
// if expect != result {
// t.Fatalf("Expected:\n%s\nResult:\n%s\n", expect, result)
// }
// }
Loading

0 comments on commit 464e5bf

Please sign in to comment.