1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# 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
var 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.
|