all repos — honk @ 9c2d2289ff615b4b08a39c88b72b6cfc4863860a

my fork of honk

template.go (view raw)

 1//
 2// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
 3//
 4// Permission to use, copy, modify, and distribute this software for any
 5// purpose with or without fee is hereby granted, provided that the above
 6// copyright notice and this permission notice appear in all copies.
 7//
 8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16package main
17
18import (
19	"errors"
20	"html/template"
21	"io"
22	"log"
23)
24
25type Template struct {
26	names     []string
27	templates *template.Template
28	reload    bool
29}
30
31func mapmaker(values ...interface{}) (map[string]interface{}, error) {
32	if len(values)%2 != 0 {
33		return nil, errors.New("need arguments in pairs")
34	}
35	dict := make(map[string]interface{}, len(values)/2)
36	for i := 0; i < len(values); i += 2 {
37		key, ok := values[i].(string)
38		if !ok {
39			return nil, errors.New("key must be string")
40		}
41		dict[key] = values[i+1]
42	}
43	return dict, nil
44}
45
46func loadtemplates(filenames ...string) (*template.Template, error) {
47	templates := template.New("")
48	templates.Funcs(template.FuncMap{
49		"map": mapmaker,
50	})
51	templates, err := templates.ParseFiles(filenames...)
52	if err != nil {
53		return nil, err
54	}
55	return templates, nil
56}
57
58func (t *Template) ExecuteTemplate(w io.Writer, name string, data interface{}) error {
59	if t.reload {
60		templates, err := loadtemplates(t.names...)
61		if err != nil {
62			return err
63		}
64		return templates.ExecuteTemplate(w, name, data)
65	}
66	return t.templates.ExecuteTemplate(w, name, data)
67}
68
69func ParseTemplates(reload bool, filenames ...string) *Template {
70	t := new(Template)
71	t.names = filenames
72	t.reload = reload
73	templates, err := loadtemplates(filenames...)
74	if err != nil {
75		log.Panic(err)
76	}
77	if !reload {
78		t.templates = templates
79	}
80	return t
81}