X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fcbi%2Fluasrc%2Fcbi.lua;h=7e2f53c80c06a79a710358ed63fea17aae327398;hb=f94fb5ac1843ae47a28cfa1ef2ea4cbdd6b239f2;hp=0ec2ff815de7095fe94c56fefc5ac6ff9498d62c;hpb=bdb4bbde130ba4cfb86746dde2905fc12b94175f;p=project%2Fluci.git diff --git a/libs/cbi/luasrc/cbi.lua b/libs/cbi/luasrc/cbi.lua index 0ec2ff815..7e2f53c80 100644 --- a/libs/cbi/luasrc/cbi.lua +++ b/libs/cbi/luasrc/cbi.lua @@ -39,6 +39,9 @@ FORM_NODATA = 0 FORM_VALID = 1 FORM_INVALID = -1 +CREATE_PREFIX = "cbi.cts." +REMOVE_PREFIX = "cbi.rts." + -- Loads a CBI map from given file, creating an environment and returns it function load(cbimap, ...) require("luci.fs") @@ -89,10 +92,10 @@ function Node._i18n(self, config, section, option, title, description) -- i18n loaded? if type(luci.i18n) == "table" then - local key = config:gsub("[^%w]+", "") + local key = config and config:gsub("[^%w]+", "") or "" if section then key = key .. "_" .. section:lower():gsub("[^%w]+", "") end - if option then key = key .. "_" .. option:lower():gsub("[^%w]+", "") end + if option then key = key .. "_" .. tostring(option):lower():gsub("[^%w]+", "") end self.title = title or luci.i18n.translate( key, option or section or config ) self.description = description or luci.i18n.translate( key .. "_desc", "" ) @@ -137,6 +140,10 @@ function Template.__init__(self, template) self.template = template end +function Template.render(self) + luci.template.render(self.template, {self=self}) +end + --[[ Map - A map describing a configuration file @@ -233,6 +240,20 @@ function Map.get(self, section, option) end end +-- UCI stateget +function Map.stateget(self, section, option) + return uci.get_statevalue(self.config, section, option) +end + + +--[[ +Page - A simple node +]]-- + +Page = class(Node) +Page.__init__ = Node.__init__ +Page.parse = function() end + --[[ SimpleForm - A Simple non-UCI form @@ -248,11 +269,17 @@ function SimpleForm.__init__(self, config, title, description, data) end function SimpleForm.parse(self, ...) - Node.parse(self, 1, ...) + if luci.http.formvalue("cbi.submit") then + Node.parse(self, 1, ...) + end local valid = true - for i, v in ipairs(self.children) do - valid = valid and not v.tag_missing[1] and not v.tag_invalid[1] + for k, j in ipairs(self.children) do + for i, v in ipairs(j.children) do + valid = valid + and (not v.tag_missing or not v.tag_missing[1]) + and (not v.tag_invalid or not v.tag_invalid[1]) + end end local state = @@ -260,7 +287,7 @@ function SimpleForm.parse(self, ...) or valid and 1 or -1 - self.dorender = self:handle(state) + self.dorender = self:handle(state, self.data) ~= false end function SimpleForm.render(self, ...) @@ -269,11 +296,33 @@ function SimpleForm.render(self, ...) end end --- Creates a child section +function SimpleForm.section(self, class, ...) + if instanceof(class, AbstractSection) then + local obj = class(self, ...) + self:append(obj) + return obj + else + error("class must be a descendent of AbstractSection") + end +end + +-- Creates a child field function SimpleForm.field(self, class, ...) + local section + for k, v in ipairs(self.children) do + if instanceof(v, SimpleSection) then + section = v + break + end + end + if not section then + section = self:section(SimpleSection) + end + if instanceof(class, AbstractValue) then local obj = class(self, ...) - self:append(obj) + obj.track_missing = true + section:append(obj) return obj else error("class must be a descendent of AbstractValue") @@ -422,6 +471,42 @@ function AbstractSection.create(self, section) end +SimpleSection = class(AbstractSection) + +function SimpleSection.__init__(self, form, ...) + AbstractSection.__init__(self, form, nil, ...) + self.template = "cbi/nullsection" +end + + +Table = class(AbstractSection) + +function Table.__init__(self, form, data, ...) + local datasource = {} + datasource.config = "table" + self.data = data + + function datasource.get(self, section, option) + return data[section][option] + end + + AbstractSection.__init__(self, datasource, "table", ...) + self.template = "cbi/tblsection" + self.rowcolors = true + self.anonymous = true +end + +function Table.cfgsections(self) + local sections = {} + + for i, v in pairs(self.data) do + table.insert(sections, i) + end + + return sections +end + + --[[ NamedSection - A fixed configuration section defined by its name @@ -505,7 +590,7 @@ end function TypedSection.parse(self) if self.addremove then -- Create - local crval = "cbi.cts." .. self.config .. "." .. self.sectiontype + local crval = CREATE_PREFIX .. self.config .. "." .. self.sectiontype local name = luci.http.formvalue(crval) if self.anonymous then if name then @@ -531,7 +616,7 @@ function TypedSection.parse(self) end -- Remove - crval = "cbi.rts." .. self.config + crval = REMOVE_PREFIX .. self.config name = luci.http.formvaluetable(crval) for k,v in pairs(name) do if self:cfgvalue(k) and self:checkscope(k) then @@ -602,10 +687,12 @@ function AbstractValue.__init__(self, map, option, ...) self.tag_missing = {} self.deps = {} + self.track_missing = false self.rmempty = false self.default = nil self.size = nil self.optional = false + self.stateful = false end -- Add a dependencie to another section field @@ -638,17 +725,17 @@ function AbstractValue.parse(self, section) local cvalue = self:cfgvalue(section) if fvalue and fvalue ~= "" then -- If we have a form value, write it to UCI - fvalue = self:transform(self:validate(fvalue)) + fvalue = self:transform(self:validate(fvalue, section)) if not fvalue then self.tag_invalid[section] = true end - if fvalue and not (fvalue == self:cfgvalue(section)) then + if fvalue and not (fvalue == cvalue) then self:write(section, fvalue) end else -- Unset the UCI or error if self.rmempty or self.optional then self:remove(section) - elseif not fvalue or fvalue ~= cvalue then + elseif self.track_missing and (not fvalue or fvalue ~= cvalue) then self.tag_missing[section] = true end end @@ -667,10 +754,10 @@ function AbstractValue.render(self, s, scope) if cond then return string.format( ' %s="%s"', tostring(key), - tostring( val + luci.util.pcdata(tostring( val or scope[key] or (type(self[key]) ~= "function" and self[key]) - or "" ) + or "" )) ) else return '' @@ -687,7 +774,9 @@ end -- Return the UCI value of this object function AbstractValue.cfgvalue(self, section) - return self.map:get(section, self.option) + return self.stateful + and self.map:stateget(section, self.option) + or self.map:get(section, self.option) end -- Validate the form value @@ -865,3 +954,14 @@ function MultiValue.validate(self, val) return result end + +--[[ +TextValue - A multi-line value + rows: Rows +]]-- +TextValue = class(AbstractValue) + +function TextValue.__init__(self, ...) + AbstractValue.__init__(self, ...) + self.template = "cbi/tvalue" +end