blocks.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package view
  2. import (
  3. "html/template"
  4. "io"
  5. "github.com/kataras/blocks"
  6. )
  7. // BlocksEngine is an Iris view engine adapter for the blocks view engine.
  8. // The blocks engine is based on the html/template standard Go package.
  9. //
  10. // To initialize a fresh one use the `Blocks` function.
  11. // To wrap an existing one use the `WrapBlocks` function.
  12. //
  13. // It contains the following four default template functions:
  14. // - url "routename" parameters...
  15. // - urlpath "routename" parameters...
  16. // - tr "language" "key" arguments...
  17. // - partial "template_name" data
  18. //
  19. // Read more at: https://github.com/kataras/blocks.
  20. type BlocksEngine struct {
  21. Engine *blocks.Blocks
  22. }
  23. var (
  24. _ Engine = (*BlocksEngine)(nil)
  25. _ EngineFuncer = (*BlocksEngine)(nil)
  26. )
  27. // WrapBlocks wraps an initialized blocks engine and returns its Iris adapter.
  28. // See `Blocks` package-level function too.
  29. func WrapBlocks(v *blocks.Blocks) *BlocksEngine {
  30. return &BlocksEngine{Engine: v}
  31. }
  32. // Blocks returns a new blocks view engine.
  33. // The given "extension" MUST begin with a dot.
  34. //
  35. // See `WrapBlocks` package-level function too.
  36. //
  37. // Usage:
  38. // Blocks("./views", ".html") or
  39. // Blocks(iris.Dir("./views"), ".html") or
  40. // Blocks(embed.FS, ".html") or Blocks(AssetFile(), ".html") for embedded data.
  41. func Blocks(fs interface{}, extension string) *BlocksEngine {
  42. return WrapBlocks(blocks.New(fs).Extension(extension))
  43. }
  44. // Name returns the blocks engine's name.
  45. func (s *BlocksEngine) Name() string {
  46. return "Blocks"
  47. }
  48. // RootDir sets the directory to use as the root one inside the provided File System.
  49. func (s *BlocksEngine) RootDir(root string) *BlocksEngine {
  50. s.Engine.RootDir(root)
  51. return s
  52. }
  53. // LayoutDir sets a custom layouts directory,
  54. // always relative to the "rootDir" one.
  55. // Layouts are recognised by their prefix names.
  56. // Defaults to "layouts".
  57. func (s *BlocksEngine) LayoutDir(relToDirLayoutDir string) *BlocksEngine {
  58. s.Engine.LayoutDir(relToDirLayoutDir)
  59. return s
  60. }
  61. // Ext returns empty ext as this template engine
  62. // supports template blocks without file suffix.
  63. // Note that, if more than one view engine is registered to a single
  64. // Iris application then, this Blocks engine should be the last entry one.
  65. func (s *BlocksEngine) Ext() string {
  66. return ""
  67. }
  68. // AddFunc implements the `EngineFuncer` which is being used
  69. // by the framework to add template functions like:
  70. // - url func(routeName string, args ...string) string
  71. // - urlpath func(routeName string, args ...string) string
  72. // - tr func(lang, key string, args ...interface{}) string
  73. func (s *BlocksEngine) AddFunc(funcName string, funcBody interface{}) {
  74. s.Engine.Funcs(template.FuncMap{funcName: funcBody})
  75. }
  76. // AddLayoutFunc adds a template function for templates that are marked as layouts.
  77. func (s *BlocksEngine) AddLayoutFunc(funcName string, funcBody interface{}) *BlocksEngine {
  78. s.Engine.LayoutFuncs(template.FuncMap{funcName: funcBody})
  79. return s
  80. }
  81. // Layout sets the default layout which inside should use
  82. // the {{ template "content" . }} to render the main template.
  83. //
  84. // Example for ./views/layouts/main.html:
  85. // Blocks("./views", ".html").Layout("layouts/main")
  86. func (s *BlocksEngine) Layout(layoutName string) *BlocksEngine {
  87. s.Engine.DefaultLayout(layoutName)
  88. return s
  89. }
  90. // Reload if called with a true parameter,
  91. // each `ExecuteWriter` call will re-parse the templates.
  92. // Useful when the application is at a development stage.
  93. func (s *BlocksEngine) Reload(b bool) *BlocksEngine {
  94. s.Engine.Reload(b)
  95. return s
  96. }
  97. // Load parses the files into templates.
  98. func (s *BlocksEngine) Load() error {
  99. return s.Engine.Load()
  100. }
  101. // ExecuteWriter renders a template on "w".
  102. func (s *BlocksEngine) ExecuteWriter(w io.Writer, tmplName, layoutName string, data interface{}) error {
  103. if layoutName == NoLayout {
  104. layoutName = ""
  105. }
  106. return s.Engine.ExecuteTemplate(w, tmplName, layoutName, data)
  107. }