在《LUCI启动流程介绍》里,我们介绍了LUCI的启动主体是dispatcher.lua的dispatch()函数,他通过解析controller目录下的lua文件,定义node节点,构建node-tree来进行页面管理。本节将详细介绍M(model)、V(view)、C(controller)各个文件的功能以及如果添加新的node节点。
因为dispatch()函数通过解析controller目录下的lua文件构建node-tree,所以我们优先看一下这个目录的lua脚本是如何定义的。以controller/admin/status.lua的部分代码为例。
module("luci.controller.admin.status", package.seeall)
function index()
entry({"admin", "status"}, alias("admin", "status", "overview"), _("Status"), 20).index = true
entry({"admin", "status", "overview"}, template("admin_status/index"), _("Overview"), 1)
entry({"admin", "status", "iptables"}, call("action_iptables"), _("Firewall"), 2).leaf = true
entry({"admin", "status", "processes"}, cbi("admin_status/processes"), _("Processes"), 6)
end
function action_iptables()
......
end
1、定义模块入口---> module("luci.controller.admin.status", package.seeall)
此行说明了程序和模块的路径名称,比如在controller/admin目录创建一个status.lua,那么就可以写成“luci.controller.admin.status”
2、添加index()函数,在index()函数中定义node节点属性
createtree()函数调用lua文件中的index()函数创建node-tree,同时index()引用entry函数定义node节点
3、entry (path, target, title, order)函数
(1)path:地址栏访问路径,通常也定义菜单分配,如:“{"admin", "一级菜单名", "菜单项名"}”
-- 定义菜单栏的一级菜单名
entry({"admin", "status"}, alias("admin", "status", "overview"), _("Status"), 20).index = true
-- 定义status下的overview菜单项
entry({"admin", "status", "overview"}, template("admin_status/index"), _("Overview"), 1)
(2)target:指定节点被调度(即用户点击)时的行为,主要有三种:call、template 和 cbi。
(3)title:标题,即我们在网页中看到的菜单名(可选)
(4)order:同级节点的显示顺序,越小越靠前,反之越靠后(可选)
在entry函数中,使用cbi方式调用model下的lua文件。在这部分主要介绍model目录的lua脚本是如何定义的,他与UCI配置文件到底有何联系,保存生效如何能连接启动脚本。
1、model页面
model的页面是通过其目录下的LUA脚本与配置文件一起生成的。在LUA脚本的开头,通过 Map("配置文件文件名", "配置页面标题", "配置页面说明") 函数连接相应的配置文件;然后使用类型或者名称查找对应的section及option;最后根据页面需求,将option转换成HTML元素。以上操作就完成了model页面的配置,LUA脚本的详细介绍可以参考下列网址,这里只贴部分代码进行说明。
https://blog.csdn.net/qq_19004627/article/details/80364099
(1)/etc/config/example配置文件内容如下
config interface 'test'
option enable '1'
option addr '192.168.1.1'
(2)model目录的lua脚本内容如下,因为页面内容是由配置文件生成的,所以当修改完页面点击保存按钮时,修改的值也会同步到底层配置文件中。
--m = Map("配置文件文件名", "配置页面标题", "配置页面说明")
--第一个参数为配置文件存储的文件名,不包含路径,默认在/etc/config目录下
--第二个参数为页面的标题
--第三个参数为页面的描述
m = Map("example", translate("LUA Example"))
--创建与配置文件中对应的section
--section的创建分为两种:NamedSection和TypedSection
--s = m:section(NamedSection, name, type, title, description)
--s = m:section(TypedSection, type, title, description)
--前者根据配置文件中的section名,例如上述配置文件中的test
--后者根据配置文件中的section类型,例如上述配置文件中的interface
s = m:section(TypedSection, "interface", translate("Example Info"))
s.anonymous = true
--获取section对应的option,并转换成HTML元素
addr = s:option(Value, "addr", translate("Address"))
enable = s:option(Flag, "enable", translate("Enable"))
--一定要记得return,才会有页面显示,否则是空页面
return m
(3)保存生效按钮与脚本的关联方法有二,一是捕获保存生效按钮,如果发现用户点击保存生效按钮,则调用底层脚本;
local apply = luci.http.formvalue("cbi.apply")
if apply then
luci.sys.call("/etc/init.d/example restart")
end
二是底层脚本监听配置文件是否有修改,如果发现有改动,脚本重新启动。具体操作可以参考下列网址:
https://www.cnblogs.com/mayswind/p/3468124.html
在entry函数中,主要通过template方式调用view下的HTML文件。在这部分主要介绍页面框架是如何搭建的。注:view目录下的文件虽然是HTML文件,但是文件尾缀必须要写成.htm形式
1、顶部<%- 内容 -%>: 此部分主要包含lua脚本的调用,在这里获取的变量可以直接在后文HTML中进行引用。
2、中部:此部分完成CGI post及get的处理,主要使用JS语言进行编写
3、html部分:此部分完成页面内容的显示,与常规HTML编写相同
例:在状态菜单下添加测试页面
1、在controller目录下定义node节点
entry({"admin", "status", "example"}, cbi("admin_status/example"), _("Example"), 6)
2、在/etc/config下添加配置文件example
config interface 'test'
option enable '1'
option addr '192.168.1.1'
3、在model目录下添加example.lua脚本
m = Map("example", translate("LUA Example"))
s = m:section(TypedSection, "interface", translate("Example Info"))
s.anonymous = true
addr = s:option(Value, "addr", translate("Address"))
enable = s:option(Flag, "enable", translate("Enable"))
return m
1、开发OpenWrt路由器上LuCI的模块(https://www.cnblogs.com/mayswind/p/3468124.html)
2、luci cbi 模块函数详解(https://blog.csdn.net/qq_19004627/article/details/80364099)
3、openWRT官网,保存生效调用脚本(https://oldwiki.archive.openwrt.org/doc/devel/config-scripting)
4、LUCI简单说明教程(https://wenku.baidu.com/view/7cfb0d17e518964bcf847c76.html)
5、OpenWrt自定义luci页面来修改配置文件(https://blog.csdn.net/lvshaorong/article/details/53939138)
6、LUA的详细总结(https://www.cnblogs.com/rohens-hbg/category/743186.html)