mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	Merge pull request #696 from mholt/templateUtils
templates: Adding some useful utility functions
This commit is contained in:
		
						commit
						b3a5b725db
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user