109 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- Copyright 2008 Steven Barth <steven@midlink.org>
 | |
| -- Copyright 2017-2018 Matthias Schiffer <mschiffer@universe-factory.net>
 | |
| -- 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
 |