templates.lua

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

mercurial