Files
op-packages/luci-app-substore/docs/UCODE_MIGRATION.md
T

4.3 KiB
Raw Blame History

模板迁移评估:.htm (Lua) → .ut (ucode)

状态:评估完成,未执行迁移。原因:本机无 OpenWrt 构建/运行环境,.ut 模板无法编译验证,冒然上线未经验证的 .ut 比保留 .htm 更危险(若 25.12 模板加载器优先 .ut,带 bug 的 .ut 会直接覆盖原本可用的 .htm)。

1. 背景

本项目的 LuCI 前端采用 Lua 兼容模式(luci-lua-runtime + luci-compat),模板为 .htm(Lua 代码 + <% %> / <%= %> / <%: %> 标签)。

LuCI 版本 模板体系 本项目的 .htm
23.05 Lua(.htm) ✅ 原生支持
24.10 ucode(.ut)为主,Lua 兼容层保留 .htm ✅ 经 luci-lua-runtime
25.12+ 趋向 ucode(.ut),Lua 兼容层可能移除 ⚠️ 风险点

调研结论(来自 LuCI 上游变更):24.10 起 luci-base 重写为 ucode,模板加载器优先查找 .ut;.htm 通过 Lua 兼容层继续工作。25.12 若彻底移除 luci-lua-runtime,则 .htm 失效,需 .ut 模板。

2. 涉及文件(5 个模板)

root/usr/lib/lua/luci/view/substore/ 下:

  • subscriptions.htm — 订阅列表(表格、token 链接、复制按钮、多表单)
  • form.htm — 添加/编辑订阅
  • nodes.htm — 节点查看(GET 表单筛选/排序)
  • output.htm — 输出页(格式下拉、textarea)
  • settings.htm — 设置页(cron 选择器、规则)

3. .htm → .ut 语法对照

事项 Lua .htm ucode .ut
输出标签 <%=expr%> <%= expr %>(ucode 表达式)或 {{= expr }}
翻译标签 <%:Text%> <%:Text%>(保留,语义一致)
引入其它模板 <%+header%> / <%+footer%> <% include("header") %> / <% include("footer") %>
取 HTTP 参数 require("luci.http") + http.formvalue(...) 预绑定全局 http,http.formvalue(...)
取查询参数 luci.dispatcher.context.query 预绑定全局 REQUEST,REQUEST.query
迭代数组 for _, v in ipairs(t) do ... end for (let v in t) { ... }
条件 if cond then ... end if (cond) { ... }
字符串拼接 .. +
三元 a and b or c(有陷阱) cond ? a : b
取长度 #t length(t)
索引 t[k] / t.k t[k] / t.k
核心库调用 require("substore.core") 后 core.xxx() core = include("substore/core.lua") 后 core.xxx()

4. 关键决策点

  1. 核心库无需改写:/usr/share/substore/*.lua 是纯 Lua,ucode 通过 include() 加载 Lua 文件并调用其函数(ucode 内置 Lua 互操作)。这是本方案最有利的一点——迁移成本集中在 5 个模板文件的“胶水代码”,核心逻辑(解析/转换/输出)不受影响。

  2. 控制器:controller/admin/substore.lua 目前用 module() + entry()。24.10 仍支持;若 25.12 要求 ucode 控制器(.uc),则需另写 controller/admin/substore.uc。与模板一样,属胶水层。

  3. 数据存储与下载端点:core.lua、action_download 逻辑与模板语言无关,无需迁移。

5. 建议的落地策略

按“能验证再迁移”原则,分步:

  • 第 1 步(当前):保持 .htm + luci-lua-runtime 依赖,确保 23.05 / 24.10 可用。
  • 第 2 步:在真实 24.10 设备上安装,验证 .htm 经兼容层正常渲染。
  • 第 3 步:拿到 25.12 构建环境后,逐模板迁移为 .ut(可 .htm 与 .ut 并存,LuCI 优先 .ut),每个模板迁完即在设备上验证页面。
  • 第 4 步:25.12 若移除 Lua 运行时,同步评估控制器 .uc 迁移。

6. 示例迁移(subscriptions.htm 片段)

Lua 现状:

<%
local core = require("substore.core")
local items = core.list()
for _, it in ipairs(items) do
%>
  <tr><td><%=it.name%></td></tr>
<%
end
%>

ucode 等价:

<%
let core = include("substore/core.lua");
let items = core.list();
for (let it in items) {
%>
  <tr><td><%= it.name %></td></tr>
<%
}
%>

注:include("substore/core.lua") 的路径与 ucode 的 LUCI_PATH / package.path 解析规则有关,具体以 25.12 目标机的 include 路径解析为准,迁移时需在设备上确认。