forked from birkirb/revel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
template_adapter_go.go
129 lines (115 loc) · 3.93 KB
/
template_adapter_go.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package revel
import (
"html/template"
"io"
"log"
"strings"
)
const GO_TEMPLATE = "go"
// Called on startup, initialized when the REVEL_BEFORE_MODULES_LOADED is called
func init() {
AddInitEventHandler(func(typeOf Event, value interface{}) (responseOf EventResponse) {
if typeOf == REVEL_BEFORE_MODULES_LOADED {
RegisterTemplateLoader(GO_TEMPLATE, func(loader *TemplateLoader) (TemplateEngine, error) {
// Set the template delimiters for the project if present, then split into left
// and right delimiters around a space character
TemplateDelims := Config.StringDefault("template.go.delimiters", "")
var splitDelims []string
if TemplateDelims != "" {
splitDelims = strings.Split(TemplateDelims, " ")
if len(splitDelims) != 2 {
log.Fatalln("app.conf: Incorrect format for template.delimiters")
}
}
return &GoEngine{
loader: loader,
templateSet: template.New("__root__").Funcs(TemplateFuncs),
templatesByName: map[string]*GoTemplate{},
splitDelims: splitDelims,
}, nil
})
}
return
})
}
// Adapter for Go Templates.
type GoTemplate struct {
*template.Template
engine *GoEngine
*TemplateView
}
// return a 'revel.Template' from Go's template.
func (gotmpl GoTemplate) Render(wr io.Writer, arg interface{}) error {
return gotmpl.Execute(wr, arg)
}
// The main template engine for Go
type GoEngine struct {
// The template loader
loader *TemplateLoader
// THe current template set
templateSet *template.Template
// A map of templates by name
templatesByName map[string]*GoTemplate
// The delimiter that is used to indicate template code, defaults to {{
splitDelims []string
// True if map is case insensitive
CaseInsensitive bool
}
// Convert the path to lower case if needed
func (i *GoEngine) ConvertPath(path string) string {
if i.CaseInsensitive {
return strings.ToLower(path)
}
return path
}
// Returns true if this engine can handle the response
func (i *GoEngine) Handles(templateView *TemplateView) bool {
return EngineHandles(i, templateView)
}
// Parses the template vide and adds it to the template set
func (engine *GoEngine) ParseAndAdd(baseTemplate *TemplateView) error {
// If alternate delimiters set for the project, change them for this set
if engine.splitDelims != nil && strings.Index(baseTemplate.Location(), ViewsPath) > -1 {
engine.templateSet.Delims(engine.splitDelims[0], engine.splitDelims[1])
} else {
// Reset to default otherwise
engine.templateSet.Delims("", "")
}
templateSource := string(baseTemplate.FileBytes)
templateName := engine.ConvertPath(baseTemplate.TemplateName)
tpl, err := engine.templateSet.New(baseTemplate.TemplateName).Parse(templateSource)
if nil != err {
_, line, description := ParseTemplateError(err)
return &Error{
Title: "Template Compilation Error",
Path: baseTemplate.TemplateName,
Description: description,
Line: line,
SourceLines: strings.Split(templateSource, "\n"),
}
}
engine.templatesByName[templateName] = &GoTemplate{Template: tpl, engine: engine, TemplateView: baseTemplate}
return nil
}
// Lookups the template name, to see if it is contained in this engine
func (engine *GoEngine) Lookup(templateName string) Template {
// Case-insensitive matching of template file name
if tpl, found := engine.templatesByName[engine.ConvertPath(templateName)]; found {
return tpl
}
return nil
}
// Return the engine name
func (engine *GoEngine) Name() string {
return GO_TEMPLATE
}
// An event listener to listen for Revel INIT events
func (engine *GoEngine) Event(action Event, i interface{}) {
if action == TEMPLATE_REFRESH_REQUESTED {
// At this point all the templates have been passed into the
engine.templatesByName = map[string]*GoTemplate{}
engine.templateSet = template.New("__root__").Funcs(TemplateFuncs)
// Check to see what should be used for case sensitivity
engine.CaseInsensitive = Config.BoolDefault("go.template.caseinsensitive", true)
}
}