前言
最近在基于Openwrt做一个设备的固件,需要提供网页配置设备参数的功能,OpenWRT的设备页面是基于Luci的,以前没有学过lua语言,也没了解过相应的内容,因此简单记录下如何在OpenWRT中添加新页面;
一、Luci简介
Luci 的界面用户目录在/usr/lib/lua/luci
。其是 mvc 架构,/usr/lib/lua/luci/
下有三个目录model、view、controller
,它们对应 M、V、C
。
其中 M
是已经生成的 web 控件,其实就是写好的 lua 脚本;V
是给外部提供的一些 web 界面;C
控制其 V
和 M
的显示方式。
从上面的描述可以看出 C
部分是其入口, 我们进入 controller 看看它的内容, 其实它的入口地址在 controller的 admin 目录下面,里面的各个 lua 文件就是各个入口。比如 system.lua 就对应的主界面的 system 栏下面。
每个功能界面的入口地址为对应的 lua 文件中 entry 功能函数,entry 功能函数的原型为:
entry(path, target, title=nil, order=nil) --前面两个参数是必须的,后面两个是可选的。
path
形如(admin, system, reboot)
,entry 根据这些属性创建节点。比如上面内容代表在 system 标签中的 reboot 页面。
target
是这里的重点,它描述了当用户调用这个界面所执行的行为。主要有三种行为:
- call 为调用文件中的功能函数;
- template 为调用 view 中的 html 界面;
- cbi 为调用 mode 中的 lua 文件;
title
是在页面中显示的内容;order
是显示的顺序,顺序越小显示内容越靠前。
二、添加页面实例
1.添加一个静态页面
-
在
/usr/lib/lua/luci/controller/admin/system.lua
中增加一条lua语句:entry({"admin", "system", "helloworld"}, template("admin_system/helloworld"), _("helloworld "), 99)
第一个参数代表一个节点;
第二个参数,调用view/admin_system/helloworld.htm
文件;
第三个参数为显示的名字;
第四个参数为显示顺序,这里在最后显示; -
添加新文件
/usr/lib/lua/luci/view/admin_system/helloworld.htm
,新文件内容如下:<%+header%> <h1><%:Hello World%></h1> <%+footer%>
然后就可以在system栏找到刚添加的helloworld
页面了。
2. 添加新栏,并在其下添加参数配置页面
-
在
/usr/lib/lua/luci/controller/admin/
文件夹中新建文件deviceapp.lua
,内容如下:module("luci.controller.admin.deviceapp",package.seeall) function index() entry({"admin","deviceapp"},alias("admin","deviceapp","deviceapp"),_("设备应用配置"),80).index=true entry({"admin","deviceapp","deviceapp"},cbi("admin_deviceapp/deviceapp"),_("应用参数配置"),1) entry({"admin","deviceapp","deviceftp"},cbi("admin_deviceapp/deviceftp"),_("FTP参数配置"),2) end
这样就会在顶栏中添加一栏“设备应用配置”,而其中包含两个页面“应用参数配置”、“FTP参数配置”,这两个页面指向的是
/usr/lib/lua/luci/model/cbi/
文件夹中的admin_deviceapp/deviceapp.lua
脚本和admin_deviceapp/deviceftp.lua
脚本; -
在
/usr/lib/lua/luci/model/cbi/
文件夹中创建admin_deviceapp
文件夹,并在其中创建deviceapp.lua
脚本和deviceftp.lua
脚本,以deviceftp.lua
文件为例,内容如下:require("luci.sys") require("luci.sys.zoneinfo") require("luci.config") local m,s,o m=Map("wifidetect",translate("FTP配置")) m:chain("luci") -------------------------------------------------------------------- s=m:section(NamedSection,"servercfg","wifidetect",translate("FTP服务器参数配置")) s.anonymous=true s.addremove=false s:tab("servercfg",translate("FTP服务器信息配置")) -------------------------------------------------------------------- o=s:taboption("servercfg",Value,"ftphorstip",translate("FTP服务器ip地址:")) o.default="192.168.1.1" o=s:taboption("servercfg",Value,"ftpportd",translate("FTP服务器端口:")) o.default="8888" o=s:taboption("servercfg",ListValue,"enable_auto_ftp",translate("自动更新:")) o.default="1" o.datatype = "string" o:value("1", translate("是")) o:value("0", translate("否")) o=s:taboption("servercfg",Value,"ftpinvtime",translate("FTP更新查询间隔:")) o.default="1800" o=s:taboption("servercfg",Value,"ftpusrname",translate("FTP用户名:")) o.default="admin" o=s:taboption("servercfg",Value,"ftppwd",translate("FTP用户密码:")) o.default="123" o=s:taboption("servercfg",Value,"ftpsrcfilepath",translate("FTP用户根路径:")) o.default="/" ------------------------------------------------------------------- local apply=luci.http.formvalue("cbi.apply")
该脚本是读取配置文件
wifidetect
,并将该配置文件中名字为servercfg
的区域参数读取出来用于页面显示;
函数原型:
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
- title: title shown in the UI
- description: description shown in the UI
class NamedSection (name, type, title, description)
An object describing an UCI section selected by the name.
To instantiate use: Map:section(NamedSection, “name”, “type”, “title”, “description”)
- name: UCI section name
- type: UCI section type
- title: The title shown in the UI
- description: description shown in the UI
总结
以上是在OpenWRT下添加新页面的步骤,在实践中我们可以很明显的看到,我们并没有做多少额外的工作,比如http页面的生成,请求的解析,参数读取和表单的分析,OpenWRT的继承功能很好的减轻了我们的工作量,至于改变页面什么的对我可以说是完全解放了出来,不想单片机中那样要做很多额外的工作。