functions.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2018 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. "net/mail"
  9. "strings"
  10. "time"
  11. "github.com/gorilla/mux"
  12. "github.com/miniflux/miniflux/config"
  13. "github.com/miniflux/miniflux/filter"
  14. "github.com/miniflux/miniflux/http/route"
  15. "github.com/miniflux/miniflux/model"
  16. "github.com/miniflux/miniflux/url"
  17. )
  18. type funcMap struct {
  19. cfg *config.Config
  20. router *mux.Router
  21. }
  22. func (f *funcMap) Map() template.FuncMap {
  23. return template.FuncMap{
  24. "baseURL": func() string {
  25. return f.cfg.BaseURL()
  26. },
  27. "rootURL": func() string {
  28. return f.cfg.RootURL()
  29. },
  30. "hasOAuth2Provider": func(provider string) bool {
  31. return f.cfg.OAuth2Provider() == provider
  32. },
  33. "hasKey": func(dict map[string]string, key string) bool {
  34. if value, found := dict[key]; found {
  35. return value != ""
  36. }
  37. return false
  38. },
  39. "route": func(name string, args ...interface{}) string {
  40. return route.Path(f.router, name, args...)
  41. },
  42. "noescape": func(str string) template.HTML {
  43. return template.HTML(str)
  44. },
  45. "proxyFilter": func(data string) string {
  46. return filter.ImageProxyFilter(f.router, f.cfg, data)
  47. },
  48. "proxyURL": func(link string) string {
  49. proxyImages := f.cfg.ProxyImages()
  50. if proxyImages == "all" || (proxyImages != "none" && !url.IsHTTPS(link)) {
  51. return filter.Proxify(f.router, link)
  52. }
  53. return link
  54. },
  55. "domain": func(websiteURL string) string {
  56. return url.Domain(websiteURL)
  57. },
  58. "isEmail": func(str string) bool {
  59. _, err := mail.ParseAddress(str)
  60. if err != nil {
  61. return false
  62. }
  63. return true
  64. },
  65. "hasPrefix": func(str, prefix string) bool {
  66. return strings.HasPrefix(str, prefix)
  67. },
  68. "contains": func(str, substr string) bool {
  69. return strings.Contains(str, substr)
  70. },
  71. "isodate": func(ts time.Time) string {
  72. return ts.Format("2006-01-02 15:04:05")
  73. },
  74. "dict": dict,
  75. "truncate": func(str string, max int) string {
  76. if len(str) > max {
  77. var buffer bytes.Buffer
  78. buffer.WriteString(str[:max-1])
  79. buffer.WriteString("…")
  80. return buffer.String()
  81. }
  82. return str
  83. },
  84. "theme_color": func(theme string) string {
  85. return model.ThemeColor(theme)
  86. },
  87. // These functions are overrided at runtime after the parsing.
  88. "elapsed": func(timezone string, t time.Time) string {
  89. return ""
  90. },
  91. "t": func(key interface{}, args ...interface{}) string {
  92. return ""
  93. },
  94. "plural": func(key string, n int, args ...interface{}) string {
  95. return ""
  96. },
  97. }
  98. }
  99. func newFuncMap(cfg *config.Config, router *mux.Router) *funcMap {
  100. return &funcMap{cfg, router}
  101. }