2 FFLuCI - Configuration Bind Interface
5 Offers an interface for binding confiugration values to certain
6 data types. Supports value and range validation and basic dependencies.
12 Copyright 2008 Steven Barth <steven@midlink.org>
14 Licensed under the Apache License, Version 2.0 (the "License");
15 you may not use this file except in compliance with the License.
16 You may obtain a copy of the License at
18 http://www.apache.org/licenses/LICENSE-2.0
20 Unless required by applicable law or agreed to in writing, software
21 distributed under the License is distributed on an "AS IS" BASIS,
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 See the License for the specific language governing permissions and
24 limitations under the License.
27 module("ffluci.cbi", package.seeall)
28 require("ffluci.template")
29 require("ffluci.util")
30 require("ffluci.http")
31 require("ffluci.model.uci")
32 local Template = ffluci.template.Template
33 local class = ffluci.util.class
34 local instanceof = ffluci.util.instanceof
37 -- Node pseudo abstract class
40 function Node.__init__(self, title, description)
43 self.description = description
44 self.template = "cbi/node"
47 function Node.append(self, obj)
48 table.insert(self.children, obj)
51 function Node.parse(self)
52 for k, child in ipairs(self.children) do
57 function Node.render(self)
58 ffluci.template.render(self.template)
63 Map - A map describing a configuration file
67 function Map.__init__(self, config, ...)
68 Node.__init__(self, ...)
70 self.template = "cbi/map"
73 function Map.section(self, class, ...)
74 if instanceof(class, AbstractSection) then
75 local obj = class(...)
77 obj.config = self.config
81 error("class must be a descendent of AbstractSection")
85 function Map.read(self)
86 self.ucidata = self.ucidata or ffluci.model.uci.show(self.config)
93 AbstractSection = class(Node)
95 function AbstractSection.__init__(self, sectiontype, ...)
96 Node.__init__(self, ...)
97 self.sectiontype = sectiontype
100 function AbstractSection.option(self, class, ...)
101 if instanceof(class, AbstractValue) then
102 local obj = class(...)
104 obj.config = self.config
108 error("class must be a descendent of AbstractValue")
115 NamedSection - A fixed configuration section defined by its name
117 NamedSection = class(AbstractSection)
119 function NamedSection.__init__(self, section, ...)
120 AbstractSection.__init__(self, ...)
121 self.template = "cbi/nsection"
123 self.section = section
126 function NamedSection.option(self, ...)
127 local obj = AbstractSection.option(self, ...)
128 obj.section = self.section
134 TypedSection - A (set of) configuration section(s) defined by the type
135 addremove: Defines whether the user can add/remove sections of this type
136 anonymous: Allow creating anonymous sections
137 valid: a table with valid names or a function returning nil if invalid
139 TypedSection = class(AbstractSection)
141 function TypedSection.__init__(self, ...)
142 AbstractSection.__init__(self, ...)
143 self.template = "cbi/tsection"
145 self.addremove = true
146 self.anonymous = false
152 AbstractValue - An abstract Value Type
153 null: Value can be empty
154 valid: A function returning the value if it is valid otherwise nil
155 depends: A table of option => value pairs of which one must be true
156 default: The default value
158 AbstractValue = class(Node)
160 function AbstractValue.__init__(self, option, ...)
161 Node.__init__(self, ...)
170 function AbstractValue.formvalue(self)
171 local key = "uci."..self.map.config.."."..self.section.."."..self.option
172 return ffluci.http.formvalue(key)
175 function AbstractValue.ucivalue(self)
176 return self.map.read()[self.section][self.option]
179 function AbstractValue.validate(self, value)
180 return ffluci.util.validate(value, nil, nil, self.valid)
183 function AbstractValue.write(self, value)
184 ffluci.model.uci.set(self.config, self.section, self.option, value)
189 Value - A one-line value
190 maxlength: The maximum length
191 isnumber: The value must be a valid (floating point) number
192 isinteger: The value must be a valid integer
194 Value = class(AbstractValue)
196 function Value.__init__(self, ...)
197 AbstractValue.__init__(self, ...)
198 self.template = "cbi/value"
201 self.isnumber = false
202 self.isinteger = false
207 ListValue - A one-line value predefined in a list
209 ListValue = class(AbstractValue)
211 function ListValue.__init__(self, ...)
212 AbstractValue.__init__(self, ...)
213 self.template = "cbi/lvalue"
218 function ListValue.addValue(self, key, val)