-viewns = {
- write = io.write,
- include = function(name) Template(name):render(getfenv(2)) end,
-}
-
--- Compiles a given template into an executable Lua module
-function compile(template)
- -- Search all <% %> expressions (remember: Lua table indexes begin with #1)
- local function expr_add(command)
- table.insert(expr, command)
- return "<%" .. tostring(#expr) .. "%>"
- end
-
- -- As "expr" should be local, we have to assign it to the "expr_add" scope
- local expr = {}
- luci.util.extfenv(expr_add, "expr", expr)
-
- -- Save all expressiosn to table "expr"
- template = template:gsub("<%%(.-)%%>", expr_add)
-
- local function sanitize(s)
- s = luci.util.escape(s)
- s = luci.util.escape(s, "'")
- s = luci.util.escape(s, "\n")
- return s
- end
-
- -- Escape and sanitize all the template (all non-expressions)
- template = sanitize(template)
-
- -- Template module header/footer declaration
- local header = "write('"
- local footer = "')"
-
- template = header .. template .. footer
-
- -- Replacements
- local r_include = "')\ninclude('%s')\nwrite('"
- local r_i18n = "'..translate('%1','%2')..'"
- local r_pexec = "'..(%s or '')..'"
- local r_exec = "')\n%s\nwrite('"
-
- -- Parse the expressions
- for k,v in pairs(expr) do
- local p = v:sub(1, 1)
- local re = nil
- if p == "+" then
- re = r_include:format(sanitize(string.sub(v, 2)))
- elseif p == ":" then
- re = sanitize(v):gsub(":(.-) (.+)", r_i18n)
- elseif p == "=" then
- re = r_pexec:format(v:sub(2))
- else
- re = r_exec:format(v)
- end
- template = template:gsub("<%%"..tostring(k).."%%>", re)
- end
-
- if compiler_enable_bytecode then
- tf = loadstring(template)
- template = string.dump(tf)
- end
-
- return template
-end