* ffluci.cbi: updates
* ffluci.template: fixed a bug where different template scopes were not separated correctly * Added ffluci.dispatcher.cbi and ffluci.dispatcher.dynamic
This commit is contained in:
parent
6e0df95e27
commit
c8426cfa3c
10 changed files with 157 additions and 61 deletions
|
@ -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)
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
module(..., package.seeall)
|
||||
dispatcher = require("ffluci.dispatcher").simpleview
|
||||
module(..., package.seeall)
|
|
@ -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,18 +140,9 @@ 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)
|
||||
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
|
||||
|
||||
-- Dispatchers --
|
||||
|
||||
|
||||
-- The Action Dispatcher searches the module for any function called
|
||||
-- action_"request.action" and calls it
|
||||
|
@ -165,4 +157,68 @@ function action(request)
|
|||
else
|
||||
disp.error404()
|
||||
end
|
||||
end
|
||||
|
||||
-- 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()
|
||||
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
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
</select>
|
||||
</div>
|
||||
<div class="cbi-value-description"><%=self.description%></div>
|
||||
</div>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
<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>
|
Loading…
Reference in a new issue