LUCI
官网:
UCI
有的时候,我们开发的luci
https://forum.openwrt.org/viewtopic.php?id=15243
OK
进入正题:
一:luci
#!/usr/bin/lua --cgi的执行命令的路径
require"luci.cacheloader" --导入cacheloader包
require"luci.sgi.cgi" --导入sgi.cgi包
luci.dispatcher.indexcache = "/tmp/luci-indexcache" --cache缓存路径地址
luci.sgi.cgi.run() --执行run方法,此方法位于*/luci/sgi/cgi.lua中
-bash-4.0# pwd
/var/www/cgi-bin
-bash-4.0# ./luci
Status: 200 OK
Content-Type: text/html;
charset=utf-8
Cache-Control: no-cache
Expires: 0
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html class=" ext-strict">
</html>
二:LUCI
1:用户管理:
2:
module("luci.controller.mini.index", package.seeall)
17
18 function index()
19 luci.i18n.loadc("admin-core")
20 local i18n = luci.i18n.translate
21
22 local root = node()
23 if not root.lock then
24 root.target = alias("mini")
25 root.index = true
26 end
27
28 entry({"about"}, template("about")).i18n = "admin-core"
29
30 local page = entry({"mini"}, alias("mini", "index"), i18n("essentials", "Essentials"), 10)
31 page.i18n = "admin-core"
32 page.sysauth = "root"
33 page.sysauth_authenticator = "htmlauth"
34 page.index = true
35
36 entry({"mini", "index"}, alias("mini", "index", "index"), i18n("overview"), 10).index = true
37 entry({"mini", "index", "index"}, form("mini/index"), i18n("general"), 1).ignoreindex = true
38 entry({"mini", "index", "luci"}, cbi("mini/luci", {autoapply=true}), i18n("settings"), 10)
39 entry({"mini", "index", "logout"}, call("action_logout"), i18n("logout"))
40 end
41
42 function action_logout()
43 luci.http.header("Set-Cookie", "sysauth=; path=/")
44 luci.http.redirect(luci.dispatcher.build_url())
45 end
这个文件定义了node
例如
function index()
19 luci.i18n.loadc("admin-core")
20 local i18n = luci.i18n.translate
21
22 entry({"mini", "system"}, alias("mini", "system", "index"), i18n("system"), 40).index = true
23 entry({"mini", "system", "index"}, cbi("mini/system", {autoapply=true}), i18n("general"), 1)
24 entry({"mini", "system", "passwd"}, form("mini/passwd"), i18n("a_s_changepw"), 10)
25 entry({"mini", "system", "backup"}, call("action_backup"), i18n("a_s_backup"), 80)
26 entry({"mini", "system", "upgrade"}, call("action_upgrade"), i18n("a_s_flash"), 90)
27 entry({"mini", "system", "reboot"}, call("action_reboot"), i18n("reboot"), 100)
28 end
mudel是对应文件的,
第1
{"mini",
entry({"mini",
第二项为菜单对应的页面,可以是lua
alias
alias是等同于别的链接,
问价查找对应简介:
entry({"mini",
entry({"mini",
。。。。。
第三项为i18n
第四项为现实的顺序,这个数字越小,显示越靠前,靠上。
<%
require("luci.sys")
local load1, load5, load15 = luci.sys.loadavg()
local request = require("luci.dispatcher").context.path
local category = request[1]
local tree = luci.dispatcher.node()
local cattree = category and luci.dispatcher.node(category)
local node = luci.dispatcher.context.dispatched
local hostname = luci.sys.hostname()
local c = tree
for i,r in ipairs(request) do
if c.nodes and c.nodes[r] then
c = c.nodes[r]
c._menu_selected = true
end
end
require("luci.i18n").loadc("default")
require("luci.http").prepare_content("application/xhtml+xml")
-%>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%=luci.i18n.context.lang%>" lang="<%=luci.i18n.context.lang%>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<!--[if lt IE 7]><link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/ie6.css" /><![endif]-->
<!--[if IE 7]><link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/ie7.css" /><![endif]-->
<% if node and node.css then %><link rel="stylesheet" type="text/css" media="screen" href="<%=resource%>/<%=node.css%>" />
<% end -%>
<mce:script type="text/javascript" src="<%=resource%><!--
/VarType.js">
// --></mce:script>
<mce:script type="text/javascript" src="<%=resource%><!--
/XHTML1.js">
// --></mce:script>
<mce:script type="text/javascript" src="<%=resource%><!--
/Dropdowns.js">
// --></mce:script>
<title><%=striptags( hostname .. ( (node and node.title) and ' - ' .. node.title or '')) %> - LuCI</title>
</head>
<body class="lang_<%=luci.i18n.context.lang%>">
<p class="skiplink">
<span id="skiplink1"><a href="#navigation" mce_href="#navigation"><%:skiplink1 Skip to navigation%></a></span>
<span id="skiplink2"><a href="#content" mce_href="#content"><%:skiplink2 Skip to content%></a></span>
</p>
<div id="header">
<h1><%=luci.version.distname%></h1>
<p>
<%=luci.version.distversion%><br />
<%:load%>: <%="%.2f" % load1%> <%="%.2f" % load5%> <%="%.2f" % load15%><br />
<%:hostname%>: <%=hostname%>
</p>
</div>
<div id="menubar">
<h2 class="navigation"><a id="navigation" name="navigation"><%:navigation Navigation%></a></h2>
<ul id="mainmenu" class="dropdowns">
<%-
local function submenu(prefix, node)
if not node.nodes or node.hidden then
return false
end
local index = {}
local count = 0
for k, n in pairs(node.nodes) do
if n.title and n.target then
table.insert(index, {name=k, order=n.order or 100})
count = count + 1
end
end
table.sort(index, function(a, b) return a.order < b.order end)
if count > 0 then
%>
<ul id="submenu_<%=string.gsub(string.gsub(prefix, "/", "_"), "^_(.-)_$", "%1")%>">
<%-
for j, v in pairs(index) do
if #v.name > 0 then
local nnode = node.nodes[v.name]
local href = controller .. prefix .. v.name .. "/"
href = (nnode.query) and href .. luci.http.build_querystring(nnode.query) or href
if nnode.nodes then
for k1, n1 in pairs(nnode.nodes) do
href = "#"
end
end
%>
<li><a<% if nnode._menu_selected then %> class="active"<%end%> href="<%=luci.util.pcdata(href)%>"><%=nnode.title%></a><%-
submenu(prefix .. v.name .. "/", nnode)
%></li>
<%-
end
end
%>
</ul>
<%
end
end
3:
下面以
具体文件
pw1=f:field(Value,"pw1",translate("password"))
pw1.rmempty=false
pw2 = f:field(Value, "pw2", translate("confirmation"))
pw2.rmempty = false
function pw2.validate(self, value, section)
return pw1:formvalue(section) == value and value
end
function f.handle(self, state, data)
if state == FORM_VALID then --这个就是业务处理了 你懂得 呵呵
local stat = luci.sys.user.setpasswd("admin", data.pw1) == 0 -- root --> admin
if stat then
f.message = translate("a_s_changepw_changed")
else
f.errmessage = translate("unknownerror")
end
data.pw1 = nil
data.pw2 = nil
end
return true
end
return f
说明:(
现在在给一个小例子:
以.*/luci/model 6 local h = loadfile("/usr/local/luci/help.lua")
7 if h then
8 h()
9 end
10 local help_txt = help_info and help_info.version
加载帮助帮助文件help.lua,
help_txt
12
定义一个全局变量,其实跟功能跟宏一样,定义appadmin
14 versionlist = {}
15
16 function getline (s)
.........
32 end
33
34 function get_versionlist()
.........
68 end
69
70 versionlist = get_versionlist()
定义一个全局变量和两个函数,并初始化此变量
接下来就是和最终展现的Web
类可以在以下文件查看:./host/usr/lib/lua/luci/cbi.lua
71 m = SimpleForm("version", translate("版本管理 "))
72 m.submit = false
73 m.reset = false
74 m.help = help_txt and true or false
75 m.helptxt = help_txt or ""
使用了一个SimpleForm
,是它的子控件
submit
"帮助
性的意义、实现和扩充可以按以下步骤进行:
表明SimpleForm
功能以及模版中使用lua
属性。
77
新建了一个section,section
与Table
t = {
row1 = {column1 = "xxx", column2 = "xxx", .... },
row2 = {column1 = "xxx", column2 = "xxx", .... },
row3 = {column1 = "xxx", column2 = "xxx", .... },
row4 = {column1 = "xxx", column2 = "xxx", .... },
}
然后定义Table
79 enable = s:option(DummyValue, "_enabled", translate("软件状态 "))
83 appid = s:option(DummyValue, "_appid", translate("软件版本 "))
84 appname = s:option(DummyValue, "_appname", translate("软件名称 "))
DummyValue是只读的文本框,只输出不输入。
ListValue是列表框
以看./host/usr/lib/lua/luci
"ListValue")
对于table
对于非变通字符串类的值,或者为字符串但需要进行一定的处理然后再显示的值,可以按以下方法显示:定义该控件的cfgvalue
127 newinfo = up_s:option(TextValue, "_newifo", translate("新版本信息 "))
128 newinfo.readonly = true
129 newinfo.rows = 11
130 newinfo.cfgvalue = function(self, section)
131 local t = string.gsub(info, "Archive:[^/n]*", "")
132 return t
133 end
定义cfgvalue
对于DummyValue
对于有输入的控件Value
成的
对有输入控件的处理有两种方法:
1
88 up_s = m:section(SimpleSection)
89 up_version = up_s:option(Button, "_up_version", translate("上传新版本 "))
90 up_version.onlybutton = true
91 up_version.align = "right"
92 up_version.inputstyle = "save"
93 up_version.write = function(self, section)
94 luci.http.redirect(luci.dispatcher.build_url("admin", "system", "version_manage", "upload"))
95 end
ps:只有当
4:
这个是最好理解的
<%+header%>
<h2><a id="content" name="content"><%:system%></a></h2>
<h3><%:reboot%></h3>
<p><%:a_s_reboot1%></p>
<%-
local c = require("luci.model.uci").cursor():changes()
if c and next(c) then
-%>
<p class="warning"><%:a_s_reboot_u%></p>
<%-
end
if not reboot then
-%>
<p><a href="<%=controller%>/admin/system/reboot?reboot=1"><%:a_s_reboot_do%></a></p>
<%- else -%>
<p><%:a_s_reboot_running%></p>
<script type="text/javascript">setTimeout("location='<%=controller%>/admin'", 60000)</script>
<%- end -%>
<%+footer%>
<%+header%> <%+footer%> 加载公用的头部和尾部
<% lua code%>
<%:i18n%>
<%lua code%>
<%=lua 变量 %>