luci界面开发中的MVC架构——LuCI介绍(二)

想要给openwrt开发应用,虽然直接可执行程序也可以运行,但是没有UI会很不方便,想要开发UI就要用openwrt的那一套,自然就是LuCI,LuCI又用了一套MVC框架,今天就讲讲这是个什么东西。

OpenWrt LuCI 界面开发中的 MVC 架构

在 OpenWrt 的 LuCI Web 界面开发中,采用了 MVC(Model-View-Controller)架构,但它和传统的 MVC 框架有所不同,主要依赖 Lua + UCI + JavaScript(Vue 风格) 来实现 Web UI 交互。


1. OpenWrt LuCI 的 MVC 架构

在 LuCI 开发中:

  • Model(模型):负责数据处理(通常基于 UCI 配置)。
  • View(视图):负责 UI 展示(使用 Lua Template (.htm) 或现代 JavaScript (.js))。
  • Controller(控制器):负责业务逻辑和路由(通常是 Lua (.lua) 脚本)。

🔹 架构示意图

用户请求 (Web)
    ↓
Controller (Lua) - 处理请求,调用 Model
    ↓
Model (UCI) - 读取/写入配置数据
    ↓
View (HTML/JS) - 渲染页面
    ↓
用户交互 (表单提交,RPC 调用)

2. LuCI 的三大核心组件

组件作用代码位置
Model(模型)处理 UCI 配置数据/usr/lib/lua/luci/model/cbi/
View(视图)生成 HTML/JS 页面/usr/lib/lua/luci/view//www/luci-static/resources/view/
Controller(控制器)处理请求逻辑和路由/usr/lib/lua/luci/controller/

3. Model(模型) - 处理 UCI 配置

在 LuCI 开发中,Model 层主要用于 操作 OpenWrt 的 UCI(Unified Configuration Interface)

📌 示例:定义 Model 处理 UCI

文件/usr/lib/lua/luci/model/cbi/admin_network/wol.lua

m = Map("wol", "Wake on LAN")  -- 绑定到 UCI "wol" 配置
s = m:section(NamedSection, "main", "wol", "WOL 配置")

mac = s:option(Value, "macaddr", "MAC 地址")  -- 用户输入的 MAC 地址
mac.datatype = "macaddr"

iface = s:option(ListValue, "interface", "网络接口")
iface:value("br-lan", "LAN")
iface:value("wan", "WAN")

return m

🔹 解释

  • Map("wol", "Wake on LAN") 绑定到 /etc/config/wol UCI 配置文件。
  • s:option(Value, "macaddr", "MAC 地址") 定义了 MAC 地址 输入框,并限制为 macaddr 数据类型。
  • iface:value("br-lan", "LAN") 提供了接口选择。

4. View(视图) - 生成 UI 页面

LuCI 视图有两种方式:

  1. 传统 Lua 模板 (.htm)
  2. 现代 JavaScript (.js)

📌 示例 1:Lua 方式渲染 HTML

文件/usr/lib/lua/luci/view/admin_network/wol.htm

<%+cbi/header%>
<h2>Wake on LAN</h2>
<%+cbi/apply_cb%>
<form method="post">
    <input type="text" name="macaddr" placeholder="输入 MAC 地址"/>
    <button type="submit">发送 WOL</button>
</form>
<%+cbi/footer%>

🔹 解释

  • cbi/headercbi/footer 负责引入 LuCI 标准框架。
  • <input type="text" name="macaddr"> 让用户输入 MAC 地址。
  • <button> 让用户提交 WOL 请求。

📌 示例 2:JavaScript (.js) 动态渲染

文件/www/luci-static/resources/view/wol.js

return view.extend({
    render: function() {
        return E([
            CBI.form.Value.extend({
                name: "macaddr",
                label: _("MAC 地址"),
                datatype: "macaddr",
            }),
            CBI.form.ListValue.extend({
                name: "interface",
                label: _("网络接口"),
                values: {
                    "br-lan": _("LAN"),
                    "wan": _("WAN")
                }
            })
        ]);
    }
});

🔹 解释

  • CBI.form.Value 创建一个 MAC 地址输入框
  • CBI.form.ListValue 创建一个 接口选择下拉框
  • 视图是动态生成的,没有固定 HTML 代码

5. Controller(控制器) - 处理请求

LuCI 的 Controller 层主要用于:

  1. 定义 Web UI 的 URL 路由
  2. 调用 Model(UCI 读取/写入)
  3. 返回 View(HTML/JS 渲染)

📌 示例:控制器定义 WOL 页面

文件/usr/lib/lua/luci/controller/admin/wol.lua

module("luci.controller.admin.wol", package.seeall)

function index()
    entry({"admin", "network", "wol"}, cbi("admin_network/wol"), "Wake on LAN", 30)
    entry({"admin", "network", "wol_send"}, call("send_wol"), nil).leaf = true
