LUCI简单说明教程

更新时间:2023-10-06 15:59:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

LUCI这个在百度上搜索除了一篇我的百度文库luci的介绍文章之外,前三页都是些不知所 云的名词(足见百度在专业领域的搜索之烂),我却在大学毕业的大半年的大部分时间里与 它纠结,由于开始的发懵到后来逐渐感觉到这家伙还很好玩的,现在就把我对luci的浅显认 识介绍给大家。

官网:http://luci.subsignal.org/

有关luci的各个方面,你几乎都可以从这里获得,当然,只是浅显的获得,luci的文档写 的还算比较全,但是写的稍显简略,开始看的时候会有一点不知所措。

UCI 熟悉openwrt的人都会有所了解,就是UnifiedConfigurationInterface的简称,而luci 这个openwrt上的默认web系统,是一个独立的由严谨的德国人开发的web框架,是Lua ConfigurationInterface的简称,如果在您的应用里,luci是对openwrt的服务,我们就有必 要做一下uci的简介,我这里就不说了,见链接:

http://www.google.com.hk/url?sa=t&source=web&cd=5&ved=0CEMQFjAE&url=http:/ /nbd.name/openwrt-fosdem-09.pdf&ei=h52iTcXvOcrMcJ-xxOwD&usg=AFQjCNGFhum CIgS5tK_mDJ2dDFU4qsskfQ

有的时候,我们开发的luci是在自己的LinuxPC上开发,在普通的linux上,一般是没有 uci命令的,为了开发方便,可以手动编译一下,方法见链接: https://forum.openwrt.org/viewtopic.php?id=15243

OK,之前罗里罗嗦的说了很多,现在就进入正题,进入正题的前提是你已经makeinstall正 确的安装了lua ,luci,以及编译好链接了相关的so(如果你需要,比如uci.sonixio.so), 以及makeinstall正确webserver,(我用的webserver是thttpd,也编译过mongoose,lighttpd, 在这三个之中,lighttpd是功能最完善的,mongoose是最小巧的)。 进入正题: 一:luci的启动

在webserver中的cgi-bin目录下,运行luci文件(权限一般是755),luci的代码如下: 1#!/usr/bin/lua --cgi的执行命令的路径

2require\导入cacheloader包 3require\导入sgi.cgi包

4luci.dispatcher.indexcache=\缓存路径地址 5luci.sgi.cgi.run() --执行run方

法,此方法位于*/luci/sgi/cgi.lua中

run方法的主要任务就是在安全的环境中打开开始页面(登录页面),在run中,最主要的 功能还是在dispatch.lua中完成。 运行luci之后,就会出现登录界面: -bash-4.0#pwd /var/www/cgi-bin -bash-4.0#./luci Status:200OK

Content-Type:text/html;charset=utf-8 Cache-Control:no-cache Expires:0

如果你成功的运行了luci 就说明你的luci框架成功的跑了起来。 二:LUCI的MVC 1:用户管理:

在luci的官方网站说明了luci是一个MVC架构的框架,这个MVC做的可扩展性很 好,可以完全的统一的写自己的html网页,而且他对shell的支持相当的到位,(因为luci 是lua写的,lua是C的儿子嘛, 与shell是兄弟)。在登录界面用户名的选择很重要, luci是一个单用户框架,公用的模块放置在*/luci/controller/下面,各个用户的模块放置在 */luci/controller/下面对应的文件夹里面,比如 admin登录,最终的页面只显示 /luci/controller/admin下面的菜单。这样既有效的管理了不同管理员的权限。 2:controller文件夹下的lua文件说明:(以mini用户为例) 在mini目录下面,会有一个index.lua文件,简略的代码如下:

这个文件定义了node,最外面的节点,最上层菜单的显示等等。在其他的lua文件里,定义 了其他菜单的显示和html以及业务处理路径。每个文件对应一个菜单相。 例如system.lua文件

