mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
13e83fc57e
Former-commit-id: e8b0dde3cb3b72919f01b9d836d8ccb3d4e20214
139 lines
5.6 KiB
Go
139 lines
5.6 KiB
Go
// Package view is the adaptor of the 5 template engines
|
|
// as written by me at https://github.com/kataras/go-template
|
|
package view
|
|
|
|
import (
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/kataras/go-template"
|
|
"gopkg.in/kataras/iris.v6"
|
|
)
|
|
|
|
// Adaptor contains the common actions
|
|
// that all template engines share.
|
|
//
|
|
// We need to export that as it is without an interface
|
|
// because it may be used as a wrapper for a template engine
|
|
// that is not exists yet but community can create.
|
|
type Adaptor struct {
|
|
dir string
|
|
extension string
|
|
// for a .go template file lives inside the executable
|
|
assetFn func(name string) ([]byte, error)
|
|
namesFn func() []string
|
|
|
|
reload bool
|
|
|
|
engine template.Engine // used only on Adapt, we could make
|
|
//it as adaptEngine and pass a second parameter there but this would break the pattern.
|
|
}
|
|
|
|
// NewAdaptor returns a new general template engine policy adaptor.
|
|
func NewAdaptor(directory string, extension string, e template.Engine) *Adaptor {
|
|
return &Adaptor{
|
|
dir: directory,
|
|
extension: extension,
|
|
engine: e,
|
|
}
|
|
}
|
|
|
|
// Binary optionally, use it when template files are distributed
|
|
// inside the app executable (.go generated files).
|
|
func (h *Adaptor) Binary(assetFn func(name string) ([]byte, error), namesFn func() []string) *Adaptor {
|
|
h.assetFn = assetFn
|
|
h.namesFn = namesFn
|
|
return h
|
|
}
|
|
|
|
// Reload if setted to true the templates are reloading on each call,
|
|
// use it when you're in development and you're boring of restarting
|
|
// the whole app when you edit a template file
|
|
func (h *Adaptor) Reload(developmentMode bool) *Adaptor {
|
|
h.reload = developmentMode
|
|
return h
|
|
}
|
|
|
|
// Adapt adapts a template engine to the main Iris' policies.
|
|
// this specific Adapt is a multi-policies adaptors
|
|
// we use that instead of just return New() iris.RenderPolicy
|
|
// for two reasons:
|
|
// - the user may need to edit the adaptor's fields
|
|
// like Directory, Binary
|
|
// - we need to adapt an event policy to add the engine to the external mux
|
|
// and load it.
|
|
func (h *Adaptor) Adapt(frame *iris.Policies) {
|
|
mux := template.DefaultMux
|
|
// on the build state in order to have the shared funcs also
|
|
evt := iris.EventPolicy{
|
|
Build: func(s *iris.Framework) {
|
|
// mux has default to ./templates and .html ext
|
|
// no need for any checks here.
|
|
// the RenderPolicy will give a "no templates found on 'directory'"
|
|
// if user tries to use the context.Render without having the template files
|
|
// no need to panic here because we will use the html as the default template engine
|
|
// even if the user doesn't asks for
|
|
// or no? we had the defaults before... maybe better to give the user
|
|
// the oportunity to learn about the template's configuration
|
|
// (now 6.1.4 ) they are defaulted and users may don't know how and if they can change the configuration
|
|
// even if the book and examples covers these things, many times they're asking me on chat.............
|
|
// so no defaults? ok no defaults. This file then will be saved to /adaptors as with other template engines.
|
|
// simple.
|
|
mux.AddEngine(h.engine).
|
|
Directory(h.dir, h.extension).
|
|
Binary(h.assetFn, h.namesFn)
|
|
|
|
mux.Reload = h.reload
|
|
|
|
// notes for me: per-template engine funcs are setted by each template engine adaptor itself,
|
|
// here we will set the template funcs policy'.
|
|
// as I explain on the TemplateFuncsPolicy it exists in order to allow community to create plugins
|
|
// even by adding custom template funcs to their behaviors.
|
|
|
|
// We know that iris.TemplateFuncsPolicy is useless without this specific
|
|
// adaptor. We also know that it is not a good idea to have two
|
|
// policies with the same function or we can? wait. No we can't.
|
|
// We can't because:
|
|
// - the RenderPolicy should accept any type of render process, not only tempaltes.
|
|
// - I didn't design iris/policy.go to keep logic about implementation, this would make that very limited
|
|
// and I don't want to break that just for the templates.
|
|
// - We want community to be able to create packages which can adapt template functions but
|
|
// not to worry about the rest of the template engine adaptor policy.
|
|
// And even don't worry if the user has registered or use a template engine at all.
|
|
// So we should keep separate the TemplateFuncsPolicy(just map[string]interface{})
|
|
// from the rest of the implementation.
|
|
//
|
|
// So when the community wants to create a template adaptor has two options:
|
|
// - Use the RenderPolicy which is just a func
|
|
// - Use the kataras/iris/adaptors/view.Adaptor adaptor wrapper for RenderPolicy with a compination of kataras/go-template/.Engine
|
|
//
|
|
//
|
|
// So here is the only place we adapt the iris.TemplateFuncsPolicy to the tempaltes, if and only if templates are used,
|
|
// otherwise they are just ignored without any creepy things.
|
|
//
|
|
// The TemplateFuncsPolicy will work in compination with the specific template adaptor's functions(see html.go and the rest)
|
|
|
|
if len(frame.TemplateFuncsPolicy) > 0 {
|
|
mux.SetFuncMapToEngine(frame.TemplateFuncsPolicy, h.engine)
|
|
}
|
|
|
|
if err := mux.Load(); err != nil {
|
|
s.Log(iris.ProdMode, err.Error())
|
|
}
|
|
},
|
|
}
|
|
// adapt the build event to the main policies
|
|
evt.Adapt(frame)
|
|
|
|
r := iris.RenderPolicy(func(out io.Writer, file string, tmplContext interface{}, options ...map[string]interface{}) (error, bool) {
|
|
// template mux covers that but maybe we have more than one RenderPolicy
|
|
// and each of them carries a different mux on the new design.
|
|
if strings.Contains(file, h.extension) {
|
|
return mux.ExecuteWriter(out, file, tmplContext, options...), true
|
|
}
|
|
return nil, false
|
|
})
|
|
|
|
r.Adapt(frame)
|
|
}
|