limitations under the License.
]]--
+
+--- LuCI template library.
module("luci.template", package.seeall)
require("luci.config")
require("luci.util")
require("luci.fs")
+require("luci.sys")
require("luci.http")
luci.config.template = luci.config.template or {}
-viewdir = luci.config.template.viewdir or luci.sys.libpath() .. "/view"
-compiledir = luci.config.template.compiledir or luci.sys.libpath() .. "/view"
+viewdir = luci.config.template.viewdir or luci.util.libpath() .. "/view"
+compiledir = luci.config.template.compiledir or luci.util.libpath() .. "/view"
-- Compile modes:
include = function(name) Template(name):render(getfenv(2)) end,
}
--- Compiles a given template into an executable Lua module
+--- Manually compile a given template into an executable Lua function
+-- @param template LuCI template
+-- @return Lua template function
function compile(template)
- -- Search all <% %> expressions (remember: Lua table indexes begin with #1)
+ -- Search all <% %> expressions
local function expr_add(ws1, skip1, command, skip2, ws2)
table.insert(expr, command)
return ( #skip1 > 0 and "" or ws1 ) ..
template = template:gsub("(%s*)<%%(%-?)(.-)(%-?)%%>(%s*)", expr_add)
local function sanitize(s)
- s = luci.util.escape(s)
- s = luci.util.escape(s, "'")
- s = luci.util.escape(s, "\n")
- return s
+ s = string.format("%q", s)
+ return s:sub(2, #s-1)
end
-- Escape and sanitize all the template (all non-expressions)
template = sanitize(template)
-- Template module header/footer declaration
- local header = "write('"
- local footer = "')"
+ local header = 'write("'
+ local footer = '")'
template = header .. template .. footer
-- Replacements
- local r_include = "')\ninclude('%s')\nwrite('"
- local r_i18n = "'..translate('%1','%2')..'"
- local r_i18n2 = "'..translate('%1', '')..'"
- local r_pexec = "'..(%s or '')..'"
- local r_exec = "')\n%s\nwrite('"
+ local r_include = '")\ninclude("%s")\nwrite("'
+ local r_i18n = '"..translate("%1","%2").."'
+ local r_i18n2 = '"..translate("%1", "").."'
+ 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)
+ v = v:gsub("%%", "%%%%")
local re = nil
if p == "+" then
re = r_include:format(sanitize(string.sub(v, 2)))
return loadstring(template)
end
--- Oldstyle render shortcut
+--- Render a certain template.
+-- @param name Template name
+-- @param scope Scope to assign to template
function render(name, scope, ...)
scope = scope or getfenv(2)
local s, t = luci.util.copcall(Template, name)
if source then
local compiled, err = compile(source)
- luci.fs.writefile(compiledfile, luci.util.dump(compiled))
+ luci.fs.writefile(compiledfile, luci.util.get_bytecode(compiled))
self.template = compiled
end
else