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={}}
37 -- Global request object
40 -- Active dispatched node
49 function build_url(...)
50 return luci.http.dispatcher() .. "/" .. table.concat(arg, "/")
53 -- Sends a 404 error code and renders the "error404" template if available
54 function error404(message)
55 luci.http.status(404, "Not Found")
56 message = message or "Not Found"
58 require("luci.template")
59 if not pcall(luci.template.render, "error404") then
60 luci.http.prepare_content("text/plain")
66 -- Sends a 500 error code and renders the "error500" template if available
67 function error500(message)
68 luci.http.status(500, "Internal Server Error")
70 require("luci.template")
71 if not pcall(luci.template.render, "error500", {message=message}) then
72 luci.http.prepare_content("text/plain")
78 -- Creates a request object for dispatching
79 function httpdispatch()
80 local pathinfo = luci.http.env.PATH_INFO or ""
83 for s in pathinfo:gmatch("([%w_]+)") do
84 table.insert(request, s)
90 -- Dispatches a request
92 if not built_tree then
99 for i, s in ipairs(request) do
105 for k, v in pairs(c) do
112 require("luci.i18n").loadc(track.i18n)
115 if track.setgroup then
116 luci.sys.process.setgroup(track.setgroup)
119 if track.setuser then
120 luci.sys.process.setuser(track.setuser)
123 -- Init template engine
124 local tpl = require("luci.template")
125 tpl.viewns.translate = function(...) return require("luci.i18n").translate(...) end
126 tpl.viewns.controller = luci.http.dispatcher()
127 tpl.viewns.uploadctrl = luci.http.dispatcher_upload()
128 tpl.viewns.media = luci.config.main.mediaurlbase
129 tpl.viewns.resource = luci.config.main.resourcebase
132 if c and type(c.target) == "function" then
135 stat, err = pcall(c.target)
144 -- Generates the dispatching tree
145 function createindex()
147 local path = luci.sys.libpath() .. "/controller/"
150 if pcall(require, "fastindex") then
151 createindex_fastindex(path, suff)
153 createindex_plain(path, suff)
159 -- Uses fastindex to create the dispatching tree
160 function createindex_fastindex(path, suffix)
161 local fi = fastindex.new("index")
162 fi.add(path .. "*" .. suffix)
163 fi.add(path .. "*/*" .. suffix)
166 for k, v in pairs(fi.indexes) do
171 -- Calls the index function of all available controllers
172 function createindex_plain(path, suffix)
173 local controllers = luci.util.combine(
174 luci.fs.glob(path .. "*" .. suffix) or {},
175 luci.fs.glob(path .. "*/*" .. suffix) or {}
178 for i,c in ipairs(controllers) do
179 c = "luci.controller." .. c:sub(#path+1, #c-#suffix):gsub("/", ".")
180 stat, mod = pcall(require, c)
182 if stat and mod and type(mod.index) == "function" then
188 -- Creates the dispatching tree from the index
189 function createtree()
190 if not built_index then
194 for k, v in pairs(index) do
195 luci.util.updfenv(v, _M)
197 local stat, mod = pcall(require, k)
199 luci.util.updfenv(v, mod)
208 -- Shortcut for creating a dispatching node
209 function entry(path, target, title, order, add)
217 for k,v in pairs(add) do
224 -- Fetch a dispatching node
228 if arg[1] and type(arg[1]) == "table" then
232 for k,v in ipairs(arg) do
233 if not c.nodes[v] then
234 c.nodes[v] = {nodes={}}
252 function template(name)
253 require("luci.template")
254 return function() luci.template.render(name) end
259 require("luci.template")
262 local stat, res = pcall(luci.cbi.load, model)
268 local stat, err = pcall(res.parse, res)
274 luci.template.render("cbi/header")
276 luci.template.render("cbi/footer")