template.lua 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. -- Copyright 2008 Steven Barth <steven@midlink.org>
  2. -- Copyright 2017-2018 Matthias Schiffer <mschiffer@universe-factory.net>
  3. -- Licensed to the public under the Apache License 2.0.
  4. local tparser = require "gluon.web.template.parser"
  5. local i18n = require "gluon.web.i18n"
  6. local util = require "gluon.web.util"
  7. local tostring, ipairs, setmetatable, setfenv = tostring, ipairs, setmetatable, setfenv
  8. local pcall, assert = pcall, assert
  9. module "gluon.web.template"
  10. local viewdir = util.libpath() .. "/view/"
  11. function renderer(env)
  12. local ctx = {}
  13. local language = 'en'
  14. local catalogs = {}
  15. function ctx.set_language(langs)
  16. for _, lang in ipairs(langs) do
  17. if i18n.supported(lang) then
  18. language = lang
  19. catalogs = {}
  20. return
  21. end
  22. end
  23. end
  24. function ctx.i18n(pkg)
  25. local cat = catalogs[pkg] or i18n.load(language, pkg)
  26. if pkg then catalogs[pkg] = cat end
  27. return cat
  28. end
  29. local function render_template(name, template, scope, pkg)
  30. scope = scope or {}
  31. local t = ctx.i18n(pkg)
  32. local locals = {
  33. renderer = ctx,
  34. i18n = ctx.i18n,
  35. translate = t.translate,
  36. translatef = t.translatef,
  37. _translate = t._translate,
  38. include = function(name)
  39. ctx.render(name, scope, pkg)
  40. end,
  41. }
  42. setfenv(template, setmetatable({}, {
  43. __index = function(tbl, key)
  44. return scope[key] or locals[key] or env[key]
  45. end
  46. }))
  47. -- Now finally render the thing
  48. local stat, err = pcall(template)
  49. assert(stat, "Failed to execute template '" .. name .. "'.\n" ..
  50. "A runtime error occured: " .. tostring(err or "(nil)"))
  51. end
  52. --- Render a certain template.
  53. -- @param name Template name
  54. -- @param scope Scope to assign to template (optional)
  55. function ctx.render(name, scope, pkg)
  56. local sourcefile = viewdir .. name .. ".html"
  57. local template, _, err = tparser.parse(sourcefile)
  58. assert(template, "Failed to load template '" .. name .. "'.\n" ..
  59. "Error while parsing template '" .. sourcefile .. "':\n" ..
  60. (err or "Unknown syntax error"))
  61. render_template(name, template, scope, pkg)
  62. end
  63. --- Render a template from a string.
  64. -- @param template Template string
  65. -- @param scope Scope to assign to template (optional)
  66. function ctx.render_string(str, scope, pkg)
  67. local template, _, err = tparser.parse_string(str)
  68. assert(template, "Error while parsing template:\n" ..
  69. (err or "Unknown syntax error"))
  70. render_template('(local)', template, scope, pkg)
  71. end
  72. return ctx
  73. end