mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
Adding some useful utility functions for templates
This commit is contained in:
parent
5989eb0635
commit
f28d8b8601
2 changed files with 69 additions and 0 deletions
|
@ -2,6 +2,7 @@ package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -219,3 +220,40 @@ func ContextInclude(filename string, ctx interface{}, fs http.FileSystem) (strin
|
||||||
|
|
||||||
return buf.String(), nil
|
return buf.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToLower will convert the given string to lower case.
|
||||||
|
func (c Context) ToLower(s string) string {
|
||||||
|
return strings.ToLower(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToUpper will convert the given string to upper case.
|
||||||
|
func (c Context) ToUpper(s string) string {
|
||||||
|
return strings.ToUpper(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split is a passthrough to strings.Split. It will split the first argument at each instance of the seperator and return a slice of strings.
|
||||||
|
func (c Context) Split(s string, sep string) []string {
|
||||||
|
return strings.Split(s, sep)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slice will convert the given arguments into a slice.
|
||||||
|
func (c Context) Slice(elems ...interface{}) []interface{} {
|
||||||
|
return elems
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map will convert the arguments into a map. It expects alternating string keys and values. This is useful for building more complicated data structures
|
||||||
|
// if you are using subtemplates or things like that.
|
||||||
|
func (c Context) Map(values ...interface{}) (map[string]interface{}, error) {
|
||||||
|
if len(values)%2 != 0 {
|
||||||
|
return nil, fmt.Errorf("Map expects an even number of arguments")
|
||||||
|
}
|
||||||
|
dict := make(map[string]interface{}, len(values)/2)
|
||||||
|
for i := 0; i < len(values); i += 2 {
|
||||||
|
key, ok := values[i].(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("Map keys must be strings")
|
||||||
|
}
|
||||||
|
dict[key] = values[i+1]
|
||||||
|
}
|
||||||
|
return dict, nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInclude(t *testing.T) {
|
func TestInclude(t *testing.T) {
|
||||||
|
@ -611,3 +613,32 @@ func getContextOrFail(t *testing.T) Context {
|
||||||
func getTestPrefix(testN int) string {
|
func getTestPrefix(testN int) string {
|
||||||
return fmt.Sprintf("Test [%d]: ", testN)
|
return fmt.Sprintf("Test [%d]: ", testN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTemplates(t *testing.T) {
|
||||||
|
tests := []struct{ tmpl, expected string }{
|
||||||
|
{`{{.ToUpper "aAA"}}`, "AAA"},
|
||||||
|
{`{{"bbb" | .ToUpper}}`, "BBB"},
|
||||||
|
{`{{.ToLower "CCc"}}`, "ccc"},
|
||||||
|
{`{{range (.Split "a,b,c" ",")}}{{.}}{{end}}`, "abc"},
|
||||||
|
{`{{range .Split "a,b,c" ","}}{{.}}{{end}}`, "abc"},
|
||||||
|
{`{{range .Slice "a" "b" "c"}}{{.}}{{end}}`, "abc"},
|
||||||
|
{`{{with .Map "A" "a" "B" "b" "c" "d"}}{{.A}}{{.B}}{{.c}}{{end}}`, "abd"},
|
||||||
|
}
|
||||||
|
for i, test := range tests {
|
||||||
|
ctx := getContextOrFail(t)
|
||||||
|
tmpl, err := template.New("").Parse(test.tmpl)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Test %d: %s", i, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err = tmpl.Execute(buf, ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Test %d: %s", i, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if buf.String() != test.expected {
|
||||||
|
t.Errorf("Test %d: Results do not match. '%s' != '%s'", i, buf.String(), test.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue