templates.lua

1
module("templates", package.seeall)
2
 
3
local tpl = {};
4
local tpl_mt = { __index = tpl };
5
 
6
local tplutil = {};
7
local tplutil_mt = { __index = tplutil };
8
 
9
function tpl:saverender(fn, vars)
10
	local f, err = io.open(fn, "w+");
11
	if not f then return f,err; end
12
	f:write(self:render(vars));
13
	f:close();
14
	return true
15
end
16
 
17
function tpl:render(vars)
18
	local tpl = self.tpl or self.file:read("*a");
19
	self.tpl = tpl;
20
 
21
	if not vars then return tpl; end
22
		
23
	return (tpl:gsub("%b{}", 	function (cap)
24
						local v = cap:match("^%{%{%s*(.-)%s*%}%}*$")
25
						
26
						if not v then return cap; end
27
						local chunk, err = loadstring("return "..v);
28
						if not chunk then
29
							chunk, err = loadstring(v);
30
							if not chunk then error(err); end
31
						end
32
						setfenv(chunk, vars);
33
						local ok, ret = pcall(chunk);
34
						if not ok then error(ret); end
35
						do return ret or ""; end
36
						
37
						local v = cap:match("^%{%{%s*([%w_%.]+)%s*%}%}*$")
38
						if v then
39
							local _vars = vars;
40
							local ret, subs = v:gsub("(%w+)%.", function (var) if _vars then _vars = _vars[var]; end end);
41
							if _vars and _vars ~= vars then return _vars[v:match("%w+$")] or cap; end
42
							return vars[v] or cap;
43
						end
44
						
45
						local v = cap:match("^%{*[%w_]+%(.*%}*$");
46
						if v then
47
							local chunk, err = loadstring("return "..v:sub(2,-2));
48
							if not chunk then error("error in template: "..tostring(err)); end
49
							setfenv(chunk, setmetatable(vars, tplutil_mt));
50
							local success, ret = pcall(chunk);
51
							if success then
52
								return ret;
53
							else
54
								error("error in template: "..ret);
55
							end
56
						end
57
					end));
58
end
59
 
60
-- -- -- --
61
local function escape(s) return s; end
62
 
63
function tplutil.kvlist(t)
64
	if #t > 0 then
65
		-- Assume an array
66
		if type(t[1]) == "table" then
67
			-- Assume a table of tables
68
		else
69
			-- Assume a straight list
70
		end
71
	else
72
		-- assume a k->v list
73
		local b = { "<table>" };
74
 
75
	end
76
end
77
 
78
function tplutil.ulist(t)
79
	-- assume a list/array
80
	local b = { "<ul>\n" };
81
	for _, v in ipairs(t) do
82
		table.insert(b, "   <li>"..escape(v).."</li>\n");
83
	end
84
	table.insert(b, "</ul>\n");
85
	return table.concat(b);
86
end
87
 
88
function init(file)
89
	local f, err = io.open(file);
90
	if not f then return nil, "Couldn't open template file: "..err; end
91
	return setmetatable({ file = f }, tpl_mt);
92
end
93
 
94
function load(template)
95
	return setmetatable({ tpl = template }, tpl_mt);
96
end