Merge v1.2.1-master

Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
Emile Vauge 2017-04-11 17:10:46 +02:00
parent a590155b0b
commit aeb17182b4
No known key found for this signature in database
GPG key ID: D808B4C167352E59
396 changed files with 27271 additions and 9969 deletions

View file

@ -4,12 +4,14 @@ import (
"bytes"
"fmt"
"html/template"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"sync"
)
const (
@ -85,6 +87,8 @@ type Options struct {
RequireBlocks bool
// Disables automatic rendering of http.StatusInternalServerError when an error occurs. Default is false.
DisableHTTPErrorRendering bool
// Enables using partials without the current filename suffix which allows use of the same template in multiple files. e.g {{ partial "carosuel" }} inside the home template will match carosel-home or carosel.
RenderPartialsWithoutPrefix bool
}
// HTMLOptions is a struct for overriding some rendering Options for specific HTML call.
@ -99,6 +103,7 @@ type Render struct {
// Customize Secure with an Options struct.
opt Options
templates *template.Template
templatesLk sync.Mutex
compiledCharset string
}
@ -118,11 +123,6 @@ func New(options ...Options) *Render {
r.prepareOptions()
r.compileTemplates()
// Create a new buffer pool for writing templates into.
if bufPool == nil {
bufPool = NewBufferPool(64)
}
return &r
}
@ -270,6 +270,9 @@ func (r *Render) addLayoutFuncs(name string, binding interface{}) {
"block": func(partialName string) (template.HTML, error) {
log.Print("Render's `block` implementation is now depericated. Use `partial` as a drop in replacement.")
fullPartialName := fmt.Sprintf("%s-%s", partialName, name)
if r.TemplateLookup(fullPartialName) == nil && r.opt.RenderPartialsWithoutPrefix {
fullPartialName = partialName
}
if r.opt.RequireBlocks || r.TemplateLookup(fullPartialName) != nil {
buf, err := r.execute(fullPartialName, binding)
// Return safe HTML here since we are rendering our own template.
@ -279,6 +282,9 @@ func (r *Render) addLayoutFuncs(name string, binding interface{}) {
},
"partial": func(partialName string) (template.HTML, error) {
fullPartialName := fmt.Sprintf("%s-%s", partialName, name)
if r.TemplateLookup(fullPartialName) == nil && r.opt.RenderPartialsWithoutPrefix {
fullPartialName = partialName
}
if r.opt.RequirePartials || r.TemplateLookup(fullPartialName) != nil {
buf, err := r.execute(fullPartialName, binding)
// Return safe HTML here since we are rendering our own template.
@ -303,16 +309,16 @@ func (r *Render) prepareHTMLOptions(htmlOpt []HTMLOptions) HTMLOptions {
}
// Render is the generic function called by XML, JSON, Data, HTML, and can be called by custom implementations.
func (r *Render) Render(w http.ResponseWriter, e Engine, data interface{}) error {
func (r *Render) Render(w io.Writer, e Engine, data interface{}) error {
err := e.Render(w, data)
if err != nil && !r.opt.DisableHTTPErrorRendering {
http.Error(w, err.Error(), http.StatusInternalServerError)
if hw, ok := w.(http.ResponseWriter); err != nil && !r.opt.DisableHTTPErrorRendering && ok {
http.Error(hw, err.Error(), http.StatusInternalServerError)
}
return err
}
// Data writes out the raw bytes as binary data.
func (r *Render) Data(w http.ResponseWriter, status int, v []byte) error {
func (r *Render) Data(w io.Writer, status int, v []byte) error {
head := Head{
ContentType: ContentBinary,
Status: status,
@ -326,7 +332,10 @@ func (r *Render) Data(w http.ResponseWriter, status int, v []byte) error {
}
// HTML builds up the response from the specified template and bindings.
func (r *Render) HTML(w http.ResponseWriter, status int, name string, binding interface{}, htmlOpt ...HTMLOptions) error {
func (r *Render) HTML(w io.Writer, status int, name string, binding interface{}, htmlOpt ...HTMLOptions) error {
r.templatesLk.Lock()
defer r.templatesLk.Unlock()
// If we are in development mode, recompile the templates on every HTML request.
if r.opt.IsDevelopment {
r.compileTemplates()
@ -354,7 +363,7 @@ func (r *Render) HTML(w http.ResponseWriter, status int, name string, binding in
}
// JSON marshals the given interface object and writes the JSON response.
func (r *Render) JSON(w http.ResponseWriter, status int, v interface{}) error {
func (r *Render) JSON(w io.Writer, status int, v interface{}) error {
head := Head{
ContentType: ContentJSON + r.compiledCharset,
Status: status,
@ -372,7 +381,7 @@ func (r *Render) JSON(w http.ResponseWriter, status int, v interface{}) error {
}
// JSONP marshals the given interface object and writes the JSON response.
func (r *Render) JSONP(w http.ResponseWriter, status int, callback string, v interface{}) error {
func (r *Render) JSONP(w io.Writer, status int, callback string, v interface{}) error {
head := Head{
ContentType: ContentJSONP + r.compiledCharset,
Status: status,
@ -388,7 +397,7 @@ func (r *Render) JSONP(w http.ResponseWriter, status int, callback string, v int
}
// Text writes out a string as plain text.
func (r *Render) Text(w http.ResponseWriter, status int, v string) error {
func (r *Render) Text(w io.Writer, status int, v string) error {
head := Head{
ContentType: ContentText + r.compiledCharset,
Status: status,
@ -402,7 +411,7 @@ func (r *Render) Text(w http.ResponseWriter, status int, v string) error {
}
// XML marshals the given interface object and writes the XML response.
func (r *Render) XML(w http.ResponseWriter, status int, v interface{}) error {
func (r *Render) XML(w io.Writer, status int, v interface{}) error {
head := Head{
ContentType: ContentXML + r.compiledCharset,
Status: status,