diff -r 87c8d96f6173 -r 2d9e83c34b23 doc/book/en/B0031-define-entities.en.txt --- /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_` 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. +