docs: add documentation for gluon-web
This commit is contained in:
parent
31d3f08f25
commit
22746a2a0d
117
docs/dev/web/controller.rst
Normal file
117
docs/dev/web/controller.rst
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
Controllers
|
||||||
|
===========
|
||||||
|
|
||||||
|
Controllers live in ``/lib/gluon/web/controller``. They define which pages ("routes")
|
||||||
|
exist under the ``/cgi-bin/gluon`` path, and what code is run when these pages are requested.
|
||||||
|
|
||||||
|
Controller scripts mostly consist of calls of the `entry` function, which each define
|
||||||
|
one route:
|
||||||
|
|
||||||
|
.. code-block:: lua
|
||||||
|
|
||||||
|
entry({"admin"}, alias("admin", "info"), _("Advanced settings"), 10)
|
||||||
|
entry({"admin", "info"}, template("admin/info"), _("Information"), 1)
|
||||||
|
|
||||||
|
The entry function expects 4 arguments:
|
||||||
|
|
||||||
|
- `path`: Components of the path to define a route for.
|
||||||
|
|
||||||
|
The above example defines routes for the paths ``admin`` and ``admin/info``.
|
||||||
|
|
||||||
|
- `target`: Dispatcher for the route. See the following section for details.
|
||||||
|
- `title`: Page title (also used in navigation). The underscore function is used
|
||||||
|
|
||||||
|
- `order`: Sort index in navigation (defaults to 100)
|
||||||
|
|
||||||
|
Navigation indexes are automatically generated for each path level. Pages can be
|
||||||
|
hidden from the navigation by setting the `hidden` property of the node object
|
||||||
|
returned by `entry`:
|
||||||
|
|
||||||
|
.. code-block:: lua
|
||||||
|
|
||||||
|
entry({"hidden"}, alias("foo"), _("I'm hidden!")).hidden = true
|
||||||
|
|
||||||
|
|
||||||
|
Dispatchers
|
||||||
|
-----------
|
||||||
|
|
||||||
|
- *alias* (*path*, ...): Redirects to a different page. The path components are
|
||||||
|
passed as individual arguments.
|
||||||
|
- *call* (*func*, ...): Runs a Lua function for custom request handling. The given
|
||||||
|
function is called with the HTTP object and the template renderer as first
|
||||||
|
two arguments, followed by all additional arguments passed to `call`.
|
||||||
|
- *template* (*view*): Renders the given view. See :doc:`view`.
|
||||||
|
- *model* (*name*): Displays and evaluates a form as defined by the given model. See the
|
||||||
|
:doc:`model` page for an explanation of gluon-web models.
|
||||||
|
|
||||||
|
|
||||||
|
.. _web-controller-http:
|
||||||
|
|
||||||
|
The HTTP object
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The HTTP object provides information about the HTTP requests and allows to add
|
||||||
|
data to the reply. Using it directly is rarely necessary when gluon-web
|
||||||
|
models and views are used.
|
||||||
|
|
||||||
|
Useful functions:
|
||||||
|
|
||||||
|
- *getenv* (*key*): Returns a value from the CGI environment passed by the webserver.
|
||||||
|
- *formvalue* (*key*): Returns a value passed in a query string or in the content
|
||||||
|
of a POST request. If multiple values with the same name have been passed, only
|
||||||
|
the first is returned.
|
||||||
|
- *formvaluetable* (*key*): Similar to *formvalue*, but returns a table of all
|
||||||
|
values for the given key.
|
||||||
|
- *status* (*code*, *message*): Writes the HTTP status to the reply. Has no effect
|
||||||
|
if a status has already been sent or non-header data has been written.
|
||||||
|
- *header* (*key*, *value*): Adds an HTTP header to the reply to be sent to to
|
||||||
|
the client. Has no effect when non-header data has already been written.
|
||||||
|
- *prepare_content* (*mime*): Sets the *Content-Type* header to the given MIME
|
||||||
|
type, potentially setting additional headers or modifying the MIME type to
|
||||||
|
accommodate browser quirks
|
||||||
|
- *write* (*data*, ...): Sends the given data to the client. If headers have not
|
||||||
|
been sent, it will be done before the data is written.
|
||||||
|
|
||||||
|
|
||||||
|
HTTP functions are called in method syntax, for example:
|
||||||
|
|
||||||
|
.. code-block:: lua
|
||||||
|
|
||||||
|
http:write('Output!')
|
||||||
|
|
||||||
|
|
||||||
|
.. _web-controller-template-renderer:
|
||||||
|
|
||||||
|
The template renderer
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
The template renderer allows to render templates (views). The most useful functions
|
||||||
|
are:
|
||||||
|
|
||||||
|
- *render* (*view*, *scope*): Renders the given view, optionally passing a table
|
||||||
|
with additional variables to make available in the template.
|
||||||
|
- *render_string* (*str*, *scope*): Same as *render*, but the template is passed
|
||||||
|
directly instead of being loaded from the view directory.
|
||||||
|
|
||||||
|
The renderer functions are called in property syntax, for example:
|
||||||
|
|
||||||
|
.. code-block:: lua
|
||||||
|
|
||||||
|
renderer.render('layout')
|
||||||
|
|
||||||
|
|
||||||
|
Differences from LuCI
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
- Controllers must not use the *module* function to define a Lua module (*gluon-web*
|
||||||
|
will set up a proper environment for each controller itself)
|
||||||
|
- Entries are defined at top level, not inside an *index* function
|
||||||
|
- The *alias* dispatcher triggers an HTTP redirect instead of directly running
|
||||||
|
the dispatcher of the aliased route.
|
||||||
|
- The *call* dispatcher is passed a function instead of a string with a function
|
||||||
|
name.
|
||||||
|
- The *cbi* dispatcher of LuCI has been renamed to *model*.
|
||||||
|
- The HTTP POST handler support the multipart/form-data encoding only, so
|
||||||
|
``enctype="multipart/form-data"`` must be included in all *<form>* HTML
|
||||||
|
elements.
|
||||||
|
- Other dispatchers like *form* are not provided.
|
148
docs/dev/web/model.rst
Normal file
148
docs/dev/web/model.rst
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
Models
|
||||||
|
======
|
||||||
|
|
||||||
|
Models are defined in ``/lib/gluon/web/model``. 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 toplevel 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 beed 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 to anything, but it can be
|
||||||
|
overridden.
|
||||||
|
|
||||||
|
- *Section* (usually instanciated 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*)
|
55
docs/dev/web/view.rst
Normal file
55
docs/dev/web/view.rst
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
Views
|
||||||
|
=====
|
||||||
|
|
||||||
|
The template parser reads views from ``/lib/gluon/web/view``. Writing own view
|
||||||
|
should 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.
|
||||||
|
- ``<%+`` ... ``%>`` 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 an 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* and *translatef*: see :doc:`i18n`
|
@ -41,11 +41,21 @@ Developer Documentation
|
|||||||
dev/basics
|
dev/basics
|
||||||
dev/hardware
|
dev/hardware
|
||||||
dev/upgrade
|
dev/upgrade
|
||||||
dev/configmode
|
|
||||||
dev/wan
|
dev/wan
|
||||||
dev/i18n
|
|
||||||
dev/mac_addresses
|
dev/mac_addresses
|
||||||
|
|
||||||
|
gluon-web Reference
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
dev/web/controller
|
||||||
|
dev/web/model
|
||||||
|
dev/web/view
|
||||||
|
dev/web/i18n
|
||||||
|
dev/web/config-mode
|
||||||
|
|
||||||
Packages
|
Packages
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user