* 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:
Steven Barth 2008-03-17 21:38:03 +00:00
parent cfe8fc894f
commit f41539e549
5 changed files with 145 additions and 21 deletions

View file

@ -5,8 +5,8 @@ FILES = ffluci/config.lua
CFILES = ffluci/util.lua ffluci/http.lua \ CFILES = ffluci/util.lua ffluci/http.lua \
ffluci/fs.lua ffluci/i18n.lua ffluci/model/uci.lua \ ffluci/fs.lua ffluci/i18n.lua ffluci/model/uci.lua \
ffluci/template.lua ffluci/dispatcher.lua ffluci/menu.lua \ ffluci/template.lua ffluci/cbi.lua ffluci/dispatcher.lua \
ffluci/init.lua ffluci/sys.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 DIRECTORIES = dist/ffluci/model dist/ffluci/controller/public dist/ffluci/controller/admin dist/ffluci/i18n dist/ffluci/view

View file

@ -25,8 +25,10 @@ limitations under the License.
]]-- ]]--
module("ffluci.cbi", package.seeall) module("ffluci.cbi", package.seeall)
require("ffluci.template")
require("ffluci.util") require("ffluci.util")
local class = ffluci.util.class local class = ffluci.util.class
local instanceof = ffluci.util.instanceof
-- Node pseudo abstract class -- Node pseudo abstract class
@ -36,6 +38,7 @@ function Node.__init__(self, title, description)
self.children = {} self.children = {}
self.title = title self.title = title
self.description = description self.description = description
self.template = "cbi/node"
end end
function Node.append(self, obj) function Node.append(self, obj)
@ -43,13 +46,129 @@ function Node.append(self, obj)
end end
-- CBI Map --[[
Map - A map describing a configuration file
]]--
Map = class(Node) 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, ...) Node.__init__(self, ...)
end end
function Map.render(self, template) function AbstractSection.option(self, class, ...)
-- ToDo 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 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

View file

@ -104,13 +104,9 @@ end
function error404(message) function error404(message)
message = message or "Not Found" message = message or "Not Found"
local s, t = pcall(ffluci.template.Template, "error404") if not pcall(ffluci.template.render, "error404") then
if not s then
ffluci.http.textheader() ffluci.http.textheader()
print(message) print(message)
else
t:render()
end end
return false return false
end end
@ -119,13 +115,9 @@ end
function error500(message) function error500(message)
ffluci.http.status(500, "Internal Server Error") ffluci.http.status(500, "Internal Server Error")
local s, t = pcall(ffluci.template.Template, "error500") if not pcall(ffluci.template.render, "error500") then
if not s then
ffluci.http.textheader() ffluci.http.textheader()
print(message) print(message)
else
t:render()
end end
return false return false
end end
@ -155,12 +147,8 @@ function simpleview(request)
local disp = require("ffluci.dispatcher") local disp = require("ffluci.dispatcher")
i18n.loadc(request.module) i18n.loadc(request.module)
local s, t = pcall(tmpl.Template, request.module .. "/" .. request.action) if not pcall(tmpl.render, request.module .. "/" .. request.action) then
if not s then
disp.error404() disp.error404()
else
t:render()
end end
end end

View file

@ -92,6 +92,7 @@ function exec(command)
return data return data
end end
-- Runs "command" and returns its output as a array of lines -- Runs "command" and returns its output as a array of lines
function execl(command) function execl(command)
local pp = io.popen(command) local pp = io.popen(command)
@ -108,6 +109,7 @@ function execl(command)
return data return data
end end
-- Populate obj in the scope of f as key -- Populate obj in the scope of f as key
function extfenv(f, key, obj) function extfenv(f, key, obj)
local scope = getfenv(f) local scope = getfenv(f)
@ -116,6 +118,19 @@ function extfenv(f, key, obj)
end 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" -- Updates the scope of f with "extscope"
function updfenv(f, extscope) function updfenv(f, extscope)
local scope = getfenv(f) local scope = getfenv(f)
@ -125,6 +140,7 @@ function updfenv(f, extscope)
setfenv(f, scope) setfenv(f, scope)
end end
-- Returns the filename of the calling script -- Returns the filename of the calling script
function __file__() function __file__()
return debug.getinfo(2, 'S').source:sub(2) return debug.getinfo(2, 'S').source:sub(2)

View file

@ -11,6 +11,7 @@ require("ffluci.http").htmlheader()
<head> <head>
<link rel="stylesheet" type="text/css" href="<%=media%>/cascade.css" /> <link rel="stylesheet" type="text/css" href="<%=media%>/cascade.css" />
<title>FFLuCI</title> <title>FFLuCI</title>
<% if addheaders then write(addheaders) end %>
</head> </head>
<body> <body>
<div id="header"> <div id="header">