[doc] Renaming for advanced thematic.
.. -*- coding: utf-8 -*-
Parametrization and specific extensions
---------------------------------------
Dynamic default values
``````````````````````
It is possible to define in the schema *static* default values.
It is also possible to define in the schema *dynamic* default values
by defining in the entity class a method `default_<attribut name>` for
a given attribute.
Loaded attributes and default sorting management
````````````````````````````````````````````````
* The class attribute `fetch_attrs` allows to defined in an entity class
a list of names of attributes or relations that should be automatically
loaded when we recover the entities of this type. In the case of relations,
we are limited to *subject of cardinality `?` or `1`* relations.
* The class method `fetch_order(attr, var)` expects an attribute (or relation)
name as a parameter and a variable name, and it should return a string
to use in the requirement `ORDER BY` of an RQL query to automatically
sort the list of entities of such type according to this attribute, or
`None` if we do not want to sort on the attribute given in the parameter.
By default, the entities are sorted according to their creation date.
* The class method `fetch_unrelated_order(attr, var)` is similar to the
method `fetch_order` except that it is essentially used to control
the sorting of drop-down lists enabling relations creation in
the editing view of an entity.
The function `fetch_config(fetchattrs, mainattr=None)` simplifies the
definition of the attributes to load and the sorting by returning a
list of attributes to pre-load (considering automatically the attributes
of `AnyEntity`) and a sorting function based on the main attribute
(the second parameter if specified otherwisethe first attribute from
the list `fetchattrs`).
This function is defined in `cubicweb.entities`.
For example: ::
class Transition(AnyEntity):
"""..."""
id = 'Transition'
fetch_attrs, fetch_order = fetch_config(['name'])
Indicates that for the entity type "Transition", you have to pre-load
the attribute `name` and sort by default on this attribute.
Editing forms management
````````````````````````
It is possible to manage attributes/relations in the simple or multiple
editing form thanks to the following *rtags*:
* `primary`, indicates that an attribute or a relation has to be inserted
in the simple or multiple editing forms. In the case of a relation,
the related entity editing form will be included in the editing form.
* `secondary`, indicates that an attribute or a relation has to be inserted
in the simple editing form only. In the case of a relation, the related
entity editing form sill be included in the editing form.
* `generic`, indicates that a relation has to be inserted in the simple
editing form, in the generic box of relation creation.
* `generated`, indicates that an attribute is dynamically computed
or other, and that it should not be displayed in the editing form.
If necessarry, it is possible to overwrite the method
`relation_category(rtype, x='subject')` to dynamically compute
a relation editing category.
``add_related`` box management
``````````````````````````````
The box ``add_related`` is an automatic box that allows to create
an entity automatically related to the initial entity (context in
which the box is displayed). By default, the links generated in this
box are computed from the schema properties of the displayed entity,
but it is possible to explicitely specify them thanks to the
following *rtags*:
* `link`, indicates that a relation is in general created pointing
to an existing entity and that we should not to display a link
for this relation
* `create`, indicates that a relation is in general created pointing
to new entities and that we should display a link to create a new
entity and link to it automatically
If necessarry, it is possible to overwrite the method
`relation_mode(rtype, targettype, x='subject')` to dynamically
compute a relation creation category.
Please note that if at least one action belongs to the `addrelated` category,
the automatic behavior is desactivated in favor of an explicit behavior
(e.g. display of `addrelated` category actions only).
Filtering table forms management
````````````````````````````````
By default, the view ``table`` manages automatically a filtering
form of its content. The algorithm is as follows:
1. we consider that the first column contains the entities to constraint
2. we collect the first entity of the table (row 0) to represent all the
others
3. for all the others variables defined in the original request:
1. if the varaible is related to the main variable by at least one relation
2. we call the method ``filterform_vocabulary(rtype, x)`` on the entity,
if nothing is returned (meaning a tuple `Non`, see below), we go to the
next variable, otherwise a form filtering element is created based on
the vocabulary values returned
4. there is no others limitations to the `RQL`, it can include sorting, grouping
conditions... Javascripts functions are used to regenerate a request based on the
initial request and on the selected values from the filtering form.
The method ``filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)`` takes
the name of a relation and the target as parameters, which indicates of the
entity on which we apply the method is subject or object of the relation. It
has to return:
* a 2-uple of None if it does not know how to handle the relation
* a type and a list containing the vocabulary
* the list has to contain couples (value, label)
* the type indicates if the value designate an integer (`type == 'int'`),
a string (`type =='string'` or a non-final relation (`type == 'eid'`)
For example in our application managing tickets, we want to be able to filter
them by :
* type
* priority
* state (in_state)
* tag (tags)
* version (done_in)
For that we define the following method: ::
class Ticket(AnyEntity):
...
def filterform_vocabulary(self, rtype, x, var, rqlst, args, cachekey):
_ = self.req._
if rtype == 'type':
return 'string', [(x, _(x)) for x in ('bug', 'story')]
if rtype == 'priority':
return 'string', [(x, _(x)) for x in ('minor', 'normal', 'important')]
if rtype == 'done_in':
rql = insert_attr_select_relation(rqlst, var, rtype, 'num')
return 'eid', self.req.execute(rql, args, cachekey)
return super(Ticket, self).filterform_vocabulary(rtype, x, var, rqlst,
args, cachekey)
.. note::
Filtering on state and tags is automatically installed, no need to handle it.