From: Jo-Philipp Wich Date: Thu, 10 Sep 2009 08:05:56 +0000 (+0000) Subject: libs/web: drop the Lua template parser, the C implementation is faster in almost... X-Git-Tag: 0.10.0~1147 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=aa93e160923ae0873fac5ea061935cf4338dc047;p=oweals%2Fluci.git libs/web: drop the Lua template parser, the C implementation is faster in almost every case, even without caching --- diff --git a/libs/web/luasrc/template.lua b/libs/web/luasrc/template.lua index 7cc6e11b0..90ac69fba 100644 --- a/libs/web/luasrc/template.lua +++ b/libs/web/luasrc/template.lua @@ -30,7 +30,6 @@ local util = require "luci.util" local table = require "table" local string = require "string" local config = require "luci.config" -local coroutine = require "coroutine" local nixio = require "nixio", require "nixio.util" local tparser = require "luci.template.parser" @@ -43,84 +42,12 @@ local assert, type, error = assert, type, error module "luci.template" config.template = config.template or {} - -viewdir = config.template.viewdir or util.libpath() .. "/view" -compiledir = config.template.compiledir or util.libpath() .. "/view" - - --- Compile modes: --- memory: Always compile, do not save compiled files, ignore precompiled --- file: Compile on demand, save compiled files, update precompiled -compiler_mode = config.template.compiler_mode or "memory" +viewdir = config.template.viewdir or util.libpath() .. "/view" -- Define the namespace for template modules context = util.threadlocal() ---- Manually compile a given template into an executable Lua function --- @param template LuCI template --- @return Lua template function -function compile(template) - local expr = {} - - -- Search all <% %> expressions - local function expr_add(ws1, skip1, command, skip2, ws2) - expr[#expr+1] = command - return ( #skip1 > 0 and "" or ws1 ) .. - "<%" .. tostring(#expr) .. "%>" .. - ( #skip2 > 0 and "" or ws2 ) - end - - -- Save all expressiosn to table "expr" - template = template:gsub("(%s*)<%%(%-?)(.-)(%-?)%%>(%s*)", expr_add) - - local function sanitize(s) - s = "%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 = '")' - - template = header .. template .. footer - - -- Replacements - local r_include = '")\ninclude("%s")\nwrite("' - local r_i18n = '")\nwrite(translate("%1","%2"))\nwrite("' - local r_i18n2 = '")\nwrite(translate("%1", ""))\nwrite("' - local r_pexec = '")\nwrite(tostring(%s or ""))\nwrite("' - 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))) - elseif p == ":" then - if v:find(" ") then - re = sanitize(v):gsub(":(.-) (.*)", r_i18n) - else - re = sanitize(v):gsub(":(.+)", r_i18n2) - end - elseif p == "=" then - re = r_pexec:format(v:sub(2)) - elseif p == "#" then - re = "" - else - re = r_exec:format(v) - end - template = template:gsub("<%%"..tostring(k).."%%>", re) - end - - return loadstring(template) -end - --- Render a certain template. -- @param name Template name -- @param scope Scope to assign to template (optional) @@ -138,21 +65,6 @@ Template.cache = setmetatable({}, {__mode = "v"}) -- Constructor - Reads and compiles the template on-demand function Template.__init__(self, name) - local function _encode_filename(str) - - local function __chrenc( chr ) - return "%%%02x" % string.byte( chr ) - end - - if type(str) == "string" then - str = str:gsub( - "([^a-zA-Z0-9$_%-%.%+!*'(),])", - __chrenc - ) - end - - return str - end self.template = self.cache[name] self.name = name @@ -161,60 +73,18 @@ function Template.__init__(self, name) self.viewns = context.viewns -- If we have a cached template, skip compiling and loading - if self.template then - return - end - - -- Enforce cache security - local cdir = compiledir .. "/" .. sys.process.info("uid") - - -- Compile and build - local sourcefile = viewdir .. "/" .. name - local compiledfile = cdir .. "/" .. _encode_filename(name) .. ".lua" - local err - - if compiler_mode == "file" then - local tplmt = fs.stat(sourcefile, "mtime") or fs.stat(sourcefile .. ".htm", "mtime") - local commt = fs.stat(compiledfile, "mtime") - - if not fs.stat(cdir, "mtime") then - fs.mkdirr(cdir) - fs.chmod(fs.dirname(cdir), 777) - end - - assert(tplmt or commt, "No such template: " .. name) - - -- Build if there is no compiled file or if compiled file is outdated - if not commt or (commt and tplmt and commt < tplmt) then - local source - source, err = fs.readfile(sourcefile) or fs.readfile(sourcefile .. ".htm") - - if source then - local compiled, err = compile(source) - - local f = nixio.open(compiledfile, "w", 600) - f:writeall(util.get_bytecode(compiled)) - f:close() - self.template = compiled - end + if not self.template then + + -- Compile template + local sourcefile = viewdir .. "/" .. name .. ".htm" + self.template, _, err = tparser.parse(sourcefile) + + -- If we have no valid template throw error, otherwise cache the template + if not self.template then + error(err) else - assert( - sys.process.info("uid") == fs.stat(compiledfile, "uid") - and fs.stat(compiledfile, "modestr") == "rw-------", - "Fatal: Cachefile is not sane!" - ) - self.template, err = loadfile(compiledfile) + self.cache[name] = self.template end - - elseif compiler_mode == "memory" then - self.template, _, err = tparser.parse(sourcefile .. ".htm") - end - - -- If we have no valid template throw error, otherwise cache the template - if not self.template then - error(err) - else - self.cache[name] = self.template end end diff --git a/libs/web/root/etc/config/luci b/libs/web/root/etc/config/luci index a42bac390..c503a8f1e 100644 --- a/libs/web/root/etc/config/luci +++ b/libs/web/root/etc/config/luci @@ -20,9 +20,5 @@ config internal sauth config internal ccache option enable 1 - -config internal template - option compiler_mode memory - option compiledir "/tmp/luci-templatecache" config internal themes