end

function send_wol()
    local mac = luci.http.formvalue("macaddr")
    os.execute("etherwake " .. mac)
    luci.http.redirect(luci.dispatcher.build_url("admin", "network", "wol"))
end

🔹 解释

  • entry({"admin", "network", "wol"}) 创建 Web UI 菜单项
  • cbi("admin_network/wol") 调用 Model (wol.lua) 处理 UCI 配置
  • function send_wol() 处理用户提交的 WOL 请求,然后执行 etherwake 命令。

6. 组件之间如何协作?

组件作用代码
Controller (Lua)处理请求,调用 Modelluci.controller.admin.wol
Model (Lua/UCI)读取/写入配置luci.model.cbi.admin_network.wol
View (HTML/JS)渲染 Web UIluci-static/resources/view/wol.js
后端进程 (C/命令行)执行 WOLetherwake

🔹 交互流程

  1. 用户打开 WOL 页面(Controller 解析请求)
  2. Controller 调用 Model 读取 UCI 配置
  3. View 生成 UI,用户输入 MAC 地址
  4. 用户点击 "发送 WOL",Controller 处理请求
  5. Controller 调用 etherwake 发送 WOL
  6. 返回到 Web UI,显示成功消息

7. 结论

LuCI 使用 MVC 架构,但 Controller 是 Lua,View 现在更多用 JavaScript。
现代 OpenWrt 主要基于 rpcdubus 进行数据交互,而不只是传统的 Lua cbi()
如果你要修改 luci-app-wol,需要改动 controller/wol.lua(后端)、view/wol.js(前端)、以及 rpcd 相关部分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/975872.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

zyNo.25

SSRF漏洞 在了解ssrf漏洞前先了解curl命令的使用 1.curl命令的使用 基本格式&#xff1a;curl<参数值>请求地址 get请求&#xff1a;curl http://127.0.0.1 post请求&#xff1a;curl -X POST -d "a1&b2" http://127.0.0.1/(其中&#xff0c;使用-X参…

2.19学习(php文件后缀)

misc buu-后门查杀 下载附件&#xff0c;我们用火绒安全扫一下然后点击详情进入该文件所在文件夹&#xff0c;再用记事本打开该文件&#xff0c;搜索flag无果&#xff0c;再试试pass&#xff08;由题目中的密码联系到pass&#xff0c;password&#xff0c;key等&#xff09;&a…

浅谈 Redis 主从复制原理(二)

大家好&#xff0c;我是此林。 【浅谈 Redis 主从集群原理&#xff08;一&#xff09; 】 上一篇文章中&#xff0c;说到了 Redis 主从复制的全量同步和增量同步&#xff0c;repl_baklog 复制缓冲区&#xff0c;以及 slave 挂掉之后数据同步的措施。 下面介绍的上一篇遗留问…

接雨水的算法

题目 代码 # 接雨水算法 def trap(height):# 1. 特殊情况&#xff1a;数组为空 则返回0if not height:return 0n len(height)# 2. 初始化左右指针&#xff0c;左右最大值&#xff0c;结果left, right 0, n - 1# maxleft代表左边最大值&#xff0c;maxright代表右边最大值max…

【C++】list 链表的使用+模拟实现

目录 文章目录 前言 一、list的简介 二、list的使用方法 三、list的模拟实现 1.基本框架&#xff1a; 2.迭代器实现 3.常用接口实现 四、完整代码 总结 前言 本文主要介绍C【STL】容器中的 list&#xff0c;包括接口说明和模拟实现。其中讲解了迭代器功能上的分类&am…

Python游戏编程之赛车游戏6-2

3.2 move()方法的定义 Player类的move()方法用于玩家控制汽车左右移动&#xff0c;当玩家点击键盘上的左右按键时&#xff0c;汽车会相应地进行左右移动。 move()方法的代码如图7所示。 图7 move()方法的代码 其中&#xff0c;第20行代码通过pygame.key.get_pressed()函数获…

RT-Thread+STM32L475VET6——ADC采集电压

文章目录 前言一、板载资源二、具体步骤1.打开CubeMX进行配置1.1 使用外部高速时钟&#xff0c;并修改时钟树1.2 打开ADC1的通道3&#xff0c;并配置为连续采集模式(ADC根据自己需求调整&#xff09;1.3 打开串口1.4 生成工程 2. 配置ADC2.1 打开ADC驱动2.2 声明ADC2.3 剪切stm…

Jupyter Notebook切换虚拟环境(Kernel管理)

我们在使用Jupyter Notebook的时候&#xff0c;打开文件发现只有一个Python3(ipykernel)&#xff0c;我们自己在conda中创建的虚拟环境为什么没有显示出来&#xff0c;今天我就来和大家一起讨论一下&#xff01; 在 Jupyter Notebook 中&#xff0c;kernel 是执行代码的核心。管…

Ubuntu 22.04 Install deepseek

