luci-app-example: drop Lua

https://github.com/openwrt/luci/issues/3378
https://github.com/openwrt/luci/issues/7310

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
This commit is contained in:
Paul Donald
2026-02-24 03:15:54 +01:00
parent e83899e93e
commit f91fa4b151
4 changed files with 4 additions and 157 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ If you're doing a whole new application, instead of editing this one, you can us
## Toolchain build
Even though you're only building a simple JS + Lua package, you'll need the whole toolchain.
Even though you're only building a simple JS package, you'll need the whole toolchain.
Though the command says "install", nothing is actually installed outside of the working directory (`~/src/openwrt` in this case).
* Run `make tools/install`
+1 -2
View File
@@ -1,7 +1,6 @@
# Example app for js based Luci
This app is meant to be a starting point for developing new LuCI apps using the modern JavaScript client-rendered approach.
Previously the LuCI used a Lua server-side render approach which is deprecated now.
## Installation
@@ -22,7 +21,7 @@ ssh root@192.168.1.1 "sh /etc/uci-defaults/80_example"
Install the app on your OpenWrt installation. This can be an actual router/device, or something like a QEMU virtual machine.
`opkg install luci-app-example`
`apk add luci-app-example`
Visit the web UI for the device/virtual machine where the package was installed.
Log in to OpenWrt, and **Example** should be present in the navigation menu.
-151
View File
@@ -1,151 +0,0 @@
# Processing YAML in Lua
You may need to deal with YAML data in your Lua code.
## root/usr/libexec/rpcd/luci.example
These are the changes you would need in the `usr/libexec/rpcd/luci.example` file.
First, declare that you want YAML libraries:
```lua
-- If you need to process YAML, opkg install lyaml
local lyaml = require "lyaml"
```
Then, declare a function to handle the YAML data, and a helper to read the file
```lua
local function readfile(path)
local s = fs.readfile(path)
return s and (s:gsub("^%s+", ""):gsub("%s+$", ""))
end
local function reading_from_yaml()
-- Use the locally declared readfile() function to read in the
-- sample YAML file that ships with this package.
local example_config = readfile("/etc/luci.example.yaml")
-- Map that string to a Lua table via lyaml's load() method
local example_table = lyaml.load(example_config)
-- Convert the table to JSON
local example_json = jsonc.stringify(example_table)
-- Pass the JSON back
return example_json
end
```
Declare the method in the `methods` table
```lua
-- Converts the AGH YAML configuration into JSON for consumption by
-- the LuCI app.
get_yaml_file_sample = {
-- A special key of 'call' points to a function definition for execution.
call = function()
local r = {}
r.result = reading_from_yaml()
-- The 'call' handler will refer to '.code', but also defaults if not found.
r.code = 0
-- Return the table object; the call handler will access the attributes
-- of the table.
return r
end
},
```
## htdocs/luci-static/resources/view/example/rpc.js
These are the changes you need in the `rpc.js` file.
Declare the RPC call
```js
const load_sample_yaml = rpc.declare({
object: 'luci.example',
method: 'get_yaml_file_sample'
});
```
Add this declaration to the `view.extend()` call
```js
render_sample_yaml: function(sample) {
console.log('render_sample_yaml()');
console.log(sample);
if (sample.error) {
return this.generic_failure(sample.error)
}
// Basically, a fully static table declaration.
var table = E('table', { 'class': 'table', 'id': 'sample-yaml' }, [
E('tr', {}, [
E('td', { 'class': 'td left', 'width': '33%' }, _("Top Level Int")),
E('td', { 'class': 'td left' }, sample.top_level_int),
]),
E('tr', {}, [
E('td', { 'class': 'td left', 'width': '33%' }, _("Top Level String")),
E('td', { 'class': 'td left' }, sample.top_level_string),
])
]);
return table;
},
```
Add a call to the `load` function in `view.extend()`
```js
load: function () {
return Promise.all([
load_sample_yaml(),
load_sample1()
]);
},
```
Add this code to the `render` function in `view.extend()`
```js
E('div', { 'class': 'cbi-section', 'id': 'cbi-sample-yaml' }, [
E('div', { 'class': 'left' }, [
E('h3', _('Sample YAML via RPC')),
E('div', {}), _("YAML transformed to JSON, table built explicitly"),
this.render_sample_yaml(sample_yaml),
]),
]),
```
## root/usr/share/rpcd/acl.d/luci-app-example.json
Allow access to the new RPC API
```json
"read": {
"ubus": {
"luci.example": [
"get_yaml_file_sample",
"get_sample1",
"get_sample2"
]
},
```
## root/etc/luci.example.yaml
Set up the sample YAML file, by placing it either in `root/etc` of the development tree, or directly
in `/etc` on the target machine and call it `luci.example.yaml` to match up to the `reading_from_yaml`
function's expectations.
```yaml
top_level_string: example
top_level_int: 8080
top_level:
list_elements:
- foo
- bar
```
That's it. Don't forget to also update the `LUCI_DEPENDS` segment of the `Makefile` to include
`+lyaml` so that the packaging system knows your code needs the YAML parsing package.
+2 -3
View File
@@ -19,7 +19,6 @@
├── README.md
└── root
├── etc
│ ├── luci.example.yaml
│ └── uci-defaults
│ └── 80_example
└── usr
@@ -43,7 +42,7 @@ For the rest of this documentation, `appname` is `example`.
## Root files
At least one file must exist in `applications/luci-app-example` - a Makefile. This defines what license is to be applied to the code, and what packages are required for the package to be installed. In this example app, YAML is processed by the Lua code, so **lyaml** is marked as a dependency.
At least one file must exist in `applications/luci-app-example` - a Makefile. This defines what license is to be applied to the code, and what packages are required for the package to be installed.
A `README.md` file is also recommended. It should provide context on what the app does, and perhaps instructions on how to test things like RPC calls.
@@ -65,7 +64,7 @@ Note that there may be legacy UCI (luci-compat) grants ACL in place, permitting
## Additional files
LuCI apps do not have to have any additional files such as Lua scripts or UCI default setup. However, here's how you deal with those if needed.
LuCI apps do not have to have any additional files or UCI default setup. However, here's how you deal with those if needed.
### Installing additional files