一、CBI控件类型汇总
- CBI模型是描述UCI配置文件结构的Lua文件,并且CBI解析器将lua文件转为HTML呈现给用户 。
- 所有 CBI 模型文件必须返回类型为 luci.cbi.Map 的对象。
- CBI 模型文件的范围由 luci.cbi 模块的内容和 luci.i18n 的转换函数自动扩展。
名称 | 描述 | 继承自 | 模板 |
---|---|---|---|
NamedSection | A fixed configuration section defined by its name | NamedSection = class(AbstractSection) | cbi/nsection |
TypedSection | A (set of) configuration section(s) defined by the type | TypedSection = class(AbstractSection) | cbi/tsection |
Node | Node pseudo abstract class | Node = class() | cbi/node |
Template | A simple template element | Template = class(Node) | |
Map | A map describing a configuration file | Map = class(Node) | cbi/map |
Compound | Container | Compound = class(Node) | cbi/compound |
Delegator | Node controller | Delegator = class(Node) | cbi/delegator |
SimpleForm | A Simple non-UCI form | SimpleForm = class(Node) | cbi/simpleform |
Form | Form = class(SimpleForm) | ||
AbstractSection | AbstractSection = class(Node) | ||
SimpleSection | SimpleSection = class(AbstractSection) | cbi/nullsection | |
Table | Table = class(AbstractSection) | cbi/tblsection | |
AbstractValue | An abstract Value Type | AbstractValue = class(Node) | |
Value | A one-line value | Value = class(AbstractValue) | cbi/value |
DummyValue | This does nothing except being there | DummyValue = class(AbstractValue) | cbi/dvalue |
Flag | A flag being enabled or disabled | Flag = class(AbstractValue) | cbi/fvalue |
ListValue | A one-line value predefined in a list | ListValue = class(AbstractValue) | cbi/lvalue |
MultiValue | Multiple delimited values | MultiValue = class(AbstractValue) | cbi/mvalue |
StaticList | StaticList = class(MultiValue) | ||
DynamicList | DynamicList = class(AbstractValue) | cbi/dynlist | |
TextValue | A multi-line value | TextValue = class(AbstractValue) | cbi/tvalue |
Button | Button = class(AbstractValue) | cbi/button | |
FileUpload | FileUpload = class(AbstractValue) | cbi/upload | |
FileBrowser | FileBrowser = class(AbstractValue) | cbi/browser | |
Page | A simple node | Page = class(Node) |
二、CBI常用控件用法详解
2.1 class Map (config, title, description)
- This is the root object of the model.。
- 模型的根对象
参数说明:
- config: configuration filename to be mapped, see UCI documentation and the files in /etc/config
- UCI详解 见 Openwrt:LuCI之UCI(三)
- title: 页面显示名称
- description: 页面显示详细描述
方法说明:
- function :section(sectionclass, …)
- sectionclass: a class object of the section。// section的类对象
- additional parameters passed to the constructor of the section class。//传递给section类的构造函数的其他参数
- 补充
section(TypedSection, type, title, description)
section(NamedSection, name, type, title, description)
section 对象有一些属性如下:template: html 模板, 默认为"cbi/tsection"
addremove: 是否可以增加和删除, 默认为 false
anonymous: 是否为匿名 section, 默认为 false
- 网页图例
2.2 class NamedSection(name, type, title, description)
- An object describing an UCI section selected by the name. //根据type来解析一个UCI section
- To instantiate use:
Map:section(NamedSection, "name", "type", "title", "description")
参数说明:
- name: UCI section名字, config type section
- type: UCI section类型, config type section
- type可选:Value、 DynamicList、 Flag、 ListValue、TextValue、MultiValue、DummyValue、StaticList、Button …
- title: 页面显示名称
- description: 页面显示详细描述
对象属性:
- property.addremove = false
- Allows the user to remove and recreate the configuration section. //允许用户删除并重新创建配置section。
- property.anonymous = true
- true 页面不显示section名字
- false 页面显示section名字
- property.dynamic = false
- ture 将section 标记为动态
- Dynamic sections can contain an undefinded number of completely userdefined options. //将此部分标记为动态。动态section可以包含未找到的完全用户定义的选项数。
- property.optional = true
- 解析可选的options
方法说明:
- function :option(optionclass, …)
- Creates a new option //创建新选项
- ptionclass: a class object of the section //section的类对象
- additional parameters passed to the constructor of the option class //传递给选项类的构造函数的其他参数
- 补充
option(type, name, title, description)
option对象有一些属性如下:rmempty:如果为空值则删除该选项,默认为 true
default: 默认值, 如果为空值,则设置为该默认值
datatype: 限制输入类型。 例如"and(uinteger,min(1))"限制输入无符号整形而且大于 0, "ip4addr"限制
输入 IPv4 地址, "port"限制输入类型为端口,更多参考/usr/lib/lua/luci/cbi/datatypes.lua
placeholder: 占位符( html5 才支持)
2.3 class TypedSection (type, title, description)
- An object describing a group of UCI sections selected by their type. // 通过类型type选择来描述一组 UCI section的对象。
- To instantiate use:
Map:section(TypedSection, "type", "title", "description")
参数说明:
- type: UCI section类型, config type section
- type可选:Value、 DynamicList、 Flag、 ListValue、TextValue、MultiValue、DummyValue、StaticList、Button …
- title: 页面显示名称
- description: 页面显示详细描述
对象属性:
- property.addremove = false 同NameSection
- property.anonymous = true 同NameSection
- property.template = “cbi/template” 设置此页面的模块
方法说明:
- function :depends(key, value)
- Only show this option field if another option key is set to value in the same section.
If you call this function several times the dependencies will be linked with “or”// 仅当另一个选项键在同一section中设置为值时,才显示此选项字段。如果多次调用此函数,则依赖项将链接为 [或]
- function .filter(self, section) -abstract-
- You can override this function to filter certain sections that will not be parsed. The filter function will be called for every section that should be parsed and returns nil for sections that should be filtered. For all other sections it should return the section name as given in the second parameter. //您可以重写此函数以筛选某些不会解析的部分。对于应分析的每个section,将调用筛选器函数,对于应筛选的section,将返回 nil。对于所有其他section,它应返回第二个参数中给出的section名称。
- function :option(optionclass, …)
- 网页图例
2.4 class Value (option, title, description)
- An object describing an option in a section of a UCI File. Creates a standard text field in the formular.//描述 UCI 文件部分中的选项的对象。在公式中创建标准文本框。(单行文本框)
- To instantiate use:
NamedSection:option(Value, "option", "title", "description")
orTypedSection:option(Value, "option", "title", "description")
参数说明:
- option: UCI option name
- title: 页面显示名称
- description: 页面显示详细描述
对象属性:
- property .default = nil 文本框中缺省的值
- property .maxlength = nil
- The maximum input length (of chars) of the value //值的最大输入长度(字符)
- property .optional = false
- Marks this option as optional, implies .rmempty = true //将此选项标记为可选, .rmempty = true
- property .rmempty = true
- Removes this option from the configuration file when the user enters an empty value //当用户输入空值时,从配置文件中删除此选项
- property .size = nil
- The maximum number of chars displayed by form field //窗体字段显示的最大字符数
- property .password = false
密码输入框
方法说明:
- function :depends(key, value)
- Only show this option field if another option key is set to value in the same section.
If you call this function several times the dependencies will be linked with “or”
- function :value(key, value)
- Convert this text field into a combobox if possible and add a selection option. //如果可能,将此文本字段转换为组合框,并添加选择选项。
- 网页图例
2.5 class ListValue (option, title, description)
- An object describing an option in a section of a UCI File.Creates a list box or list of radio (for selecting one of many choices) in the formular. //描述 UCI File 部分中选项的对象。在公式中创建一个列表框或单选列表(用于选择多种选项之一)(即下拉列表)。
- To instantiate use:
NamedSection:option(ListValue, "option", "title", "description")
orTypedSection:option(ListValue, "option", "title", "description")
参数说明:
- option: UCI option name
- title: 页面显示名称
- description: 页面显示详细描述
对象属性:
property .default = nil 文本框中缺省的值
property .widget = “select”
- select shows a selection list, radio shows a list of radio buttons inside form
//select 显示选择列表,radio 显示表单内单选按钮的列表
- property .optional = false
- property .rmempty = true
- property .size = nil
- The maximum number of chars displayed by form field
方法说明:
- function :depends(key, value)
- function :value(key, value)
- Adds an entry to the selection list.//将条目添加到选择列表中。
- 网页图例
2.6 class Flag (option, title, description)
- An object describing an option with two possible values in a section of a UCI File. Creates a checkbox field in the formular. //描述在 UCI 文件部分中具有两个可能值的选项的对象。在公式中创建复选框。
- To instantiate use:
NamedSection:option(Flag, "option", "title", "description")
orTypedSection:option(Flag, "option", "title", "description")
参数说明:
- option: UCI option name
- title: 页面显示名称
- description: 页面显示详细描述
对象属性:
- property .default = nil The default value
- property .disabled = 0
- the value that should be set if the checkbox is unchecked //取消选中复选框时 应设置的值
- property .enabled = 1
- the value that should be set if the checkbox is checked //选中复选框时 应设置的值
- property .optional = false
- property .rmempty = true
方法说明:
- function :depends (key, value)
- 网页图例
2.7 class MultiValue (option, title, description)
- An object describing an option in a section of a UCI File.Creates a list of checkboxed or a multiselectable list as form fields. //描述 UCI 文件部分中的选项的对象。创建复选框列表或多选列表(非下拉列表)。
- To instantiate use: NamedSection:option(MultiValue, “option”, “title”, “description”)
or TypedSection:option(MultiValue, “option”, “title”, “description”)
参数说明:
- option: UCI option name
- title: 页面显示名称
- description: 页面显示详细描述
对象属性:
- property .widget = “checkbox”
- select shows a selection list, checkbox shows a list of checkboxes inside form //选中显示选择列表,复选框显示表单内的复选框列表
- property .delimiter = " "
-The string which will be used to delimit the values inside stored option //用于分隔存储选项内的值的字符串
- property .default = nil
- property .optional = false
- property .rmempty = true
- property .size = nil
-The size of the form field (only used if property .widget = “select”) //窗体字段的大小(仅当属性 .widget = "选择"时才使用)
方法说明:
- function :depends (key, value)
- function :value(key, value)
- Adds an entry to the list
- 网页图例
2.8 class StaticList (option, title, description)
- Similar to the MultiValue, but stores selected Values into a UCI list instead of a character-separated option. //与MultiValue类似,但将所选值存储到 UCI list中,而不是字符分隔option中。
- (这里可能会有疑问,请看下面操作,当在网页对StaticList和MultiValue 选中四个选项时,保存并应用,查看UCI 中配置文件就可以明白。MultiValue 对应的值存储在option,而StaticList对应的值分别存储在list中)
- 网页图例
2.9 class DynamicList (option, title, description)
- A extensible list of user-defined values. Stores Values into a UCI list //用户定义值的可扩展列表。将值存储到 UCI list中
- 网页图例
2.10 class DummyValue (option, title, description)
- Creates a readonly text in the form. It writes no data to UCI!//在窗体中创建只读文本。它不写入任何数据到UCI!
- To instantiate use:
NamedSection:option(DummyValue, "option", "title", "description")
orTypedSection:option(DummyValue, "option", "title", "description")
参数说明:
- option: UCI option name
- title: 页面显示名称
- description: 页面显示详细描述
方法说明:
- function :depends (key, value)
- 网页图例
2.11 class TextValue (option, title, description)
- An object describing a multi-line textbox in a section in a non-UCI form.// 描述非 UCI 窗体中节中多行文本框的对象。
- 注:与Value的区别就是TextValue可以多行显示,而Value只能单行显示。
- 网页图例
2.12 class Button (option, title, description)
- An object describing a Button in a section in a non-UCI form.//描述非 UCI 窗体中节中的按钮的对象。
属性说明:同Value
- .inputstyle = nil 按钮样式 apply, reset
方法说明:同Value
- 网页图例
2.13 class tab(tabname, title)
- 调用 section 的 tab 函数创建一个名称为 tabname,标题为 title 的 Tab 标签。
- 对应的 option 则使用 taboption
s:taboption(tabname, type, name, title)
在指定的 tabname 下创建一个 option。 - s为section 对象,与之前的控件不同,一个section里面如果有tab控件,会将其他(如Value)控件覆盖掉,所以,要想创建tab选项,必须另外再创建section。
b = m:section(TypedSection, "typedsection2_title", "typedsection2 description")
b:tab("tab1", "Tab1");
b:tab("tab2", "Tab2");
b1=b:taboption("tab1", Value, "tab1_option1", "tab1 Option1");
b2=b:taboption("tab2", Value, "tab2_option2", "tab2 Option2");
- 网页图例
三、实例操作
3.1 示例
- (1)网页整体图例
- (2) lua 文件中CBI控件代码
m = Map("test_file","map title" ,translate("map descrption")) -- cbi_file is the config file in /etc/config
a = m:section(TypedSection, "typedsection1_title", "typedsection1 description") -- info is the section called info in cbi_file
a1 = a:option(Value, "Value_option_name","Value option title", translate("Value option description"));
a2 = a:option(TextValue, "TextValue_option_name","TextValue option title", "TextValue option description");
a3 = a:option(MultiValue , "MultiValue_option_name","MultiValue option title", "MultiValue option description");
a3:value("0", translate("value0"));
a3:value("1", translate("value1"));
a3:value("2", translate("value2"));
a3:value("3", translate("value3"));
a4 = a:option(DummyValue , "DummyValue_option_name","DummyValue option title", "DummyValue option description");
a5 = a:option(ListValue, "Listvalue_option_name","ListValue option title", "ListValue option description");
a5:value("0", translate("value0"));
a5:value("1", translate("value1"));
a5:value("2", translate("value2"));
a5:value("3", translate("value3"));
a6 = a:option(DynamicList, "DynamicList_option_name","Dynamiclist option title", "DynamicList option description");
a7 = a:option(StaticList, "StaticList_option_name","StaticList option title", "StaticList option description");
a7:value("0", translate("value0"));
a7:value("1", translate("value1"));
a7:value("2", translate("value2"));
a7:value("3", translate("value3"));
a8 = a:option(Flag, "Flag_option_name","Flag option title", "Flag option description");
a9 = a:option(Button, "Button_option_name","Button option title", "Button option description");
b = m:section(TypedSection, "typedsection2_title", "typedsection2 description")
b:tab("tab1", "Tab1");
b:tab("tab2", "Tab2");
b1=b:taboption("tab1", Value, "tab1_option1", "tab1 Option1");
b2=b:taboption("tab2", Value, "tab2_option2", "tab2 Option2");
return m
- (3)UCI 文件中配置信息
config typedsection1_title 'typedsection1'
option Value_option_name 'Value'
option TextValue_option_name 'TextValue'
option DummyValue_option_name 'DummyValue'
option Listvalue_option_name '1'
list DynamicList_option_name 'DynamicList'
list DynamicList_option_name '123123'
option Flag_option_name '1'
option MultiValue_option_name '0 1 2 3'
list StaticList_option_name '0'
list StaticList_option_name '1'
list StaticList_option_name '2'
list StaticList_option_name '3'
config typedsection2_title 'typedsection2'
option tab1_option1 '1'
option tab2_option2 '2'
3.2 网上实例参考
例程详情参考 https://github.com/openwrt/luci/wiki/ModulesHowTo
1 m = Map("network", "Network") -- We want to edit the uci config file /etc/config/network
2 s = m:section(TypedSection, "interface", "Interfaces") -- Especially the "interface"-sections
3 s.addremove = true -- Allow the user to create and remove the interfaces
4 function s:filter(value)
5 return value ~= "loopback" and value -- Don't touch loopback
6 end s:depends("proto", "static") -- Only show thosewith"static"
7 s:depends("proto", "dhcp") -- or "dhcp" as protocol and leave PPPoE and PPTP alone
8
9 p = s:option(ListValue, "proto", "Protocol") -- Creates an element list (select box)
10 p:value("static", "static") -- Key and value pairs
11 p:value("dhcp", "DHCP")
12 p.default = "static"
13
14 s:option(Value, "ifname", "interface", "the physical interface to be used") -- This will give a simple textbox
15
16 s:option(Value, "ipaddr", translate("IP Address")) -- Ja, das ist eine i18n-Funktion ;-)
17
18 s:option(Value, "netmask", "Netmask"):depends("proto", "static") -- You may remember this "depends" function from above
19
20 mtu = s:option(Value, "mtu", "MTU")
21 mtu.optional = true -- This one is very optional
22 dns = s:option(Value, "dns", "DNS-Server")
23 dns:depends("proto", "static")
24 dns.optional = true
25 function dns:validate(value) -- Now, that's nifty, eh?
26 return value:match("[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") -- Returns nil if it doesn't match otherwise returns match
27 end
28
29 gw = s:option(Value, "gateway", "Gateway")
30 gw:depends("proto", "static")
31 gw.rmempty = true -- Remove entry if it is empty
32
33 return m -- Returns the map
- 更多 CBI 例程可以参考
openwrt源码/feeds/luci/modules/xxx模块/luasrc/model/cbi/
目录下的相关文件,结合网页界面去阅读相关源码,学习提高。
四、结尾
4.1 总结&反思
- TypedSection与NamedSection的运用场景与区别?
- Openwrt源码中提到的SimpleForm的效果是如何的?
- 每个控件属性对每个控件的影响是怎么样,效果如何?哪些属性是所有控件共同的,哪些属性是独有?
- 如何重构控件方法?
- 控件未列出的属性或方法在哪些途径能获取到?
4.2 资料参考
文档参考: https://github.com/openwrt/luci/wiki/CBI
博客参考:https://blog.csdn.net/qq_21949217/article/details/44340261
跟随大师的脚步,模仿大师的行为,感受大师的意境,成为真正的大师。