前言 deepseekAI助手。它具有聊天机器人功能&#xff0c;可以与用户进行自然语言交互&#xff0c;回答问题、提供建议和帮助解决问题。DeepSeek 的特点包括&#xff1a; 强大的语言理解能力&#xff1a;能够理解和生成自然语言&#xff0c;与用户进行流畅的对话。多领域知识&…

Transformer LLaMA

一、Transformer Transformer&#xff1a;一种基于自注意力机制的神经网络结构&#xff0c;通过并行计算和多层特征抽取&#xff0c;有效解决了长序列依赖问题&#xff0c;实现了在自然语言处理等领域的突破。 Transformer 架构摆脱了RNNs&#xff0c;完全依靠 Attention的优…

mysql的源码包安装

安装方式一&#xff1a;&#xff08;编译好的直接安装&#xff09; 1.添加一块10G的硬盘&#xff0c;给root逻辑卷扩容 &#xff08;下面安装方式二有&#xff0c;一模一样的装就行&#xff0c;我就不写了&#xff0c;再写的话篇幅就太长了&#xff09; 2.下载编译好的源码包…

内网网络安全的解决之道

本文简要分析了企业内部网络所面临的主要分析&#xff0c;阐述了安全管理人员针对不同威胁的主要技术应对措施。进一步介绍了业界各种技术措施的现状&#xff0c;并提出了未来可能的发展趋势。 内网网络安全问题的提出 网络安全对于绝大多数人而言指的都是互联网安全&#xff…

【Redis原理】底层数据结构 五种数据类型

文章目录 动态字符串SDS(simple dynamic string )SDS结构定义SDS动态扩容 IntSetIntSet 结构定义IntSet的升级 DictDict结构定义Dict的扩容Dict的收缩Dict 的rehash ZipListZipListEntryencoding 编码字符串整数 ZipList的连锁更新问题 QuickListQuickList源码 SkipListRedisOb…

Orange 单体架构 - 快速启动

1 后端服务 1.1 基础设施 组件说明版本MySQLMySQL数据库服务5.7/8JavaJava17redis-stackRedis向量数据库最新版本Node安装Node22.11.0 1.2 orange-dependencies-parent 项目Maven依赖版本管理 1.2.1 项目克隆 GitHub git clone https://github.com/hengzq/orange-depende…

在线骑行|基于SpringBoot的在线骑行网站设计与实现(源码+数据库+文档)

在线骑行网站系统 目录 基于SpringBoot的在线骑行设计与实现 一、前言 二、系统设计 三、系统功能设计 5.1用户信息管理 5.2 路线攻略管理 5.3路线类型管理 5.4新闻赛事管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取…

内外网文件传输 安全、可控、便捷的跨网数据传输方案

一、背景与痛点 在内外网隔离的企业网络环境中&#xff0c;员工与外部协作伙伴&#xff08;如钉钉用户&#xff09;的文件传输面临以下挑战&#xff1a; 安全性风险&#xff1a;内外网直连可能导致病毒传播、数据泄露。 操作繁琐&#xff1a;传统方式需频繁切换网络环境&…

Unity学习笔记-Unity了解,安装,简单配置(一)

Unity 是什么&#xff1f; Unity 是一款广受欢迎的跨平台游戏开发引擎&#xff0c;由 Unity Technologies 公司开发并推出。它以强大的功能和易用性&#xff0c;在游戏开发领域占据着举足轻重的地位&#xff0c;甚至可以说&#xff0c;它改变了游戏开发的格局。凭借其出色的跨…

骁勇善战的量化利器:多因子模型【量化理论】

我叫补三补四&#xff0c;很高兴见到大家&#xff0c;欢迎一起学习交流和进步 今天来讲一讲alpha策略制定后的测试问题 风险模型雏形 股票因子受多种因素影响&#xff0c;其价格由多种因素决定&#xff0c;所谓的多因子策略就是要发掘诸如此类的因子&#xff0c;以一种合理的方…

【DeepSeek】本地部署,保姆级教程

deepseek网站链接传送门&#xff1a;DeepSeek 在这里主要介绍DeepSeek的两种部署方法&#xff0c;一种是调用API&#xff0c;一种是本地部署。 一、API调用 1.进入网址Cherry Studio - 全能的AI助手选择立即下载 2.安装时位置建议放在其他盘&#xff0c;不要放c盘 3.进入软件后…

国产编辑器EverEdit - 文本编辑器的关键特性:文件变更实时监视,多头编辑不掉坑

1 监视文件变更 1.1 应用场景 某些时候&#xff0c;用户会使用多个编辑器打开同一个文件&#xff0c;如果在A编辑器修改保存&#xff0c;但是B编辑器没有重新打开&#xff0c;直接在B编辑器修改再保存&#xff0c;则可能造成在A编辑器中修改的内容丢失&#xff0c;因此&#x…