engine.go 2.3 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
  5. import (
  6. "bytes"
  7. "html/template"
  8. "time"
  9. "github.com/miniflux/miniflux/config"
  10. "github.com/miniflux/miniflux/errors"
  11. "github.com/miniflux/miniflux/locale"
  12. "github.com/miniflux/miniflux/logger"
  13. "github.com/gorilla/mux"
  14. )
  15. // Engine handles the templating system.
  16. type Engine struct {
  17. templates map[string]*template.Template
  18. translator *locale.Translator
  19. funcMap *funcMap
  20. }
  21. func (e *Engine) parseAll() {
  22. commonTemplates := ""
  23. for _, content := range templateCommonMap {
  24. commonTemplates += content
  25. }
  26. for name, content := range templateViewsMap {
  27. logger.Debug("[Template] Parsing: %s", name)
  28. e.templates[name] = template.Must(template.New("main").Funcs(e.funcMap.Map()).Parse(commonTemplates + content))
  29. }
  30. }
  31. // Render process a template and write the ouput.
  32. func (e *Engine) Render(name, language string, data interface{}) []byte {
  33. tpl, ok := e.templates[name]
  34. if !ok {
  35. logger.Fatal("[Template] The template %s does not exists", name)
  36. }
  37. lang := e.translator.GetLanguage(language)
  38. tpl.Funcs(template.FuncMap{
  39. "elapsed": func(timezone string, t time.Time) string {
  40. return elapsedTime(lang, timezone, t)
  41. },
  42. "t": func(key interface{}, args ...interface{}) string {
  43. switch key.(type) {
  44. case string:
  45. return lang.Get(key.(string), args...)
  46. case errors.LocalizedError:
  47. return key.(errors.LocalizedError).Localize(lang)
  48. case *errors.LocalizedError:
  49. return key.(*errors.LocalizedError).Localize(lang)
  50. case error:
  51. return key.(error).Error()
  52. default:
  53. return ""
  54. }
  55. },
  56. "plural": func(key string, n int, args ...interface{}) string {
  57. return lang.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, translator *locale.Translator) *Engine {
  69. tpl := &Engine{
  70. templates: make(map[string]*template.Template),
  71. translator: translator,
  72. funcMap: newFuncMap(cfg, router),
  73. }
  74. tpl.parseAll()
  75. return tpl
  76. }