Add API Framework Revel Source Files
[iec.git] / src / foundation / api / revel / template_adapter_go.go
diff --git a/src/foundation/api/revel/template_adapter_go.go b/src/foundation/api/revel/template_adapter_go.go
new file mode 100644 (file)
index 0000000..4111307
--- /dev/null
@@ -0,0 +1,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)
+       }
+}