|
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 |