日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

如何编写一个路由器的界面1Luci开发入门

發布時間:2023/12/13 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 如何编写一个路由器的界面1Luci开发入门 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Howto:如何寫Module(模塊)-----------------這一部分主要是翻譯github上的document

注意:如果您打算將模塊加入LUCI整合之前,您應該閱讀Module參考。

本教程介紹如何編寫自己的LUCIWebUI中的模塊。在本教程中,我們假設您的luci安裝目錄lucidir(如果您目前使用的是安裝版/usr/lib/LUA/LUCI),并假設你的luci安裝經由/cgi-bin/LUCI訪問您的Web服務器。
方法路線(針對調度過程)

要編寫模塊,您需要了解LUCI調度過程的基礎知識。LUCI使用,將通過執行每個可供使用的controller的索引功能建立一個調度樹。在CGI環境變量PATH_INFO將作為在這個調度樹,例如:/cgi-bin/luci/foo/bar/baz將被解析為foo.bar.baz

要注冊在調度樹中的功能,你可以使用luci.dispatcher的入口函數(Entryfunction)。進入需要4參數(其中的2個是可選的):

entry(path,target,title=nil,order=nil)

path是一個table結構,描述了在調度樹的的位置:例如,{"foo","bar","baz"}的path將被插入到foo.bar.baz.
target描述當用戶請求該節點時將要采取的行動.其中有三個預定義的對象是最重要的(call,template,cbi),他們將在本頁的后邊描述
title定義了在可見的菜單中的選項,也就是最終luci界面中可以看到的標題內容(可選)
order主要依據這個數字來使同一水平上的節點在菜單上的排序(可選)

你可以通過操作節點表的返回值來給entryfunction賦更多的參數。一些典型的參數例子:

i18n定義了當頁面被請求時,自動加載的解釋程序(文件)
dependent防止插件在其父節點的確實,也就是添加插件的依賴
leaf停止解析該節點的請求,并沒有更進一步的調度樹
sysauth要求用戶與給定系統的用戶帳戶進行認證

下邊就是命名與使用過程

既然你已經了解了調度的基礎知識,現在,我們可以開始寫module了。但是在這之前,我們必須先選擇目錄并且命名屬于你自己的新節點。

我們假設你想要創建一個新叫做myapp的應用,而且myapp的module是mymodule。

因此你必須創建一個子文件夾lucidir/controller/myapp,在該文件夾下創建一個mymodule.lua的文件,文件內容如下:

1 module("luci.controller.myapp.mymodule", package.seeall) 
2 
3 function index()
4 
5 end

第一行要求lua正確識別模塊,并建立它的范圍。該indexfunction將用于注冊在調度樹中的動作。

到目前為止,你就已經有了一個新的節點,只不過是該節點中沒有任何的功能。

我們假設你想要復用你的myapp.mymodule模塊,那么你就必須開始最后一個步驟。

Actions

重新打開lucidir/controller/myapp/mymodule.lua并且添加一個函數類似下邊的內容:

 1 module("luci.controller.myapp.mymodule", package.seeall)
 2 
 3 function index()   
 4      entry({"click", "here", "now"}, call("action_tryme"), "Click here", 10).dependent=false
 5 
 6 end 
 7 
 8 function action_tryme()    
 9     luci.http.prepare_content("text/plain")   
10     luci.http.write("Haha, rebooting now...")   
11     luci.sys.reboot()
12 end

現在在瀏覽器中輸入/cgi-bin/luci/click/here/now(http://192.168.1.1/luci/click/here/now在你的openwrt系統上應該是)

你可以發現這些動作已經被添加到了調度樹上。

正如你可能會或可能不知道的:CGI規范要求您發送您的內容頭之前,首先發送Content-Type。你會發現幾個快捷方式(如上面所使用的),以及在模塊luci.http重定向功能

Views

如果你僅僅是想展現給用戶一行字符或者一些有意思的家庭圖片,那么使用HTML-template就足夠了。這些template也可以包含lua代碼,但是你必須了解到僅僅使用template可以會寫入臟代碼。

現在讓我們來創建一個小的lucidir/view/myapp-mymodule/helloworld.htm,內容如下:

1 <%+header%>
2 <h1><%:Hello World%></h1> 
3 <%+footer%>

然后添加下邊的一行index-function到你的module文件中去。

entry({"my","new","template"},template("myapp-mymodule/helloworld"),"Helloworld",20).dependent=false

現在在你的瀏覽器中輸入/cgi-bin/luci/my/new/template(在你的openwrt系統上是http://192.168.1.1/luci/my/new/template)。

你也許注意到了這些奇怪的標簽,這些是被LuCI的template處理程序使用的標記.在標準設計中使用header和footer,是個好的選擇.

CBImodels

CBI是LuCI中最酷的功能.它創建一個標準的用戶接口并且將內容保存在一個特定的UCIconfig文件中。.你只需要描述配置文件的結構,然后CBI程序會幫你完成剩下的部分。這包括生成,解析和驗證HTML表單和讀取和寫入UCI文件。

所以我們必須認真的創建一個實例lucidir/model/cbi/myapp-mymodule/netifaces.lua其內容如下:

 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

當然,別忘記添加你自己的index-function函數。

1 entry({"admin", "network", "interfaces"}, cbi("myapp-mymodule/netifaces"), "Network interfaces", 30).dependent=false

總結

以上是生活随笔為你收集整理的如何编写一个路由器的界面1Luci开发入门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。