mirror of
https://github.com/caddyserver/caddy.git
synced 2025-02-24 16:59:00 +01:00
templates: Add custom template function registration (#4757)
* Add custom template function registration * Rename TemplateFunctions to CustomFunctions * Add documentation * Document CustomFunctions interface * Preallocate custom functions map list * Fix interface name in error message
This commit is contained in:
parent
4a223f5203
commit
e84e19a04e
2 changed files with 38 additions and 8 deletions
|
@ -21,6 +21,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
||||||
|
@ -36,6 +37,8 @@ func init() {
|
||||||
//
|
//
|
||||||
// ⚠️ Template functions/actions are still experimental, so they are subject to change.
|
// ⚠️ Template functions/actions are still experimental, so they are subject to change.
|
||||||
//
|
//
|
||||||
|
// Custom template functions can be registered by creating a plugin module under the `http.handlers.templates.functions.*` namespace that implements the `CustomFunctions` interface.
|
||||||
|
//
|
||||||
// [All Sprig functions](https://masterminds.github.io/sprig/) are supported.
|
// [All Sprig functions](https://masterminds.github.io/sprig/) are supported.
|
||||||
//
|
//
|
||||||
// In addition to the standard functions and the Sprig library, Caddy adds
|
// In addition to the standard functions and the Sprig library, Caddy adds
|
||||||
|
@ -249,6 +252,14 @@ type Templates struct {
|
||||||
// The template action delimiters. If set, must be precisely two elements:
|
// The template action delimiters. If set, must be precisely two elements:
|
||||||
// the opening and closing delimiters. Default: `["{{", "}}"]`
|
// the opening and closing delimiters. Default: `["{{", "}}"]`
|
||||||
Delimiters []string `json:"delimiters,omitempty"`
|
Delimiters []string `json:"delimiters,omitempty"`
|
||||||
|
|
||||||
|
customFuncs []template.FuncMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// Customfunctions is the interface for registering custom template functions.
|
||||||
|
type CustomFunctions interface {
|
||||||
|
// CustomTemplateFunctions should return the mapping from custom function names to implementations.
|
||||||
|
CustomTemplateFunctions() template.FuncMap
|
||||||
}
|
}
|
||||||
|
|
||||||
// CaddyModule returns the Caddy module information.
|
// CaddyModule returns the Caddy module information.
|
||||||
|
@ -261,6 +272,18 @@ func (Templates) CaddyModule() caddy.ModuleInfo {
|
||||||
|
|
||||||
// Provision provisions t.
|
// Provision provisions t.
|
||||||
func (t *Templates) Provision(ctx caddy.Context) error {
|
func (t *Templates) Provision(ctx caddy.Context) error {
|
||||||
|
fnModInfos := caddy.GetModules("http.handlers.templates.functions")
|
||||||
|
customFuncs := make([]template.FuncMap, len(fnModInfos), 0)
|
||||||
|
for _, modInfo := range fnModInfos {
|
||||||
|
mod := modInfo.New()
|
||||||
|
fnMod, ok := mod.(CustomFunctions)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("module %q does not satisfy the CustomFunctions interface", modInfo.ID)
|
||||||
|
}
|
||||||
|
customFuncs = append(customFuncs, fnMod.CustomTemplateFunctions())
|
||||||
|
}
|
||||||
|
t.customFuncs = customFuncs
|
||||||
|
|
||||||
if t.MIMETypes == nil {
|
if t.MIMETypes == nil {
|
||||||
t.MIMETypes = defaultMIMETypes
|
t.MIMETypes = defaultMIMETypes
|
||||||
}
|
}
|
||||||
|
@ -335,6 +358,7 @@ func (t *Templates) executeTemplate(rr caddyhttp.ResponseRecorder, r *http.Reque
|
||||||
Req: r,
|
Req: r,
|
||||||
RespHeader: WrappedHeader{rr.Header()},
|
RespHeader: WrappedHeader{rr.Header()},
|
||||||
config: t,
|
config: t,
|
||||||
|
CustomFuncs: t.customFuncs,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := ctx.executeTemplateInBuffer(r.URL.Path, rr.Buffer())
|
err := ctx.executeTemplateInBuffer(r.URL.Path, rr.Buffer())
|
||||||
|
|
|
@ -44,6 +44,7 @@ type TemplateContext struct {
|
||||||
Req *http.Request
|
Req *http.Request
|
||||||
Args []interface{} // defined by arguments to funcInclude
|
Args []interface{} // defined by arguments to funcInclude
|
||||||
RespHeader WrappedHeader
|
RespHeader WrappedHeader
|
||||||
|
CustomFuncs []template.FuncMap // functions added by plugins
|
||||||
|
|
||||||
config *Templates
|
config *Templates
|
||||||
tpl *template.Template
|
tpl *template.Template
|
||||||
|
@ -62,6 +63,11 @@ func (c *TemplateContext) NewTemplate(tplName string) *template.Template {
|
||||||
// add sprig library
|
// add sprig library
|
||||||
c.tpl.Funcs(sprigFuncMap)
|
c.tpl.Funcs(sprigFuncMap)
|
||||||
|
|
||||||
|
// add all custom functions
|
||||||
|
for _, funcMap := range c.CustomFuncs {
|
||||||
|
c.tpl.Funcs(funcMap)
|
||||||
|
}
|
||||||
|
|
||||||
// add our own library
|
// add our own library
|
||||||
c.tpl.Funcs(template.FuncMap{
|
c.tpl.Funcs(template.FuncMap{
|
||||||
"include": c.funcInclude,
|
"include": c.funcInclude,
|
||||||
|
|
Loading…
Reference in a new issue