engine.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2017 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package template // import "miniflux.app/template"
  5. import (
  6. "bytes"
  7. "html/template"
  8. "time"
  9. "miniflux.app/config"
  10. "miniflux.app/errors"
  11. "miniflux.app/locale"
  12. "miniflux.app/logger"
  13. "github.com/gorilla/mux"
  14. )
  15. // Engine handles the templating system.
  16. type Engine struct {
  17. templates map[string]*template.Template
  18. funcMap *funcMap
  19. }
  20. func (e *Engine) parseAll() {
  21. commonTemplates := ""
  22. for _, content := range templateCommonMap {
  23. commonTemplates += content
  24. }
  25. for name, content := range templateViewsMap {
  26. logger.Debug("[Template] Parsing: %s", name)
  27. e.templates[name] = template.Must(template.New("main").Funcs(e.funcMap.Map()).Parse(commonTemplates + content))
  28. }
  29. }
  30. // Render process a template.
  31. func (e *Engine) Render(name, language string, data interface{}) []byte {
  32. tpl, ok := e.templates[name]
  33. if !ok {
  34. logger.Fatal("[Template] The template %s does not exists", name)
  35. }
  36. printer := locale.NewPrinter(language)
  37. // Functions that need to be declared at runtime.
  38. tpl.Funcs(template.FuncMap{
  39. "elapsed": func(timezone string, t time.Time) string {
  40. return elapsedTime(printer, timezone, t)
  41. },
  42. "t": func(key interface{}, args ...interface{}) string {
  43. switch k := key.(type) {
  44. case string:
  45. return printer.Printf(k, args...)
  46. case errors.LocalizedError:
  47. return k.Localize(printer)
  48. case *errors.LocalizedError:
  49. return k.Localize(printer)
  50. case error:
  51. return k.Error()
  52. default:
  53. return ""
  54. }
  55. },
  56. "plural": func(key string, n int, args ...interface{}) string {
  57. return printer.Plural(key, n, args...)
  58. },
  59. })
  60. var b bytes.Buffer
  61. err := tpl.ExecuteTemplate(&b, "base", data)
  62. if err != nil {
  63. logger.Fatal("[Template] Unable to render template: %v", err)
  64. }
  65. return b.Bytes()
  66. }
  67. // NewEngine returns a new template engine.
  68. func NewEngine(cfg *config.Config, router *mux.Router) *Engine {
  69. tpl := &Engine{
  70. templates: make(map[string]*template.Template),
  71. funcMap: newFuncMap(cfg, router),
  72. }
  73. tpl.parseAll()
  74. return tpl
  75. }