mirror of https://git.openwrt.org/project/luci.git
* Added ffluci.util.instanceof function
* Minor beautifying in dispatcher * Added field for additional Tags under <head> in main style * Added structure for CBI * Added CBI to Makefile
This commit is contained in:
parent
cfe8fc894f
commit
f41539e549
4
Makefile
4
Makefile
|
@ -5,8 +5,8 @@ FILES = ffluci/config.lua
|
|||
|
||||
CFILES = ffluci/util.lua ffluci/http.lua \
|
||||
ffluci/fs.lua ffluci/i18n.lua ffluci/model/uci.lua \
|
||||
ffluci/template.lua ffluci/dispatcher.lua ffluci/menu.lua \
|
||||
ffluci/init.lua ffluci/sys.lua
|
||||
ffluci/template.lua ffluci/cbi.lua ffluci/dispatcher.lua \
|
||||
ffluci/menu.lua ffluci/init.lua ffluci/sys.lua
|
||||
|
||||
DIRECTORIES = dist/ffluci/model dist/ffluci/controller/public dist/ffluci/controller/admin dist/ffluci/i18n dist/ffluci/view
|
||||
|
||||
|
|
|
@ -25,8 +25,10 @@ limitations under the License.
|
|||
|
||||
]]--
|
||||
module("ffluci.cbi", package.seeall)
|
||||
require("ffluci.template")
|
||||
require("ffluci.util")
|
||||
local class = ffluci.util.class
|
||||
local instanceof = ffluci.util.instanceof
|
||||
|
||||
|
||||
-- Node pseudo abstract class
|
||||
|
@ -36,6 +38,7 @@ function Node.__init__(self, title, description)
|
|||
self.children = {}
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.template = "cbi/node"
|
||||
end
|
||||
|
||||
function Node.append(self, obj)
|
||||
|
@ -43,13 +46,129 @@ function Node.append(self, obj)
|
|||
end
|
||||
|
||||
|
||||
-- CBI Map
|
||||
--[[
|
||||
Map - A map describing a configuration file
|
||||
]]--
|
||||
Map = class(Node)
|
||||
|
||||
function Map.__init__(self, ...)
|
||||
function Map.__init__(self, config, ...)
|
||||
Node.__init__(self, ...)
|
||||
self.config = config
|
||||
self.template = "cbi/map"
|
||||
end
|
||||
|
||||
function Map.render(self)
|
||||
ffluci.template.render(self.template)
|
||||
end
|
||||
|
||||
function Map.section(self, class, ...)
|
||||
if instanceof(class, AbstractClass) then
|
||||
local obj = class(...)
|
||||
obj.map = self
|
||||
table.insert(self.children, obj)
|
||||
return obj
|
||||
else
|
||||
error("class must be a descendent of AbstractSection")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
AbstractSection
|
||||
]]--
|
||||
AbstractSection = class(Node)
|
||||
|
||||
function AbstractSection.__init__(self, ...)
|
||||
Node.__init__(self, ...)
|
||||
end
|
||||
|
||||
function Map.render(self, template)
|
||||
-- ToDo
|
||||
function AbstractSection.option(self, class, ...)
|
||||
if instanceof(class, AbstractValue) then
|
||||
local obj = class(...)
|
||||
obj.section = self
|
||||
obj.map = self.map
|
||||
table.insert(self.children, obj)
|
||||
return obj
|
||||
else
|
||||
error("class must be a descendent of AbstractValue")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--[[
|
||||
NamedSection - A fixed configuration section defined by its name
|
||||
]]--
|
||||
NamedSection = class(AbstractSection)
|
||||
|
||||
function NamedSection.__init__(self, section, ...)
|
||||
AbstractSection.__init__(self, ...)
|
||||
self.section = section
|
||||
self.template = "cbi/nsection"
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
TypedSection - A (set of) configuration section(s) defined by the type
|
||||
addremove: Defines whether the user can add/remove sections of this type
|
||||
anonymous: Allow creating anonymous sections
|
||||
valid: a table with valid names or a function returning nil if invalid
|
||||
]]--
|
||||
TypedSection = class(AbstractSection)
|
||||
|
||||
function TypedSection.__init__(self, sectiontype, ...)
|
||||
AbstractSection.__init__(self, ...)
|
||||
self.sectiontype = sectiontype
|
||||
self.template = "cbi/tsection"
|
||||
|
||||
self.addremove = true
|
||||
self.anonymous = false
|
||||
self.valid = nil
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
AbstractValue - An abstract Value Type
|
||||
null: Value can be empty
|
||||
valid: A table with valid names or a function returning nil if invalid
|
||||
depends: A table of option => value pairs of which one must be true
|
||||
]]--
|
||||
AbstractValue = class(Node)
|
||||
|
||||
function AbstractValue.__init__(self, option, ...)
|
||||
Node.__init__(self, ...)
|
||||
self.option = option
|
||||
|
||||
self.null = true
|
||||
self.valid = nil
|
||||
self.depends = nil
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Value - A one-line value
|
||||
maxlength: The maximum length
|
||||
isnumber: The value must be a valid (floating point) number
|
||||
isinteger: The value must be a valid integer
|
||||
]]--
|
||||
Value = class(AbstractValue)
|
||||
|
||||
function Value.__init__(self, ...)
|
||||
AbstractValue.__init__(self, ...)
|
||||
self.template = "cbi/value"
|
||||
|
||||
self.maxlength = nil
|
||||
self.isnumber = false
|
||||
self.isinteger = false
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Boolean - A simple boolean value
|
||||
]]--
|
||||
Boolean = class(AbstractValue)
|
||||
|
||||
function Boolean.__init__(self, ...)
|
||||
AbstractValue.__init__(self, ...)
|
||||
self.template = "cbi/boolean"
|
||||
end
|
|
@ -104,13 +104,9 @@ end
|
|||
function error404(message)
|
||||
message = message or "Not Found"
|
||||
|
||||
local s, t = pcall(ffluci.template.Template, "error404")
|
||||
|
||||
if not s then
|
||||
if not pcall(ffluci.template.render, "error404") then
|
||||
ffluci.http.textheader()
|
||||
print(message)
|
||||
else
|
||||
t:render()
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
@ -119,13 +115,9 @@ end
|
|||
function error500(message)
|
||||
ffluci.http.status(500, "Internal Server Error")
|
||||
|
||||
local s, t = pcall(ffluci.template.Template, "error500")
|
||||
|
||||
if not s then
|
||||
if not pcall(ffluci.template.render, "error500") then
|
||||
ffluci.http.textheader()
|
||||
print(message)
|
||||
else
|
||||
t:render()
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
@ -155,12 +147,8 @@ function simpleview(request)
|
|||
local disp = require("ffluci.dispatcher")
|
||||
|
||||
i18n.loadc(request.module)
|
||||
local s, t = pcall(tmpl.Template, request.module .. "/" .. request.action)
|
||||
|
||||
if not s then
|
||||
if not pcall(tmpl.render, request.module .. "/" .. request.action) then
|
||||
disp.error404()
|
||||
else
|
||||
t:render()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ function exec(command)
|
|||
return data
|
||||
end
|
||||
|
||||
|
||||
-- Runs "command" and returns its output as a array of lines
|
||||
function execl(command)
|
||||
local pp = io.popen(command)
|
||||
|
@ -108,6 +109,7 @@ function execl(command)
|
|||
return data
|
||||
end
|
||||
|
||||
|
||||
-- Populate obj in the scope of f as key
|
||||
function extfenv(f, key, obj)
|
||||
local scope = getfenv(f)
|
||||
|
@ -116,6 +118,19 @@ function extfenv(f, key, obj)
|
|||
end
|
||||
|
||||
|
||||
-- Checks whether an object is an instanceof class
|
||||
function instanceof(object, class)
|
||||
local meta = getmetatable(object)
|
||||
while meta and meta.__index do
|
||||
if meta.__index == class then
|
||||
return true
|
||||
end
|
||||
meta = getmetatable(meta.__index)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
-- Updates the scope of f with "extscope"
|
||||
function updfenv(f, extscope)
|
||||
local scope = getfenv(f)
|
||||
|
@ -125,6 +140,7 @@ function updfenv(f, extscope)
|
|||
setfenv(f, scope)
|
||||
end
|
||||
|
||||
|
||||
-- Returns the filename of the calling script
|
||||
function __file__()
|
||||
return debug.getinfo(2, 'S').source:sub(2)
|
||||
|
|
|
@ -11,6 +11,7 @@ require("ffluci.http").htmlheader()
|
|||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="<%=media%>/cascade.css" />
|
||||
<title>FFLuCI</title>
|
||||
<% if addheaders then write(addheaders) end %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
|
|
Loading…
Reference in New Issue