5 The request dispatcher and module dispatcher generators
11 Copyright 2008 Steven Barth <steven@midlink.org>
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
17 http://www.apache.org/licenses/LICENSE-2.0
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
26 module("luci.dispatcher", package.seeall)
31 -- Local dispatch database
32 local tree = {nodes={}}
34 -- Global request object
37 -- Active dispatched node
42 function build_url(...)
43 return luci.http.dispatcher() .. "/" .. table.concat(arg, "/")
46 -- Sends a 404 error code and renders the "error404" template if available
47 function error404(message)
48 luci.http.status(404, "Not Found")
49 message = message or "Not Found"
51 require("luci.template")
52 if not pcall(luci.template.render, "error404") then
53 luci.http.prepare_content("text/plain")
59 -- Sends a 500 error code and renders the "error500" template if available
60 function error500(message)
61 luci.http.status(500, "Internal Server Error")
63 require("luci.template")
64 if not pcall(luci.template.render, "error500", {message=message}) then
65 luci.http.prepare_content("text/plain")
71 -- Dispatches a request depending on the PATH_INFO variable
72 function httpdispatch()
73 local pathinfo = luci.http.env.PATH_INFO or ""
76 for s in pathinfo:gmatch("([%w_]+)") do
77 table.insert(request, s)
87 for i, s in ipairs(request) do
93 for k, v in pairs(c) do
100 require("luci.i18n").loadc(track.i18n)
103 if track.setgroup then
104 luci.sys.process.setgroup(track.setgroup)
107 if track.setuser then
108 luci.sys.process.setuser(track.setuser)
111 -- Init template engine
112 local tpl = require("luci.template")
113 tpl.viewns.translate = function(...) return require("luci.i18n").translate(...) end
114 tpl.viewns.controller = luci.http.dispatcher()
115 tpl.viewns.uploadctrl = luci.http.dispatcher_upload()
116 tpl.viewns.media = luci.config.main.mediaurlbase
117 tpl.viewns.resource = luci.config.main.resourcebase
120 if c and type(c.target) == "function" then
123 stat, err = pcall(c.target)
132 -- Generates the dispatching tree
133 function createindex()
134 local path = luci.sys.libpath() .. "/controller/"
137 if pcall(require, "fastindex") then
138 createindex_fastindex(path, suff)
140 createindex_plain(path, suff)
144 -- Uses fastindex to create the dispatching tree
145 function createindex_fastindex(path, suffix)
146 local fi = fastindex.new("index")
147 fi.add(path .. "*" .. suffix)
148 fi.add(path .. "*/*" .. suffix)
151 for k, v in pairs(fi.indexes) do
152 local stat, mod = pcall(require, v[2])
154 luci.util.updfenv(v[1], luci.dispatcher)
159 -- Calls the index function of all available controllers
160 function createindex_plain(path, suffix)
161 local controllers = luci.util.combine(
162 luci.fs.glob(path .. "*" .. suffix) or {},
163 luci.fs.glob(path .. "*/*" .. suffix) or {}
166 for i,c in ipairs(controllers) do
167 c = "luci.controller." .. c:sub(#path+1, #c-#suffix):gsub("/", ".")
168 stat, mod = pcall(require, c)
170 if stat and mod and type(mod.index) == "function" then
171 luci.util.updfenv(mod.index, luci.dispatcher)
177 -- Shortcut for creating a dispatching node
178 function entry(path, target, title, order, add)
186 for k,v in pairs(add) do
193 -- Fetch a dispatching node
197 if arg[1] and type(arg[1]) == "table" then
201 for k,v in ipairs(arg) do
202 if not c.nodes[v] then
203 c.nodes[v] = {nodes={}}
221 function template(name)
222 require("luci.template")
223 return function() luci.template.render(name) end
228 require("luci.template")
231 local stat, res = pcall(luci.cbi.load, model)
237 local stat, err = pcall(res.parse, res)
243 luci.template.render("cbi/header")
245 luci.template.render("cbi/footer")