* luci/libs: http.protocol: switch to blockwise reading in urlencoded post requests...
[project/luci.git] / libs / web / luasrc / template.lua
index c672f16..29aedcd 100644 (file)
@@ -44,9 +44,10 @@ compiler_mode = luci.config.template.compiler_mode or "memory"
 
 
 -- Define the namespace for template modules
+context = luci.util.threadlocal()
+
 viewns = {
-       write      = io.write,
-       include    = function(name) Template(name):render(getfenv(2)) end,      
+       include    = function(name) Template(name):render(getfenv(2)) end,
 }
 
 -- Compiles a given template into an executable Lua module
@@ -83,6 +84,7 @@ function compile(template)
        -- 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('"
        
@@ -93,7 +95,11 @@ function compile(template)
                if p == "+" then
                        re = r_include:format(sanitize(string.sub(v, 2)))
                elseif p == ":" then
-                       re = sanitize(v):gsub(":(.-) (.+)", r_i18n)
+                       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))
                else
@@ -108,7 +114,7 @@ end
 -- Oldstyle render shortcut
 function render(name, scope, ...)
        scope = scope or getfenv(2)
-       local s, t = pcall(Template, name)
+       local s, t = luci.util.copcall(Template, name)
        if not s then
                error(t)
        else
@@ -136,23 +142,32 @@ function Template.__init__(self, name)
        self.viewns = {}
        
        -- Copy over from general namespace
-       for k, v in pairs(viewns) do
-               self.viewns[k] = v
-       end     
+       luci.util.update(self.viewns, viewns)
+       if context.viewns then
+               luci.util.update(self.viewns, context.viewns)
+       end
        
        -- If we have a cached template, skip compiling and loading
        if self.template then
                return
        end
        
+       -- Enforce cache security
+       local cdir = compiledir .. "/" .. luci.sys.process.info("uid")
+       
        -- Compile and build
        local sourcefile   = viewdir    .. "/" .. name .. ".htm"
-       local compiledfile = compiledir .. "/" .. name .. ".lua"
+       local compiledfile = cdir .. "/" .. luci.http.urlencode(name) .. ".lua"
        local err       
        
        if compiler_mode == "file" then
                local tplmt = luci.fs.mtime(sourcefile)
                local commt = luci.fs.mtime(compiledfile)
+               
+               if not luci.fs.mtime(cdir) then
+                       luci.fs.mkdir(cdir, true)
+                       luci.fs.chmod(luci.fs.dirname(cdir), "a+rxw")
+               end
                                
                -- Build if there is no compiled file or if compiled file is outdated
                if ((commt == nil) and not (tplmt == nil))
@@ -163,11 +178,6 @@ function Template.__init__(self, name)
                        if source then
                                local compiled, err = compile(source)
                                
-                               local compiledfile_dir  = luci.fs.dirname(compiledfile)
-                               if not luci.fs.mtime(compiledfile_dir) then
-                                       luci.fs.mkdir(compiledfile_dir)
-                               end
-                               
                                luci.fs.writefile(compiledfile, luci.util.dump(compiled))
                                self.template = compiled
                        end