question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

lua to javascript migration questions

See original GitHub issue

I’ll be working on migrating luci apps for https-dns-proxy, simple-adblock, vpn-policy-routing and vpnbypass.

Just for reference I’ll copy the link from a different migration issue: http://openwrt.github.io/luci/jsapi/index.html

I use the service enable/disable and start/stop/special action buttons for all my services (example: https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/view/https-dns-proxy/buttons.htm). My plan is to obtain the service enabled/disabled and running/stop status thru a luci rpcd script.

Questions:

Generic migration questions:

  • both in model/cbi files and controllers I have calls to enable/disable and start/stop/restart services (both for my packages and sometimes dnsmasq/others) – is there a way to initiate those from javascript or should I do that from the luci rpcd script?
  • follow-up to the question above, how do I implement something to work on on_after_commit with javascript? I’ve searched within repo but only found examples inside the lua files.
  • in https-dns-proxy I have a directory with files for supported providers, in Lua it was easy to have a resource in those translatable, how do I achieve the same with the json file?
  • where is the description and what else is available for tools.widgets (as seen in luci-app-adblock):
'require tools.widgets as widgets';

As suggested by @aparcar I’m tagging @PolynomialDivision and @JonnyTischbein but also @dibdot and @Ansuel who have migrated other packages already. 😉

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
jow-commented, Feb 19, 2021

I use the service enable/disable and start/stop/special action buttons for all my services (example: https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/view/https-dns-proxy/buttons.htm). My plan is to obtain the service enabled/disabled and running/stop status thru a luci rpcd script.

There’s ubus APIs available for that.

To query enabled/disabled, use the luci / getInitList procedure, passing the init script as name parameter. CLI:

root@OpenWrt:~# ubus call luci getInitList '{ "name": "dropbear" }'`
{
	"dropbear": {
		"index": 19,
		"enabled": true
	}
}

JS:


var callInitList = rpc.declare({
  object: 'luci',
  method: 'getInitList',
  params: [ 'name' ]
});

callInitList('dropbear').then(function(reply) {
  console.debug('Dropbear is ' + reply["dropbear"].enabled);
});

To execute init actions, use the luci / setInitAction procedure.

CLI:

root@OpenWrt:~# pidof ntpd
30535
root@OpenWrt:~# ubus call luci setInitAction '{ "name": "sysntpd", "action": "stop" }'
{
	"result": true
}
root@OpenWrt:~# pidof ntpd
root@OpenWrt:~# ubus call luci setInitAction '{ "name": "sysntpd", "action": "start" }'
{
	"result": true
}
root@OpenWrt:~# pidof ntpd
30816
root@OpenWrt:~# 

JS:

var callInitAction = rpc.declare({
  object: 'luci',
  method: 'setInitAction',
  params: [ 'name', 'action' ],
  expect: { result: false }
});

callInitAction('sysntpd', 'stop').then(function(reply) {
  console.debug('Stop status: ' + reply.result);
});

Questions: * is the dependency on luci rpcd script (to obtain principal package status) necessary in this case or is there something esle I can do?

If with “luci rpcd script” you mean a custom script in /usr/libexec/rpcd/... then no, it is not strictly necessary. It usually is only required if you need to expose information or actions via ubus which are not available through other methods already.

* is there anything openwrt-specific to include this buttons.js file from /htdocs/.../package-name.js?

If you want to move common functionality into a helper library/module, you can use the LuCI specific 'require xxx'; statements in your view class. E.g. a 'require https_dns_proxy.utils as utils'; statement would fetch /www/luci-static/ressources/https_dns_proxy/utils.js and make it available as utils variable in your view class. See https://github.com/openwrt/luci/blob/master/applications/luci-app-firewall/htdocs/luci-static/resources/tools/firewall.js for an example utility class and https://github.com/openwrt/luci/blob/master/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/rules.js#L8 for a matching require statement.

* where do I place the actual buttons.js file, as well as required [css](https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/view/https-dns-proxy/css.htm) and [js](https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/view/https-dns-proxy/js.htm) files?

For .js files, see above. You’d typically place them in a subdirectory of /www/luci-static/ressources, e.g. /www/luci-static/ressources/https_dns_proxy/utils.js.

CSS files can be placed anywhere where you can access them externally, but a good convention is putting them into a subfolder of /www/luci-static/resources/css/, e.g. /www/luci-static/resources/css/https_dns_proxy/style.css. You can then import them by making sure your view renders a <link> tag, e.g. return E('link', { rel: 'stylesheet', href: L.ressource('css/https_dns_proxy/style.css') });.

* where do I place the [custom status](https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/view/https-dns-proxy/status.htm) and [custom textarea status](https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/view/https-dns-proxy/status-textarea.htm) formatting files?

