--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B0031-define-entities.en.txt Tue Dec 23 13:50:56 2008 -0800
@@ -0,0 +1,168 @@
+.. -*- 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.
+