Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • firmware/gluon
  • 0x4A6F/gluon
  • patrick/gluon
3 results
Select Git revision
Loading items
Show changes
Showing
with 1343 additions and 21 deletions
Models
======
Models are defined in the ``model`` subdirectory of a gluon-web application
(``/lib/gluon/config-mode/model`` for the config mode; the status
page does not use any models). Model support is not part of the gluon-web core
anymore, but is provided by the *gluon-web-model* package.
Each model defines one or more forms to display on a page, and how the submitted
form data is handled.
Let's start with an example:
.. code-block:: lua
local f = Form(translate('Hostname'))
local s = f:section(Section)
local o = s:option(Value, 'hostname', translate('Hostname'))
o.default = uci:get_first('system', 'system', 'hostname')
function o:write(data)
uci:set('system', uci:get_first('system', 'system'), 'hostname', data)
uci:commit('system')
end
return f
The top-level element of a model is always a *Form*, but it is also possible for
a model to return multiple forms, which are displayed one below the other.
A *Form* has one or more *Sections*, and each *Section* has different types
of options.
All of these elements have an *id*, which is used to identify them in the HTML
form and handlers. If no ID is given, numerical IDs will be assigned automatically,
but using explicitly named elements is often advisable (and it is required if a
form does not always include the same elements, i.e., some forms, sections or
options are added conditionally). IDs are hierarchical, so in the above example,
the *Value* would get the ID ``1.1.hostname`` (value *hostname* in first section
of first form).
Classes and methods
-------------------
- *Form* (*title*, *description*, *id*)
- *Form:section* (*type*, *title*, *description*, *id*)
Creates a new section of the given type (usually *Section*).
- *Form:write* ()
Is called after the form has been submitted (but only if the data is valid). It
is called last (after all options' *write* methods) and is usually used
to commit changed UCI packages.
The default implementation of *write* doesn't do anything, but it can be
overridden.
- *Section* (usually instantiated through *Form:section*)
- *Section:option* (*type*, *id*, *title*, *description*)
Creates a new option of the given type. Option types:
- *Value*: simple text entry
- *TextValue*: multiline text field
- *ListValue*: radio buttons or dropdown selection
- *DynamicList*: variable number of text entry fields
- *Flag*: checkbox
Most option types share the same properties and methods:
- *default*: default value
- *optional*: value may be empty
- *datatype*: one of the types described in :ref:`web-model-datatypes`
By default (when *datatype* is *nil*), all values are accepted.
- *state*: has one of the values *FORM_NODATA*, *FORM_VALID* and *FORM_INVALID*
when read in a form handler
An option that has not been submitted because of its dependencies will have
the state *FORM_NODATA*, *FORM_INVALID* if the submitted value is not valid
according to the set *datatype*, and *FORM_VALID* otherwise.
- *data*: can be read in form handlers to get the submitted value
- *depends* (*self*, *option*, *value*): adds a dependency on another option
The option will only be shown when the passed option has the given value. This
is mainly useful when the other value is a *Flag* or *ListValue*.
- *depends* (*self*, *deps*): adds a dependency on multiple other options
*deps* must be a table with options as keys and values as values. The option
will only be shown when all passed options have the corresponding values.
Multiple alternative dependencies can be added by calling *depends* repeatedly.
- *value* (*self*, *value*, *text*): adds a choice to a *ListValue*
- *write* (*self*, *data*): is called with the submitted value when all form data is valid.
Does not do anything by default, but can be overridden.
The *default* value, the *value* argument to *depends* and the output *data* always have
the same type, which is usually a string (or *nil* for optional values). Exceptions
are:
- *Flag* uses boolean values
- *DynamicList* uses a table of strings
Despite its name, the *datatype* setting does not affect the returned value type,
but only defines a validator the check the submitted value with.
For a more complete example that actually makes use of most of these features,
have a look at the model of the *gluon-web-network* package.
.. _web-model-datatypes:
Data types
----------
- *integer*: an integral number
- *uinteger*: an integral number greater than or equal to zero
- *float*: a number
- *ufloat*: a number greater than or equal to zero
- *ipaddr*: an IPv4 or IPv6 address
- *ip4addr*: an IPv4 address
- *ip6addr*: an IPv6 address
- *wpakey*: a string usable as a WPA key (either between 8 and 63 characters, or 64 hex digits)
- *range* (*min*, *max*): a number in the given range (inclusive)
- *min* (*min*): a number greater than or equal to the given minimum
- *max* (*max*): a number less than or equal to the given maximum
- *irange* (*min*, *max*): an integral number in the given range (inclusive)
- *imin* (*min*): an integral number greater than or equal to the given minimum
- *imax* (*max*): an integral number less than or equal to the given maximum
- *minlength* (*min*): a string with the given minimum length
- *maxlength* (*max*): a string with the given maximum length
Differences from LuCI
---------------------
- LuCI's *SimpleForm* and *SimpleSection* are called *Form* and *Section*, respectively
- Is it not possible to add options to a *Form* directly, a *Section* must always
be created explicitly
- Many of LuCI's CBI classes have been removed, most importantly the *Map*
- The *rmempty* option attribute does not exist, use *optional* instead
- Only the described data types are supported
- Form handlers work completely differently (in particular, a *Form*'s *handle*
method should usually not be overridden in *gluon-web*)
Views
=====
The template parser reads views from the ``view`` subdirectory of a
gluon-web application (``/lib/gluon/config-mode/view`` for the config mode,
``lib/gluon/status-page/view`` for the status page).
Writing own views should usually be avoided in favour of using :doc:`model`
with their predefined views.
Views are partial HTML pages, with additional template tags that allow
to embed Lua code and translation strings. The following tags are defined:
- ``<%`` ... ``%>`` evaluates the enclosed Lua expression.
- ``<%|`` ... ``%>`` evaluates the enclosed Lua expression and prints its value.
- ``<%=`` ... ``%>`` evaluates the enclosed Lua expression and prints its value
*without escaping HTML entities*. This is useful when the value contains HTML code.
- ``<%+`` ... ``%>`` includes another template.
- ``<%:`` ... ``%>`` translates the enclosed string using the loaded i18n catalog.
- ``<%_`` ... ``%>`` translates the enclosed string *without escaping HTML entities*
in the translation. This only makes sense when the i18n catalog contains HTML code.
- ``<%#`` ... ``%>`` is a comment.
All of these also come in the whitespace-stripping variants ``<%-`` and ``-%>`` that
remove all whitespace before or after the tag.
Complex combinations of HTML and Lua code are possible, for example:
.. code-block:: text
<div>
<% if foo then %>
Content
<% end %>
</div>
Variables and functions
-----------------------
Many call sites define additional variables (for example, model templates can
access the model as *self* and a unique element ID as *id*), but the following
variables and functions should always be available for the embedded Lua code:
- *renderer*: :ref:`web-controller-template-renderer`
- *http*: :ref:`web-controller-http`
- *request*: Table containing the path components of the current page
- *url* (*path*): returns the URL for the given path, which is passed as a table of path components.
- *attr* (*key*, *value*): Returns a string of the form ``key="value"``
(with a leading space character before the key).
*value* is converted to a string (tables are serialized as JSON) and HTML entities
are escaped. Returns an empty string when *value* is *nil* or *false*.
- *include* (*template*): Includes another template.
- *node* (*path*, ...): Returns the controller node for the given page (passed as
one argument per path component).
Use ``node(unpack(request))`` to get the node for the current page.
- *pcdata* (*str*): Escapes HTML entities in the passed string.
- *urlencode* (*str*): Escapes the passed string for use in an URL.
- *translate*, *_translate*, *translatef* and *i18n*: see :doc:`i18n`
Adding SSH public keys
======================
By using the package ``gluon-authorized-keys`` it is possible to add
SSH public keys to an image to permit root login.
If you select this package, add a list of authorized keys to ``site.conf`` like this:::
{
authorized_keys = { 'ssh-rsa AAA.... user1@host',
'ssh-rsa AAA.... user2@host' },
hostname_prefix = ...
...
Existing keys in ``/etc/dropbear/authorized_keys`` will be preserved.
This diff is collapsed.
docs/features/configmode.png

112 KiB

This diff is collapsed.
This diff is collapsed.
docs/features/fastd_mode.gif

28.1 KiB

This diff is collapsed.
This diff is collapsed.
docs/features/multidomain_configmode.gif

57.1 KiB

docs/features/node_configmode.gif

50.5 KiB

Private WLAN
============
It is possible to set up a private WLAN that bridges the uplink port and is separated from the mesh network.
Please note that you should not enable Wired Mesh on the uplink port at the same time.
The private WLAN is encrypted using WPA2 by default. On devices with enough flash and a supported radio,
WPA3 or WPA2/WPA3 mixed-mode can be used instead of WPA2. For this to work, the ``wireless-encryption-wpa3``
feature has to be enabled as a feature.
It is recommended to enable IEEE 802.11w management frame protection for WPA2/WPA3 networks, however this
can lead to connectivity problems for older clients. In this case, management frame protection can be
made optional or completely disabled in the advanced settings tab.
The private WLAN can be enabled through the config mode if the package ``gluon-web-private-wifi`` is installed.
You may also enable a private WLAN using the command line::
RID=0
SSID="privateWLANname"
KEY="yoursecret1337password"
uci set wireless.wan_radio$RID=wifi-iface
uci set wireless.wan_radio$RID.device=radio$RID
uci set wireless.wan_radio$RID.network=wan
uci set wireless.wan_radio$RID.mode=ap
uci set wireless.wan_radio$RID.encryption=psk2
uci set wireless.wan_radio$RID.ssid="$SSID"
uci set wireless.wan_radio$RID.key="$KEY"
uci set wireless.wan_radio$RID.disabled=0
uci set wireless.wan_radio$RID.macaddr=$(lua -e "print(require('gluon.util').generate_mac(3+4*$RID))")
uci commit
wifi
Please replace ``$SSID`` by the name of the WLAN and ``$KEY`` by your passphrase (8-63 characters).
If you have two radios (e.g. 2.4 and 5 GHz) you need to do this for radio0 and radio1.
It may also be disabled by running::
uci set wireless.wan_radio0.disabled=1
uci commit
wifi
This diff is collapsed.
docs/features/status-page.png

150 KiB

This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.