diff options
-rw-r--r-- | src/ffluci/cbi.lua | 42 | ||||
-rw-r--r-- | src/ffluci/controller/public/index.lua | 3 | ||||
-rw-r--r-- | src/ffluci/dispatcher.lua | 74 | ||||
-rw-r--r-- | src/ffluci/template.lua | 6 | ||||
-rw-r--r-- | src/ffluci/util.lua | 10 | ||||
-rw-r--r-- | src/ffluci/view/cbi/lvalue.htm | 20 | ||||
-rw-r--r-- | src/ffluci/view/cbi/map.htm | 15 | ||||
-rw-r--r-- | src/ffluci/view/cbi/nsection.htm | 10 | ||||
-rw-r--r-- | src/ffluci/view/cbi/tsection.htm | 18 | ||||
-rw-r--r-- | src/ffluci/view/cbi/value.htm | 14 |
10 files changed, 154 insertions, 58 deletions
diff --git a/src/ffluci/cbi.lua b/src/ffluci/cbi.lua index 149c1d70f..5a20aadc5 100644 --- a/src/ffluci/cbi.lua +++ b/src/ffluci/cbi.lua @@ -25,22 +25,50 @@ limitations under the License. ]]-- module("ffluci.cbi", package.seeall) + require("ffluci.template") require("ffluci.util") require("ffluci.http") require("ffluci.model.uci") -local Template = ffluci.template.Template -local class = ffluci.util.class + +local Template = ffluci.template.Template +local class = ffluci.util.class local instanceof = ffluci.util.instanceof +function load(cbimap) + require("ffluci.fs") + require("ffluci.i18n") + + local cbidir = ffluci.fs.dirname(ffluci.util.__file__()) .. "model/cbi/" + local func = loadfile(cbidir..cbimap..".lua") + + if not func then + error("Unable to load CBI map: " .. cbimap) + return nil + end + + ffluci.util.resfenv(func) + ffluci.util.updfenv(func, ffluci.cbi) + ffluci.util.extfenv(func, "translate", ffluci.i18n.translate) + + local map = func() + + if not instanceof(map, Map) then + error("CBI map returns no valid map object!") + return nil + end + + return map +end + -- Node pseudo abstract class Node = class() function Node.__init__(self, title, description) self.children = {} - self.title = title - self.description = description + self.title = title or "" + self.description = description or "" self.template = "cbi/node" end @@ -55,7 +83,7 @@ function Node.parse(self) end function Node.render(self) - ffluci.template.render(self.template) + ffluci.template.render(self.template, {self=self}) end @@ -83,7 +111,7 @@ function Map.section(self, class, ...) end function Map.read(self) - self.ucidata = self.ucidata or ffluci.model.uci.show(self.config) + self.ucidata = self.ucidata or ffluci.model.uci.show(self.config)[self.config] return self.ucidata end @@ -173,7 +201,7 @@ function AbstractValue.formvalue(self) end function AbstractValue.ucivalue(self) - return self.map.read()[self.section][self.option] + return self.map:read()[self.section][self.option] end function AbstractValue.validate(self, value) diff --git a/src/ffluci/controller/public/index.lua b/src/ffluci/controller/public/index.lua index 9ca70f56c..4f8160a4c 100644 --- a/src/ffluci/controller/public/index.lua +++ b/src/ffluci/controller/public/index.lua @@ -1,2 +1 @@ -module(..., package.seeall) -dispatcher = require("ffluci.dispatcher").simpleview
\ No newline at end of file +module(..., package.seeall)
\ No newline at end of file diff --git a/src/ffluci/dispatcher.lua b/src/ffluci/dispatcher.lua index d2998aa49..0f05c3d17 100644 --- a/src/ffluci/dispatcher.lua +++ b/src/ffluci/dispatcher.lua @@ -95,6 +95,7 @@ function dispatch(req) return error404() else module.request = request + module.dispatcher = module.dispatcher or dynamic setfenv(module.dispatcher, module) return module.dispatcher(request) end @@ -139,30 +140,85 @@ function httpdispatch() dispatch({category=cat, module=mod, action=act}) end --- The Simple View Dispatcher directly renders the template --- which is placed in ffluci/views/"request.module"/"request.action" -function simpleview(request) + +-- Dispatchers -- + + +-- The Action Dispatcher searches the module for any function called +-- action_"request.action" and calls it +function action(request) local i18n = require("ffluci.i18n") - local tmpl = require("ffluci.template") local disp = require("ffluci.dispatcher") i18n.loadc(request.module) - if not pcall(tmpl.render, request.module .. "/" .. request.action) then + local action = getfenv()["action_" .. request.action:gsub("-", "_")] + if action then + action() + else disp.error404() end end --- The Action Dispatcher searches the module for any function called --- action_"request.action" and calls it -function action(request) +-- The CBI dispatcher directly parses and renders the CBI map which is +-- placed in ffluci/modles/cbi/"request.module"/"request.action" +function cbi(request) local i18n = require("ffluci.i18n") local disp = require("ffluci.dispatcher") + local tmpl = require("ffluci.template") + local cbi = require("ffluci.cbi") i18n.loadc(request.module) + + stat, map = pcall(cbi.load, request.module.."/"..request.action) + if stat then + tmpl.render("header") + map:render() + tmpl.render("footer") + else + disp.error404() + end +end + +-- The dynamic dispatchers combines the action, simpleview and cbi dispatchers +-- in one dispatcher. It tries to lookup the request in this order. +function dynamic(request) + local i18n = require("ffluci.i18n") + local disp = require("ffluci.dispatcher") + local tmpl = require("ffluci.template") + local cbi = require("ffluci.cbi") + + i18n.loadc(request.module) + local action = getfenv()["action_" .. request.action:gsub("-", "_")] if action then action() - else + return + end + + if pcall(tmpl.render, request.module .. "/" .. request.action) then + return + end + + stat, map = pcall(cbi.load, request.module.."/"..request.action) + if stat then + tmpl.render("header") + map:render() + tmpl.render("footer") + return + end + + disp.error404() +end + +-- The Simple View Dispatcher directly renders the template +-- which is placed in ffluci/views/"request.module"/"request.action" +function simpleview(request) + local i18n = require("ffluci.i18n") + local tmpl = require("ffluci.template") + local disp = require("ffluci.dispatcher") + + i18n.loadc(request.module) + if not pcall(tmpl.render, request.module .. "/" .. request.action) then disp.error404() end end
\ No newline at end of file diff --git a/src/ffluci/template.lua b/src/ffluci/template.lua index 00145a0a0..18265a4a1 100644 --- a/src/ffluci/template.lua +++ b/src/ffluci/template.lua @@ -124,12 +124,13 @@ function compile(template) end -- Oldstyle render shortcut -function render(name, ...) +function render(name, scope, ...) + scope = scope or getfenv(2) local s, t = pcall(Template, name) if not s then error("Unable to load template: " .. name) else - t:render(...) + t:render(scope, ...) end end @@ -208,6 +209,7 @@ function Template.render(self, scope) local oldfenv = getfenv(self.template) -- Put our predefined objects in the scope of the template + ffluci.util.resfenv(self.template) ffluci.util.updfenv(self.template, scope) ffluci.util.updfenv(self.template, self.viewns) diff --git a/src/ffluci/util.lua b/src/ffluci/util.lua index 12031ff7d..b219be130 100644 --- a/src/ffluci/util.lua +++ b/src/ffluci/util.lua @@ -114,7 +114,6 @@ end function extfenv(f, key, obj) local scope = getfenv(f) scope[key] = obj - setfenv(f, scope) end @@ -131,13 +130,20 @@ function instanceof(object, class) end +-- Resets the scope of f doing a shallow copy of its scope into a new table +function resfenv(f) + local scope = getfenv(f) + setfenv(f, {}) + updfenv(f, scope) +end + + -- Updates the scope of f with "extscope" function updfenv(f, extscope) local scope = getfenv(f) for k, v in pairs(extscope) do scope[k] = v end - setfenv(f, scope) end diff --git a/src/ffluci/view/cbi/lvalue.htm b/src/ffluci/view/cbi/lvalue.htm index eb2eac2fd..6a9941959 100644 --- a/src/ffluci/view/cbi/lvalue.htm +++ b/src/ffluci/view/cbi/lvalue.htm @@ -1,11 +1,11 @@ -<div class="cbi-lvalue"> -<div class="cbi-lvalue-title"><%=self.title%></div> -<div class="cbi-lvalue-field"> -<select name="<%=self.config.."."..self.section.."."..self.option%>"> -<%for k, v in self.list do%> -<option value="<%=k%>"><%=v%></option> + <div class="cbi-lvalue"> + <div class="cbi-lvalue-title"><%=self.title%></div> + <div class="cbi-lvalue-field"> + <select name="cbid.<%=self.config.."."..self.section.."."..self.option%>"> +<%for k, v in pairs(self.list) do%> + <option value="<%=k%>"><%=v%></option> <% end %> -</select> -</div> -<div class="cbi-value-description"><%=self.description%></div> -</div>
\ No newline at end of file + </select> + </div> + <div class="cbi-value-description"><%=self.description%></div> + </div>
\ No newline at end of file diff --git a/src/ffluci/view/cbi/map.htm b/src/ffluci/view/cbi/map.htm index e4f493bd0..b724ffccb 100644 --- a/src/ffluci/view/cbi/map.htm +++ b/src/ffluci/view/cbi/map.htm @@ -1,7 +1,10 @@ -<div class="cbi-map" id="cbi-<%=self.config%>"> -<form method="post" action="<%=os.getenv("REQUEST_URI")%>"> -<h1><%=self.title%></h1> -<div class="cbi-map-descr"><%=self.description%></div> + <div class="cbi-map" id="cbi-<%=self.config%>"> + <form method="post" action="<%=os.getenv("REQUEST_URI")%>"> + <h1><%=self.title%></h1> + <div class="cbi-map-descr"><%=self.description%></div> + <br /> <% for k, node in ipairs(self.children) do node:render() end %> -</form> -</div> + <br /> + <input type="submit" /> <input type="reset" /> + </form> + </div> diff --git a/src/ffluci/view/cbi/nsection.htm b/src/ffluci/view/cbi/nsection.htm index 5badeca56..e002c68b0 100644 --- a/src/ffluci/view/cbi/nsection.htm +++ b/src/ffluci/view/cbi/nsection.htm @@ -1,5 +1,7 @@ -<div class="cbi-nsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>-<%=self.section%>"> -<h2><%=self.title%></h2> -<div class="cbi-nsection-descr"><%=self.description%></div> + <div class="cbi-nsection" id="cbi-<%=self.config%>-<%=self.section%>"> + <h2><%=self.title%></h2> + <div class="cbi-nsection-descr"><%=self.description%></div> + <div class="cbi-nsection-options"> <% for k, node in ipairs(self.children) do node:render() end %> -</div> + </div> + </div> diff --git a/src/ffluci/view/cbi/tsection.htm b/src/ffluci/view/cbi/tsection.htm index 8c7f0c115..b613f6271 100644 --- a/src/ffluci/view/cbi/tsection.htm +++ b/src/ffluci/view/cbi/tsection.htm @@ -2,20 +2,20 @@ local allsections = self.map:read() local sections = {} for k, v in pairs(allsections) do - if v[".type"] == sectiontype then + if v[".type"] == self.sectiontype then sections[k] = v end end %> -<div class="cbi-tsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>"> -<h2><%=self.title%></h2> -<div class="cbi-tsection-descr"><%=self.description%></div> + <div class="cbi-tsection" id="cbi-<%=self.config%>-<%=self.sectiontype%>"> + <h2><%=self.title%></h2> + <div class="cbi-tsection-descr"><%=self.description%></div> <% for k, v in pairs(sections) do %> -<div class="cbi-tsection-node" id="cbi-<%=self.config%>-<%=k%>"> -<% for k, node in ipairs(self.children) do + <div class="cbi-tsection-node" id="cbi-<%=self.config%>-<%=k%>"> +<% for i, node in ipairs(self.children) do node.section = k - node:render(k) + node:render() end %> -</div> + </div> <% end %> -</div> + </div> diff --git a/src/ffluci/view/cbi/value.htm b/src/ffluci/view/cbi/value.htm index cc22c4e56..a898d08c1 100644 --- a/src/ffluci/view/cbi/value.htm +++ b/src/ffluci/view/cbi/value.htm @@ -1,7 +1,7 @@ -<div class="cbi-value"> -<div class="cbi-value-title"><%=self.title%></div> -<div class="cbi-value-field"> -<input type="text" name="<%=self.config.."."..self.section.."."..self.option%>" value="<%=self:ucivalue()%>" /> -</div> -<div class="cbi-value-description"><%=self.description%></div> -</div>
\ No newline at end of file + <div class="cbi-value"> + <div class="cbi-value-title"><%=self.title%></div> + <div class="cbi-value-field"> + <input type="text" name="cbid.<%=self.config.."."..self.section.."."..self.option%>" value="<%=(self:ucivalue() or "")%>" /> + </div> + <div class="cbi-value-description"><%=self.description%></div> + </div>
\ No newline at end of file |