mudel是对应文件的,function index 定义了菜单,比如这一句entry({\\第1项为菜单入口:

{\,mini是最上层的菜单,即为用户项,system为一个具体的菜单, reboot为这个菜单的子菜单,如果reboot还需要加上子菜单的话,可以这样写:

entry({\,\这样 就会在reboot上产生一个新的子菜单,以此类推,可以产生N层菜单。 第二项为菜单对应的页面,可以是lua的源代码文件,也可以是html页面。

aliascgiformcall 等定义了此菜单相应的处理方式,form和cgi对应到model/cbi相应的目 录下面,那里面是对应的定制好的html和lua业务处理。

alias是等同于别的链接,call调用了相应的action_function。还有一种调用,是template,是 直接链接到view相应目录下面的htm页面。(说明:luci框架下面的htm都是可以嵌入lua 语句的,做业务处理,相当于jsp页面的内部的Java语句)。 问价查找对应简介:

entry({\:对应此文件的 action_rebootfunction

entry({\:对 应*/model/cbi/mini/system.lua {autoapply=true} 这个失传的参数。 。。。。。

第 三 项 为i18n 显 示 , 比 如entry({\i18n(\,菜单的名字为admin-core文件内的对应显示。此处也可以这样写, i18n(\重启\,即直接做了国际化。菜单上显示的就是“重启”。 第四项为现实的顺序,这个数字越小,显示越靠前,靠上。 3:model业务处理和页面生成简介

我认为model的业务处理和html生成,是luci框架的精华,但是想用好它,最终扩展

定义自己的页面也是最难的,但是一旦定义好了,后面的工作就会轻松高效简介统一,不失 为一种好的解决方案。但是它又有缺点,就是写页面虽然统一,但是不够灵活。 下面以SimpleForm为例,讲解一下。 具体文件*/luci/model/cbi/passwd.lua

f =SimpleForm(\调用 SimpleForm页面当然还是I18N从中捣乱,看上去没那么直观,不理他

pw1=f:field(Value,\里面加一个field 至于 SimpleForm和fiemd是什么,一会去看SimpleForm页面去

pw1.rmempty=false-- 把SimpleForm的rmempty为不显示后面就不做注释了应该看得懂 了

pw2=f:field(Value,\pw2.rmempty=false

functionpw2.validate(self,value,section)

returnpw1:formvalue(section)==valueandvalue end

functionf.handle(self,state,data)

ifstate==FORM_VALIDthen --这个就是业务处理了你懂得呵呵

localstat=luci.sys.user.setpasswd(\ifstatthen

f.message=translate(\else

f.errmessage=translate(\end

data.pw1=nil data.pw2=nil end

returntrue end returnf

说明:(simpleForm 位于view/cbi 下面,可以研究一下,各个元素是如何定义的) 现在在给一个小例子:

以.*/luci/model/cbi/admin_system/version_manage.lua为例,介绍一下luci中web页面lua代 码

6localh=loadfile(\7ifhthen 8 h() 9end

10localhelp_txt=help_infoand help_info.version

加载帮助帮助文件help.lua,关于loadfile()的用法可以查看lua的手册(我还没完全弄明白,先 用了)

help_txt是一个全局变量

12appadmin_path=\

定义一个全局变量,其实跟功能跟宏一样,定义appadmin的绝对路径 14versionlist={} 15

16functiongetline(s) ......... 32end

33

34functionget_versionlist() ......... 68end 69

70versionlist=get_versionlist()

定义一个全局变量和两个函数,并初始化此变量

接下来就是和最终展现的Web页面直接相关的代码了,大部分都是对luci封装好的一些html 控件(代码)的使用和扩展。luci 封装好的html控件 类可以在以下文件查看:./host/usr/lib/lua/luci/cbi.lua 71m=SimpleForm(\版本管理\72m.submit=false 73m.reset=false

74m.help=help_txtandtrueorfalse 75m.helptxt=help_txtor\

使用了一个SimpleForm的控件,SimpleForm实际上对应一个html表单,是整个页面最大 的\容器\,本页面内的绝大部分控件都处于SimpleForm内

,是它的子控件。我知道的可以做>页面最大\容器\的控件还有一个Map,但它需 要./host/etc/config/目录下的一个配置文件,我没有使用。

submitreset是luci默认就封装好的一个属性,分别控制html表单的\提交\重置\按钮;help helptxt是我扩充的表单属性,分别控制web页面的 \帮助\功能和帮助内容。关于控件属

性的意义、实现和扩充可以按以下步骤进行:

在文件./host/usr/lib/lua/luci/cbi.lua中查找控件名SimpleForm,然后可以找到以下行664 self.template=\这

表明SimpleForm的html模版文件为./host/usr/lib/lua/luci/view/cbi/simpleform.htm,通过研究 simpleform.htm文件内容可以知道各属性的

功能以及模版中使用lua代码的方法,然后可以按类似的方法添加自定义的 属性。

77s=m:section(Table,versionlist)

新建了一个section,section内定义了一个表格类,versionlist是与其相关的变量(lua的所有 变量都可归类于table类型)

与Table关联的table变量应该是这种结构的: t={

row1={column1=\row2={column1=\row3={column1=\row4={column1=\}

然后定义Table的列控件

79enable=s:option(DummyValue,\软件状态\83appid =s:option(DummyValue,\软件版本\

84appname=s:option(DummyValue,\软件名称\

DummyValue是只读的文本框,只输出不输入。Value是单行文本框,可输出也可输入。Flag

是一个checkbox,值为\时被选中,为\时未选中。 ListValue是列表框...具体的用法可

以看./host/usr/lib/lua/luci /model/cbi/下的文件(find ./host/usr/lib/lua/luci/model/cbi/ -name \\

对于table内普通的字符串类的值,只需要把列控件的id(括号内第二个值,如\)定 义为table内对应的变量名(比如column1) 对于非变通字符串类的值,或者为字符串但需要进行一定的处理然后再显示的值,可以按以 下方法显示:定义该控件的cfgvalue函数属性

127 newinfo=up_s:option(TextValue,\新版本信息\128 newinfo.readonly=true 129 newinfo.rows=11

130 newinfo.cfgvalue=function(self,section) 131 localt=string.gsub(info,\132 returnt 133 end

定义cfgvalue后,luci的处理函数会调用此函数为此控件赋值,(传入的section参数值为 row1/row2/row3等,当处理到row几时值就为row几)

对于DummyValue等只输出不输入的类,还有一种赋值方法:控件实例名(如enable).value =xxx

对于有输入的控件Value等,.value方法赋值在处理输入里会有一些问题,有什么问题以及 如何解决可以做实验试试,也许是我使用方法不对造 成的

对有输入控件的处理有两种方法: 1定义控件的.write属性

这种方法对处理比较独立的输入(与其它控件输入关系不大)比较适用 88up_s=m:section(SimpleSection)

89up_version=up_s:option(Button,\上传新版本\90up_version.onlybutton=true 91up_version.align=\92up_version.inputstyle=\

93up_version.write=function(self,section)

94 luci.http.redirect(luci.dispatcher.build_url(\\95end

ps:只有当Value的rmempty==false时,Value输入为空也会触发write函数, 需要对rmemtpy 显示赋值为false(xx.rmempty=false) 4:view下面的html简介

这个是最好理解的例:passwd.htm <%+header%>

<%:reboot%>

<%:a_s_reboot1%>

<%-localc=require(\

ifcandnext(c)then -%>

ifnotrebootthen -%>

<%:a_s_reboot_running%>

<%+footer%>

<%+header%><%+footer%> 加载公用的头部和尾部 <%luacode%> <%:i18n%> <%luacode%> <%=lua变量%>

本文来源:https://www.bwwdw.com/article/kk7d.html

Top