summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSteven Barth <steven@midlink.org>2008-03-24 21:50:48 +0000
committerSteven Barth <steven@midlink.org>2008-03-24 21:50:48 +0000
commit9fa7e0e92ddae9ff68f50ad20bbdfc8a3c09135a (patch)
treef1d316abaaced25c6d8476e65ad6d50f57013768
parent8e7ed0e8a752bc3f551aabcf2a20807b64e707ed (diff)
* CBI: updates
* UCI: fixed argument escaping
-rw-r--r--contrib/media/cascade.css35
-rw-r--r--src/ffluci/cbi.lua110
-rw-r--r--src/ffluci/i18n/cbi.en4
-rw-r--r--src/ffluci/model/uci.lua25
-rw-r--r--src/ffluci/util.lua4
-rw-r--r--src/ffluci/view/cbi/footer.htm4
-rw-r--r--src/ffluci/view/cbi/header.htm1
-rw-r--r--src/ffluci/view/cbi/lvalue.htm6
-rw-r--r--src/ffluci/view/cbi/tsection.htm12
-rw-r--r--src/ffluci/view/cbi/value.htm3
10 files changed, 177 insertions, 27 deletions
diff --git a/contrib/media/cascade.css b/contrib/media/cascade.css
index 49e51f1c8..7717b184a 100644
--- a/contrib/media/cascade.css
+++ b/contrib/media/cascade.css
@@ -151,3 +151,38 @@ h2 {
.clear {
clear: both;
}
+
+.hidden {
+ display: none;
+}
+
+
+.cbi-value-title, .cbi-lvalue-title {
+ float: left;
+ font-weight: bold;
+ line-height: 2em;
+}
+
+.cbi-value-field, .cbi-lvalue-field {
+ text-align: right;
+}
+
+.cbi-value-description, .cbi-lvalue-description {
+ clear: both;
+ font-style: italic;
+ font-size: 0.8em;
+}
+
+.cbi-value {
+ margin-bottom: 1em;
+}
+
+.cbi-form-separator {
+ margin-top: 1em;
+}
+
+.cbi-tsection-node {
+ margin-top: 1em;
+ border: none;
+ background-color: #eeeeee;
+} \ No newline at end of file
diff --git a/src/ffluci/cbi.lua b/src/ffluci/cbi.lua
index a535dc8b7..ac5c1dd84 100644
--- a/src/ffluci/cbi.lua
+++ b/src/ffluci/cbi.lua
@@ -59,6 +59,8 @@ function load(cbimap)
return nil
end
+ ffluci.i18n.loadc("cbi")
+
return map
end
@@ -137,10 +139,18 @@ function Map.section(self, class, ...)
end
end
+function Map.add(self, sectiontype)
+ return self.uci:add(self.config, sectiontype)
+end
+
function Map.set(self, section, option, value)
return self.uci:set(self.config, section, option, value)
end
+function Map.remove(self, section, option)
+ return self.uci:del(self.config, section, option)
+end
+
--[[
AbstractSection
]]--
@@ -188,7 +198,8 @@ 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
+ valid: a list of names or a validation function for creating sections
+ scope: a list of names or a validation function for editing sections
]]--
TypedSection = class(AbstractSection)
@@ -196,12 +207,58 @@ function TypedSection.__init__(self, ...)
AbstractSection.__init__(self, ...)
self.template = "cbi/tsection"
- self.addremove = true
- self.anonymous = false
- self.valid = nil
+ self.addremove = true
+ self.anonymous = false
+ self.valid = nil
+ self.scope = nil
+end
+
+function TypedSection.create(self, name)
+ if name then
+ self.map:set(name, nil, self.sectiontype)
+ else
+ name = self.map:add(self.sectiontype)
+ end
+
+ for k,v in pairs(self.children) do
+ if v.default then
+ self.map:set(name, v.option, v.default)
+ end
+ end
end
function TypedSection.parse(self)
+ if self.addremove then
+ local crval = "cbi.cts." .. self.config .. "." .. self.sectiontype
+ local name = ffluci.http.formvalue(crval)
+ if self.anonymous then
+ if name then
+ self:create()
+ end
+ else
+ if name then
+ name = ffluci.util.validate(name, self.valid)
+ if not name then
+ self.err_invalid = true
+ end
+ if name and name:len() > 0 then
+ self:create(name)
+ end
+ end
+ end
+
+
+ crval = "cbi.rts." .. self.config
+ name = ffluci.http.formvalue(crval)
+ if type(name) == "table" then
+ for k,v in pairs(name) do
+ if ffluci.util.validate(k, self.valid) then
+ self:remove(k)
+ end
+ end
+ end
+ end
+
for k, v in pairs(self:ucisections()) do
for i, node in ipairs(self.children) do
node.section = k
@@ -210,6 +267,10 @@ function TypedSection.parse(self)
end
end
+function TypedSection.remove(self, name)
+ return self.map:remove(name)
+end
+
function TypedSection.render_children(self, section)
for k, node in ipairs(self.children) do
node.section = section
@@ -221,7 +282,9 @@ function TypedSection.ucisections(self)
local sections = {}
for k, v in pairs(self.map.ucidata) do
if v[".type"] == self.sectiontype then
- sections[k] = v
+ if ffluci.util.validate(k, self.scope) then
+ sections[k] = v
+ end
end
end
return sections
@@ -234,6 +297,7 @@ AbstractValue - An abstract Value Type
valid: A function returning the value if it is valid otherwise nil
depends: A table of option => value pairs of which one must be true
default: The default value
+ size: The size of the input fields
]]--
AbstractValue = class(Node)
@@ -244,6 +308,7 @@ function AbstractValue.__init__(self, option, ...)
self.valid = nil
self.depends = nil
self.default = nil
+ self.size = nil
end
function AbstractValue.formvalue(self)
@@ -252,18 +317,24 @@ function AbstractValue.formvalue(self)
end
function AbstractValue.parse(self)
- local fvalue = self:validate(self:formvalue())
- if fvalue and not (fvalue == self:ucivalue()) then
- self:write(fvalue)
- end
+ local fvalue = self:formvalue()
+ if fvalue then
+ fvalue = self:validate(fvalue)
+ if not fvalue then
+ self.err_invalid = true
+ end
+ if fvalue and not (fvalue == self:ucivalue()) then
+ self:write(fvalue)
+ end
+ end
end
function AbstractValue.ucivalue(self)
return self.map.ucidata[self.section][self.option]
end
-function AbstractValue.validate(self, value)
- return ffluci.util.validate(value, nil, nil, self.valid)
+function AbstractValue.validate(self, val)
+ return ffluci.util.validate(val, self.valid)
end
function AbstractValue.write(self, value)
@@ -271,11 +342,14 @@ function AbstractValue.write(self, value)
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
+ ispositive: The value must be positive (and a number)
]]--
Value = class(AbstractValue)
@@ -283,9 +357,17 @@ function Value.__init__(self, ...)
AbstractValue.__init__(self, ...)
self.template = "cbi/value"
- self.maxlength = nil
- self.isnumber = false
- self.isinteger = false
+ self.maxlength = nil
+ self.isnumber = false
+ self.isinteger = false
+end
+
+function Value.validate(self, val)
+ if self.maxlength and tostring(val):len() > self.maxlength then
+ val = nil
+ end
+
+ return ffluci.util.validate(val, self.valid, self.isnumber, self.isinteger)
end
diff --git a/src/ffluci/i18n/cbi.en b/src/ffluci/i18n/cbi.en
new file mode 100644
index 000000000..7c159ce50
--- /dev/null
+++ b/src/ffluci/i18n/cbi.en
@@ -0,0 +1,4 @@
+uci_add = "Add entry"
+uci_del = "Remove entry"
+uci_save = "Save configuration"
+uci_reset = "Reset form" \ No newline at end of file
diff --git a/src/ffluci/model/uci.lua b/src/ffluci/model/uci.lua
index 5faffe548..2d6702b57 100644
--- a/src/ffluci/model/uci.lua
+++ b/src/ffluci/model/uci.lua
@@ -79,6 +79,16 @@ function commit(...)
end
+-- Wrapper for "uci del"
+function Session.del(self, config, section, option)
+ return self:_uci2("del " .. _path(config, section, option))
+end
+
+function del(...)
+ return default:del(...)
+end
+
+
-- Wrapper for "uci get"
function Session.get(self, config, section, option)
return self:_uci("get " .. _path(config, section, option))
@@ -173,12 +183,15 @@ function _path(...)
-- Not using ipairs because it is not reliable in case of nil arguments
arg.n = nil
for k,v in pairs(arg) do
- if k == 1 then
- result = "'" .. v:gsub("['.]", "") .. "'"
- elseif k < 4 then
- result = result .. ".'" .. v:gsub("['.]", "") .. "'"
- elseif k == 4 then
- result = result .. "='" .. v:gsub("'", "") .. "'"
+ if v then
+ v = tostring(v)
+ if k == 1 then
+ result = "'" .. v:gsub("['.]", "") .. "'"
+ elseif k < 4 then
+ result = result .. ".'" .. v:gsub("['.]", "") .. "'"
+ elseif k == 4 then
+ result = result .. "='" .. v:gsub("'", "") .. "'"
+ end
end
end
return result
diff --git a/src/ffluci/util.lua b/src/ffluci/util.lua
index 38f33a20d..caa8e41de 100644
--- a/src/ffluci/util.lua
+++ b/src/ffluci/util.lua
@@ -156,12 +156,12 @@ end
-- Validates a variable
-function validate(value, cast_number, cast_int, valid)
+function validate(value, valid, cast_number, cast_int)
if cast_number or cast_int then
value = tonumber(value)
end
- if cast_int and not(value % 1 == 0) then
+ if cast_int and value and not(value % 1 == 0) then
value = nil
end
diff --git a/src/ffluci/view/cbi/footer.htm b/src/ffluci/view/cbi/footer.htm
index 8fc212b88..230a17da8 100644
--- a/src/ffluci/view/cbi/footer.htm
+++ b/src/ffluci/view/cbi/footer.htm
@@ -1,3 +1,5 @@
- <input type="submit" /> <input type="reset" />
+ <hr class="cbi-form-separator" />
+ <input type="submit" value="<%:cbi_save Speichern%>" />
+ <input type="reset" value="<%:cbi_reset Zurücksetzen%>" />
</form>
<%+footer%> \ No newline at end of file
diff --git a/src/ffluci/view/cbi/header.htm b/src/ffluci/view/cbi/header.htm
index bd3607f11..b11ed3b70 100644
--- a/src/ffluci/view/cbi/header.htm
+++ b/src/ffluci/view/cbi/header.htm
@@ -1,2 +1,3 @@
<%+header%>
<form method="post" action="<%=os.getenv("REQUEST_URI")%>">
+ <input type="submit" value="<%:cbi_save Speichern%>" class="hidden" />
diff --git a/src/ffluci/view/cbi/lvalue.htm b/src/ffluci/view/cbi/lvalue.htm
index 6a9941959..739d675c4 100644
--- a/src/ffluci/view/cbi/lvalue.htm
+++ b/src/ffluci/view/cbi/lvalue.htm
@@ -1,11 +1,11 @@
<div class="cbi-lvalue">
<div class="cbi-lvalue-title"><%=self.title%></div>
<div class="cbi-lvalue-field">
- <select name="cbid.<%=self.config.."."..self.section.."."..self.option%>">
+ <select name="cbid.<%=self.config.."."..self.section.."."..self.option%>"<% if self.size then %> size="<%=self.size%>"<% end %>>
<%for k, v in pairs(self.list) do%>
- <option value="<%=k%>"><%=v%></option>
+ <option<% if self:ucivalue() == k then %> selected="selected"<% end %> value="<%=k%>"><%=v%></option>
<% end %>
</select>
</div>
- <div class="cbi-value-description"><%=self.description%></div>
+ <div class="cbi-lvalue-description"><%=self.description%></div>
</div> \ No newline at end of file
diff --git a/src/ffluci/view/cbi/tsection.htm b/src/ffluci/view/cbi/tsection.htm
index bd19ecf59..987449406 100644
--- a/src/ffluci/view/cbi/tsection.htm
+++ b/src/ffluci/view/cbi/tsection.htm
@@ -5,7 +5,19 @@
<fieldset class="cbi-tsection-node" id="cbi-<%=self.config%>-<%=k%>">
<% if not self.anonymous then %><legend><%=k%></legend><% end %>
<% self:render_children(k) %>
+ <% if self.addremove then %>
+ <input type="submit" name="cbi.rts.<%=self.config%>.<%=k%>" value="<%:cbi_del Eintrag entfernen%>" />
+ <% end %>
</fieldset>
<br />
<% end %>
+<% if self.addremove then %>
+ <div class="cbi-tsection-create">
+ <% if self.anonymous then %>
+ <input type="submit" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>" value="<%:cbi_add Eintrag hinzufügen%>" />
+ <% else %><input type="text" class="cbi-tsection-create-name" name="cbi.cts.<%=self.config%>.<%=self.sectiontype%>" />
+ <input type="submit" value="<%:cbi_add Eintrag hinzufügen%>" />
+ <% end %><% if self.err_invalid then %><div class="cbi-error"><%:cbi_invalid Fehler: Ungültiger Wert%></div><% end %>
+ </div>
+<% end %>
</div>
diff --git a/src/ffluci/view/cbi/value.htm b/src/ffluci/view/cbi/value.htm
index a898d08c1..bbb5f5f3b 100644
--- a/src/ffluci/view/cbi/value.htm
+++ b/src/ffluci/view/cbi/value.htm
@@ -1,7 +1,8 @@
<div class="cbi-value">
<div class="cbi-value-title"><%=self.title%></div>
<div class="cbi-value-field">
- <input type="text" name="cbid.<%=self.config.."."..self.section.."."..self.option%>" value="<%=(self:ucivalue() or "")%>" />
+ <input type="text" <% if self.size then %>size="<%=self.size%>" <% end %><% if self.maxlength then %>maxlength="<%=self.maxlength%>" <% end %>name="cbid.<%=self.config.."."..self.section.."."..self.option%>" value="<%=(self:ucivalue() or "")%>" />
</div>
<div class="cbi-value-description"><%=self.description%></div>
+ <% if self.err_invalid then %><div class="cbi-error"><%:cbi_invalid Fehler: Ungültiger Wert%></div><% end %>
</div> \ No newline at end of file