-- Copyright 2008 Steven Barth -- Copyright 2017-2018 Matthias Schiffer -- Licensed to the public under the Apache License 2.0. local tparser = require 'gluon.web.template.parser' local tostring, ipairs, setmetatable, setfenv = tostring, ipairs, setmetatable, setfenv local pcall, assert = pcall, assert return function(config, env) local i18n = require('gluon.web.i18n')(config) local viewdir = config.base_path .. '/view/' local ctx = {} local language = 'en' local catalogs = {} function ctx.set_language(langs) for _, lang in ipairs(langs) do if i18n.supported(lang) then language = lang catalogs = {} return end end end function ctx.i18n(pkg) local cat = catalogs[pkg] or i18n.load(language, pkg) if pkg then catalogs[pkg] = cat end return cat end local function render_template(name, template, scope, pkg) scope = scope or {} local t = ctx.i18n(pkg) local locals = { renderer = ctx, i18n = ctx.i18n, translate = t.translate, translatef = t.translatef, _translate = t._translate, include = function(include_name) ctx.render(include_name, scope, pkg) end, } setfenv(template, setmetatable({}, { __index = function(_, key) return scope[key] or locals[key] or env[key] end })) -- Now finally render the thing local stat, err = pcall(template) assert(stat, "Failed to execute template '" .. name .. "'.\n" .. "A runtime error occurred: " .. tostring(err or "(nil)")) end --- Render a certain template. -- @param name Template name -- @param scope Scope to assign to template (optional) -- @param pkg i18n namespace package (optional) function ctx.render(name, scope, pkg) local sourcefile = viewdir .. name .. ".html" local template, _, err = tparser.parse(sourcefile) assert(template, "Failed to load template '" .. name .. "'.\n" .. "Error while parsing template '" .. sourcefile .. "':\n" .. (err or "Unknown syntax error")) render_template(name, template, scope, pkg) end --- Render a template from a string. -- @param template Template string -- @param scope Scope to assign to template (optional) -- @param pkg i18n namespace package (optional) function ctx.render_string(str, scope, pkg) local template, _, err = tparser.parse_string(str) assert(template, "Error while parsing template:\n" .. (err or "Unknown syntax error")) render_template('(local)', template, scope, pkg) end --- Render a template, wrapped in the configured layout. -- @param name Template name -- @param scope Scope to assign to template (optional) -- @param pkg i18n namespace package (optional) -- @param layout_scope Additional variables to pass to the layout template function ctx.render_layout(name, scope, pkg, layout_scope) ctx.render(config.layout_template, setmetatable({ content = name, scope = scope, pkg = pkg, }, { __index = layout_scope }), config.layout_package) end return ctx end