Add extended dispatching targets, optimize dispatching behaviour
This commit is contained in:
parent
f3157bc759
commit
0cc5fdd394
1 changed files with 129 additions and 88 deletions
|
@ -146,6 +146,7 @@ function dispatch(request)
|
||||||
local t = true
|
local t = true
|
||||||
local token = ctx.urltoken
|
local token = ctx.urltoken
|
||||||
local preq = {}
|
local preq = {}
|
||||||
|
local freq = {}
|
||||||
|
|
||||||
for i, s in ipairs(request) do
|
for i, s in ipairs(request) do
|
||||||
local tkey, tval
|
local tkey, tval
|
||||||
|
@ -158,6 +159,7 @@ function dispatch(request)
|
||||||
else
|
else
|
||||||
t = false
|
t = false
|
||||||
preq[#preq+1] = s
|
preq[#preq+1] = s
|
||||||
|
freq[#freq+1] = s
|
||||||
c = c.nodes[s]
|
c = c.nodes[s]
|
||||||
n = i
|
n = i
|
||||||
if not c then
|
if not c then
|
||||||
|
@ -174,10 +176,12 @@ function dispatch(request)
|
||||||
|
|
||||||
if c and c.leaf then
|
if c and c.leaf then
|
||||||
for j=n+1, #request do
|
for j=n+1, #request do
|
||||||
table.insert(args, request[j])
|
args[#args+1] = request[j]
|
||||||
|
freq[#freq+1] = request[j]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ctx.requestpath = freq
|
||||||
ctx.path = preq
|
ctx.path = preq
|
||||||
|
|
||||||
if track.i18n then
|
if track.i18n then
|
||||||
|
@ -203,7 +207,7 @@ function dispatch(request)
|
||||||
if key == "controller" then
|
if key == "controller" then
|
||||||
return build_url()
|
return build_url()
|
||||||
elseif key == "REQUEST_URI" then
|
elseif key == "REQUEST_URI" then
|
||||||
return build_url(unpack(ctx.requested.path))
|
return build_url(unpack(ctx.requestpath))
|
||||||
else
|
else
|
||||||
return rawget(table, key) or _G[key]
|
return rawget(table, key) or _G[key]
|
||||||
end
|
end
|
||||||
|
@ -285,7 +289,16 @@ function dispatch(request)
|
||||||
luci.sys.process.setuser(track.setuser)
|
luci.sys.process.setuser(track.setuser)
|
||||||
end
|
end
|
||||||
|
|
||||||
if c and (c.index or type(c.target) == "function") then
|
local target = nil
|
||||||
|
if c then
|
||||||
|
if type(c.target) == "function" then
|
||||||
|
target = c.target
|
||||||
|
elseif type(c.target) == "table" then
|
||||||
|
target = c.target.target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if c and (c.index or type(target) == "function") then
|
||||||
ctx.dispatched = c
|
ctx.dispatched = c
|
||||||
ctx.requested = ctx.requested or ctx.dispatched
|
ctx.requested = ctx.requested or ctx.dispatched
|
||||||
end
|
end
|
||||||
|
@ -298,9 +311,9 @@ function dispatch(request)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if c and type(c.target) == "function" then
|
if type(target) == "function" then
|
||||||
util.copcall(function()
|
util.copcall(function()
|
||||||
local oldenv = getfenv(c.target)
|
local oldenv = getfenv(target)
|
||||||
local module = require(c.module)
|
local module = require(c.module)
|
||||||
local env = setmetatable({}, {__index=
|
local env = setmetatable({}, {__index=
|
||||||
|
|
||||||
|
@ -308,10 +321,14 @@ function dispatch(request)
|
||||||
return rawget(tbl, key) or module[key] or oldenv[key]
|
return rawget(tbl, key) or module[key] or oldenv[key]
|
||||||
end})
|
end})
|
||||||
|
|
||||||
setfenv(c.target, env)
|
setfenv(target, env)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
c.target(unpack(args))
|
if type(c.target) == "table" then
|
||||||
|
target(c.target, unpack(args))
|
||||||
|
else
|
||||||
|
target(unpack(args))
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error404()
|
error404()
|
||||||
end
|
end
|
||||||
|
@ -558,110 +575,134 @@ function rewrite(n, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function _call(self, ...)
|
||||||
|
if #self.argv > 0 then
|
||||||
|
return getfenv()[self.name](unpack(self.argv), ...)
|
||||||
|
else
|
||||||
|
return getfenv()[self.name](...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Create a function-call dispatching target.
|
--- Create a function-call dispatching target.
|
||||||
-- @param name Target function of local controller
|
-- @param name Target function of local controller
|
||||||
-- @param ... Additional parameters passed to the function
|
-- @param ... Additional parameters passed to the function
|
||||||
function call(name, ...)
|
function call(name, ...)
|
||||||
local argv = {...}
|
return {type = "call", argv = {...}, name = name, target = _call}
|
||||||
return function(...)
|
end
|
||||||
if #argv > 0 then
|
|
||||||
return getfenv()[name](unpack(argv), ...)
|
|
||||||
else
|
local _template = function(self, ...)
|
||||||
return getfenv()[name](...)
|
require "luci.template".render(self.view)
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a template render dispatching target.
|
--- Create a template render dispatching target.
|
||||||
-- @param name Template to be rendered
|
-- @param name Template to be rendered
|
||||||
function template(name)
|
function template(name)
|
||||||
return function()
|
return {type = "template", view = name, target = _template}
|
||||||
require("luci.template")
|
end
|
||||||
luci.template.render(name)
|
|
||||||
|
|
||||||
|
local function _cbi(self, ...)
|
||||||
|
local cbi = require "luci.cbi"
|
||||||
|
local tpl = require "luci.template"
|
||||||
|
local http = require "luci.http"
|
||||||
|
|
||||||
|
local config = self.config or {}
|
||||||
|
local maps = cbi.load(self.model, ...)
|
||||||
|
|
||||||
|
local state = nil
|
||||||
|
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
if config.autoapply then
|
||||||
|
res.autoapply = config.autoapply
|
||||||
|
end
|
||||||
|
local cstate = res:parse()
|
||||||
|
if not state or cstate < state then
|
||||||
|
state = cstate
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if config.on_valid_to and state and state > 0 and state < 2 then
|
||||||
|
http.redirect(config.on_valid_to)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.on_changed_to and state and state > 1 then
|
||||||
|
http.redirect(config.on_changed_to)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.on_success_to and state and state > 0 then
|
||||||
|
http.redirect(config.on_success_to)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.state_handler then
|
||||||
|
if not config.state_handler(state, maps) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local pageaction = true
|
||||||
|
http.header("X-CBI-State", state or 0)
|
||||||
|
tpl.render("cbi/header", {state = state})
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
res:render()
|
||||||
|
if res.pageaction == false then
|
||||||
|
pageaction = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
tpl.render("cbi/footer", {pageaction=pageaction, state = state, autoapply = config.autoapply})
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a CBI model dispatching target.
|
--- Create a CBI model dispatching target.
|
||||||
-- @param model CBI model to be rendered
|
-- @param model CBI model to be rendered
|
||||||
function cbi(model, config)
|
function cbi(model, config)
|
||||||
config = config or {}
|
return {type = "cbi", config = config, model = model, target = _cbi}
|
||||||
return function(...)
|
end
|
||||||
require("luci.cbi")
|
|
||||||
require("luci.template")
|
|
||||||
local http = require "luci.http"
|
|
||||||
|
|
||||||
maps = luci.cbi.load(model, ...)
|
|
||||||
|
|
||||||
local state = nil
|
local function _arcombine(self, ...)
|
||||||
|
local argv = {...}
|
||||||
|
local target = #argv > 0 and self.targets[2] or self.targets[1]
|
||||||
|
setfenv(target.target, self.env)
|
||||||
|
target:target(unpack(argv))
|
||||||
|
end
|
||||||
|
|
||||||
for i, res in ipairs(maps) do
|
--- Create a combined dispatching target for non argv and argv requests.
|
||||||
if config.autoapply then
|
-- @param trg1 Overview Target
|
||||||
res.autoapply = config.autoapply
|
-- @param trg2 Detail Target
|
||||||
end
|
function arcombine(trg1, trg2)
|
||||||
local cstate = res:parse()
|
return {type = "arcombine", env = getfenv(), target = _arcombine, targets = {trg1, trg2}}
|
||||||
if not state or cstate < state then
|
end
|
||||||
state = cstate
|
|
||||||
end
|
|
||||||
|
local function _form(self, ...)
|
||||||
|
local cbi = require "luci.cbi"
|
||||||
|
local tpl = require "luci.template"
|
||||||
|
local http = require "luci.http"
|
||||||
|
|
||||||
|
local maps = luci.cbi.load(self.model, ...)
|
||||||
|
local state = nil
|
||||||
|
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
local cstate = res:parse()
|
||||||
|
if not state or cstate < state then
|
||||||
|
state = cstate
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.on_valid_to and state and state > 0 and state < 2 then
|
|
||||||
luci.http.redirect(config.on_valid_to)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if config.on_changed_to and state and state > 1 then
|
|
||||||
luci.http.redirect(config.on_changed_to)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if config.on_success_to and state and state > 0 then
|
|
||||||
luci.http.redirect(config.on_success_to)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if config.state_handler then
|
|
||||||
if not config.state_handler(state, maps) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local pageaction = true
|
|
||||||
http.header("X-CBI-State", state or 0)
|
|
||||||
luci.template.render("cbi/header", {state = state})
|
|
||||||
for i, res in ipairs(maps) do
|
|
||||||
res:render()
|
|
||||||
if res.pageaction == false then
|
|
||||||
pageaction = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
luci.template.render("cbi/footer", {pageaction=pageaction, state = state, autoapply = config.autoapply})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
http.header("X-CBI-State", state or 0)
|
||||||
|
tpl.render("header")
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
res:render()
|
||||||
|
end
|
||||||
|
tpl.render("footer")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a CBI form model dispatching target.
|
--- Create a CBI form model dispatching target.
|
||||||
-- @param model CBI form model tpo be rendered
|
-- @param model CBI form model tpo be rendered
|
||||||
function form(model)
|
function form(model)
|
||||||
return function(...)
|
return {type = "cbi", model = model, target = _form}
|
||||||
require("luci.cbi")
|
|
||||||
require("luci.template")
|
|
||||||
local http = require "luci.http"
|
|
||||||
|
|
||||||
maps = luci.cbi.load(model, ...)
|
|
||||||
|
|
||||||
local state = nil
|
|
||||||
|
|
||||||
for i, res in ipairs(maps) do
|
|
||||||
local cstate = res:parse()
|
|
||||||
if not state or cstate < state then
|
|
||||||
state = cstate
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
http.header("X-CBI-State", state or 0)
|
|
||||||
luci.template.render("header")
|
|
||||||
for i, res in ipairs(maps) do
|
|
||||||
res:render()
|
|
||||||
end
|
|
||||||
luci.template.render("footer")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue