Common isomorphic functionality in one kit.

templateset.go 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. // The Isomorphic Go Project
  2. // Copyright (c) Wirecog, LLC. All rights reserved.
  3. // Use of this source code is governed by a BSD-style
  4. // license, which can be found in the LICENSE file.
  5. package isokit
  6. import (
  7. "bytes"
  8. "encoding/gob"
  9. "errors"
  10. "html/template"
  11. "io/ioutil"
  12. "log"
  13. "os"
  14. "path/filepath"
  15. "strings"
  16. )
  17. var CogStaticAssetsSearchPaths []string
  18. type TemplateSet struct {
  19. members map[string]*Template
  20. Funcs template.FuncMap
  21. bundle *TemplateBundle
  22. TemplateFilesPath string
  23. bundleBuffer bytes.Buffer
  24. }
  25. func NewTemplateSet() *TemplateSet {
  26. return &TemplateSet{
  27. members: map[string]*Template{},
  28. Funcs: template.FuncMap{},
  29. }
  30. }
  31. func (t *TemplateSet) Members() map[string]*Template {
  32. return t.members
  33. }
  34. func (t *TemplateSet) Bundle() *TemplateBundle {
  35. return t.bundle
  36. }
  37. func (t *TemplateSet) AddTemplateFile(name, filename string, templateType int8) error {
  38. contents, err := ioutil.ReadFile(filename)
  39. if err != nil {
  40. return err
  41. }
  42. tpl, err := template.New(name).Funcs(t.Funcs).Parse(string(contents))
  43. template := Template{
  44. Template: tpl,
  45. templateType: templateType,
  46. }
  47. t.members[tpl.Name()] = &template
  48. return nil
  49. }
  50. func (t *TemplateSet) MakeAllAssociations() error {
  51. for _, template := range t.members {
  52. for _, member := range t.members {
  53. if member.Lookup(template.NameWithPrefix()) == nil {
  54. if _, err := member.AddParseTree(template.NameWithPrefix(), template.Tree); err != nil {
  55. println(err)
  56. return err
  57. }
  58. }
  59. }
  60. }
  61. return nil
  62. }
  63. func (t *TemplateSet) ImportTemplatesFromMap(templateMap map[string]string) error {
  64. for name, templateContents := range templateMap {
  65. var templateType int8
  66. if strings.Contains(name, PrefixNamePartial) {
  67. templateType = TemplatePartial
  68. } else if strings.Contains(name, PrefixNameLayout) {
  69. templateType = TemplateLayout
  70. } else {
  71. templateType = TemplateRegular
  72. }
  73. tpl, err := template.New(name).Funcs(t.Funcs).Parse(templateContents)
  74. if err != nil {
  75. log.Println("Encountered error when attempting to parse template: ", err)
  76. return err
  77. }
  78. tmpl := Template{
  79. Template: tpl,
  80. templateType: templateType,
  81. }
  82. t.members[name] = &tmpl
  83. }
  84. t.MakeAllAssociations()
  85. return nil
  86. }
  87. func (t *TemplateSet) Render(templateName string, params *RenderParams) {
  88. t.Members()[templateName].Render(params)
  89. }
  90. func (t *TemplateSet) PersistTemplateBundleToDisk() error {
  91. dirPath := filepath.Dir(StaticTemplateBundleFilePath)
  92. if _, err := os.Stat(dirPath); os.IsNotExist(err) {
  93. return errors.New("The specified directory for the StaticTemplateBundleFilePath, " + dirPath + ", does not exist!")
  94. } else {
  95. var templateContentItemsBuffer bytes.Buffer
  96. enc := gob.NewEncoder(&templateContentItemsBuffer)
  97. m := t.bundle.Items()
  98. err := enc.Encode(&m)
  99. if err != nil {
  100. return err
  101. }
  102. err = ioutil.WriteFile(StaticTemplateBundleFilePath, templateContentItemsBuffer.Bytes(), 0644)
  103. if err != nil {
  104. return err
  105. } else {
  106. return nil
  107. }
  108. }
  109. }
  110. func (t *TemplateSet) PersistTemplateBundleToTemplateSetBuffer() error {
  111. dirPath := filepath.Dir(StaticTemplateBundleFilePath)
  112. if _, err := os.Stat(dirPath); os.IsNotExist(err) {
  113. return errors.New("The specified directory for the StaticTemplateBundleFilePath, " + dirPath + ", does not exist!")
  114. } else {
  115. enc := gob.NewEncoder(&t.bundleBuffer)
  116. m := t.bundle.Items()
  117. err := enc.Encode(&m)
  118. if err != nil {
  119. return err
  120. } else {
  121. return nil
  122. }
  123. }
  124. }
  125. func (t *TemplateSet) RestoreTemplateBundleFromDisk() error {
  126. if _, err := os.Stat(StaticTemplateBundleFilePath); os.IsNotExist(err) {
  127. return errors.New("The StaticTemplateBundleFilePath, " + StaticTemplateBundleFilePath + ", does not exist")
  128. } else {
  129. data, err := ioutil.ReadFile(StaticTemplateBundleFilePath)
  130. if err != nil {
  131. return err
  132. }
  133. var templateBundleMap map[string]string
  134. var templateBundleMapBuffer bytes.Buffer
  135. dec := gob.NewDecoder(&templateBundleMapBuffer)
  136. templateBundleMapBuffer = *bytes.NewBuffer(data)
  137. err = dec.Decode(&templateBundleMap)
  138. if err != nil {
  139. return err
  140. }
  141. t.ImportTemplatesFromMap(templateBundleMap)
  142. bundle := &TemplateBundle{items: templateBundleMap}
  143. t.bundle = bundle
  144. return nil
  145. }
  146. }
  147. func (t *TemplateSet) RestoreTemplateBundleFromTemplateSetBuffer() error {
  148. if _, err := os.Stat(StaticTemplateBundleFilePath); os.IsNotExist(err) {
  149. return errors.New("The StaticTemplateBundleFilePath, " + StaticTemplateBundleFilePath + ", does not exist")
  150. } else {
  151. data := t.bundleBuffer.Bytes()
  152. if err != nil {
  153. return err
  154. }
  155. var templateBundleMap map[string]string
  156. var templateBundleMapBuffer bytes.Buffer
  157. dec := gob.NewDecoder(&templateBundleMapBuffer)
  158. templateBundleMapBuffer = *bytes.NewBuffer(data)
  159. err = dec.Decode(&templateBundleMap)
  160. if err != nil {
  161. return err
  162. }
  163. t.ImportTemplatesFromMap(templateBundleMap)
  164. bundle := &TemplateBundle{items: templateBundleMap}
  165. t.bundle = bundle
  166. return nil
  167. }
  168. }
  169. func (t *TemplateSet) GatherTemplates() {
  170. if UseStaticTemplateBundleFile == true {
  171. err := t.RestoreTemplateBundleFromDisk()
  172. if err != nil {
  173. log.Println("Didn't find a template bundle from disk, will generate a new template bundle.")
  174. } else {
  175. return
  176. }
  177. }
  178. if UseTemplateBundleFromBuffer == true && UseStaticTemplateBundleFile == false {
  179. err := t.RestoreTemplateBundleFromTemplateSetBuffer()
  180. if err != nil {
  181. log.Println("Didn't find a template bundle from the template set buffer, will generate a new template bundle.")
  182. } else {
  183. return
  184. }
  185. }
  186. bundle := NewTemplateBundle()
  187. templatesPath := t.TemplateFilesPath
  188. if templatesPath == "" {
  189. templatesPath = TemplateFilesPath
  190. }
  191. bundle.importTemplateFileContents(templatesPath)
  192. t.ImportTemplatesFromMap(bundle.Items())
  193. t.bundle = bundle
  194. if StaticTemplateBundleFilePath != "" {
  195. err := t.PersistTemplateBundleToDisk()
  196. if err != nil {
  197. log.Println("Failed to persist the template bundle to disk, in GatherTemplates, with error: ", err)
  198. }
  199. }
  200. if UseTemplateBundleFromBuffer == true && StaticTemplateBundleFilePath == "" {
  201. err := t.PersistTemplateBundleToTemplateSetBuffer()
  202. if err != nil {
  203. log.Println("Failed to persist the template bundle to disk, in GatherTemplates, with error: ", err)
  204. }
  205. }
  206. }
  207. func (t *TemplateSet) GatherCogTemplates(cogTemplatePath string, prefixName string, templateFileExtension string) {
  208. if ShouldBundleStaticAssets == false || UseStaticTemplateBundleFile == true {
  209. return
  210. }
  211. bundle := NewTemplateBundle()
  212. templatesPath := cogTemplatePath
  213. bundle.importTemplateFileContentsForCog(templatesPath, prefixName, templateFileExtension)
  214. t.ImportTemplatesFromMap(bundle.Items())
  215. for k, v := range bundle.Items() {
  216. t.bundle.items[k] = v
  217. }
  218. if StaticTemplateBundleFilePath != "" {
  219. err := t.PersistTemplateBundleToDisk()
  220. if err != nil {
  221. log.Println("Failed to persist the template bundle to disk, in GatherCogTemplates, with error: ", err)
  222. }
  223. }
  224. }
  225. func StaticTemplateBundleFileExists() bool {
  226. if _, err := os.Stat(StaticTemplateBundleFilePath); os.IsNotExist(err) {
  227. return false
  228. } else {
  229. return true
  230. }
  231. }
  232. func RegisterStaticAssetsSearchPath(path string) {
  233. //fmt.Println("cog search path: ", path)
  234. CogStaticAssetsSearchPaths = append(CogStaticAssetsSearchPaths, path)
  235. }