Client side JS does not use any kind of templating atm, in your view class you need to render the markup using E() calls at the appropriate place, e.g.

return E('input', {
  'id': 'status',
  'name': 'status',
  'type': 'text',
  'class': 'cbi-input-text',
  'disabled': true,
  'value': ...,
  'style': 'outline:none;border:none;box-shadow:none;background:transparent;font-weight:bold;line-height:30px;height:30px;width:50em'
});

If you want to modify the behaviour our appearance of a standard CBI widget, you need to first extend it and then use it in your map.

A simple example would be:

var MyCustomizedCBIValueField = form.Value.extend({
  renderWidget: function(/* ... */) {
    var markup = form.Value.prototype.renderWidget.apply(this, arguments);

    /* customize markup DOM structure... */
    markup.disabled = true;
    markup.style.outline = 'none';
    markup.style.border = 'none';
    ...

    return markup;
  }
});

...

var o = s.option('whatever', MyCustomizedCBIValueField, _('A label'), _('A description'));

...
* the calls from the buttons are currently processed in the controller: https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/controller/https-dns-proxy.lua#L9-L27 what would be the correct way of migrating this?

In client side views you’d typically initiate server side actions right from the button click handler in an asynchronous manner, e.g.:

E('button', {
  click: function(ev) {
    ui.showModal(null, [
      E('p', { 'class': 'spinning' }, _('Stopping NTP service…'))
    ]);

    return callInitAction('sysntpd', 'stop').then(function(reply) {
      ui.hideModal();
    });
  }
}, _('Stop NTPd'))

Generic migration questions:

* both in [model/cbi](https://github.com/openwrt/luci/blob/master/applications/luci-app-vpnbypass/luasrc/model/cbi/vpnbypass.lua#L91-L93) files and [controllers](https://github.com/openwrt/luci/blob/master/applications/luci-app-https-dns-proxy/luasrc/controller/https-dns-proxy.lua#L9-L27) I have calls to enable/disable and start/stop/restart services (both for my packages and sometimes dnsmasq/others) -- is there a way to initiate those from javascript or should I do that from the luci rpcd script?

Yes, see first reply.

* follow-up to the question above, how do I implement something to work on `on_after_commit` with javascript? I've searched within repo but only found examples inside the lua files.

Depends on what you want to do exactly. Right now, a uci-applied event is broadcasted to the document whenever a uci apply operation completed, so you could do something like

document.addEventListener('uci-applied', function(ev) {
  alert('A uci apply operation just finished');
});
* in https-dns-proxy I have a directory with files for supported providers, in Lua it was easy to have a [resource in those translatable](https://github.com/stangri/source.openwrt.melmac.net/blob/master/luci-app-https-dns-proxy/luasrc/https-dns-proxy/providers/ca.cira.canadianshield.family.lua#L3), how do I achieve the same with the [json file](https://github.com/stangri/source.openwrt.melmac.net/blob/master/luci-app-https-dns-proxy-js/root/usr/share/https-dns-proxy/providers/ca.cira.canadianshield.family.json#L3)?

That might require changes to the translation infrastructure. For menu JSON files I added a special case to treat the “title” field as translation source. The same can be done for your packages, or even better we add a new file extension, like .json.intl which is then automatically preprocessed.

* where is the description and what else is available for tools.widgets (as seen in [luci-app-adblock](https://github.com/openwrt/luci/blob/master/applications/luci-app-adblock/htdocs/luci-static/resources/view/adblock/overview.js#L8)):

The tools.widgets class implements a few special widgets that require extra logic. The base widgets are documented in http://openwrt.github.io/luci/jsapi/LuCI.ui.html and their CBI wrappers in http://openwrt.github.io/luci/jsapi/LuCI.form.html

1reaction
dibdotcommented, Feb 16, 2021
Read more comments on GitHub >

github_iconTop Results From Across the Web

Create a Lua like JavaScript I18n internationalization
Here's a dirty but verbose way of accomplishing it. Is this what you're looking for?
Read more >
Lua & Javascript documentation generation
Are there any tools which can generate documentation for both Lua and Javascript? And as a bonus: we are hosting our project on...
Read more >
Why I switched from Lua to Javascript - Reddit
First, it is very simple and aside from the whole indexing-from-one thing, it has fewer surprising quirks than javascript. Tail call optimization (do...
Read more >
How to migrate 'run_on_first' in plugin's schema.lua - Questions
During the migration to Kong 2.0 from 1.4 our plugin stopped working as the run_on_first is no longer in kong.db.schema.typedefs.
Read more >
Lua Programming Language - Game development with Lua
Latest Posts. How To Learn JavaScript In 1 Hour · ARCHITECTURE OF GOOGLE CLOUD PLATFORM · AWS Certification FAQ · AWS Cloud Migration...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found