--- a/.hgtags Mon Apr 19 13:51:16 2010 +0200
+++ b/.hgtags Mon Apr 19 13:52:55 2010 +0200
@@ -117,3 +117,5 @@
8fda29a6c2191ba3cc59242c17b28b34127c75fa cubicweb-debian-version-3.7.2-1
768beb8e15f15e079f8ee6cfc35125e12b19e140 cubicweb-version-3.7.3
44c7bf90df71dd562e5a7be5ced3019da603d24f cubicweb-debian-version-3.7.3-1
+ec23f3ebcd34a92b9898b312f44d56cca748d0d6 cubicweb-version-3.7.4
+fefeda65bb83dcc2d775255fe69fdee0e793d135 cubicweb-debian-version-3.7.4-1
--- a/appobject.py Mon Apr 19 13:51:16 2010 +0200
+++ b/appobject.py Mon Apr 19 13:52:55 2010 +0200
@@ -3,6 +3,8 @@
# :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
# :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
+.. _appobject:
+
The `AppObject` class
---------------------
@@ -33,7 +35,7 @@
class::
@objectify_selector
- def one(cls, *args, **kwargs):
+ def one(cls, req, rset=None, **kwargs):
return 1
class MyView(View):
--- a/cwvreg.py Mon Apr 19 13:51:16 2010 +0200
+++ b/cwvreg.py Mon Apr 19 13:52:55 2010 +0200
@@ -7,18 +7,19 @@
The `VRegistry`
---------------
-The `VRegistry` can be seen as a two level dictionary. It contains all objects
-loaded dynamically to build a |cubicweb| application. Basically:
+The `VRegistry` can be seen as a two levels dictionary. It contains
+all dynamically loaded objects (subclasses of :ref:`appobject`) to
+build a |cubicweb| application. Basically:
-* first level key return a *registry*. This key corresponds to the `__registry__`
- attribute of application object classes
+* the first level key returns a *registry*. This key corresponds to the
+ `__registry__` attribute of application object classes
-* second level key return a list of application objects which share the same
- identifier. This key corresponds to the `__regid__` attribute of application
- object classes.
+* the second level key returns a list of application objects which
+ share the same identifier. This key corresponds to the `__regid__`
+ attribute of application object classes.
-A *registry* hold a specific kind of application objects. You've for instance
-a registry for entity classes, another for views, etc...
+A *registry* holds a specific kind of application objects. There is
+for instance a registry for entity classes, another for views, etc...
The `VRegistry` has two main responsibilities:
@@ -27,7 +28,6 @@
- handling the registration process at startup time, and during automatic
reloading in debug mode.
-
.. _AppObjectRecording:
Details of the recording process
@@ -36,21 +36,22 @@
.. index::
vregistry: registration_callback
-On startup, |cubicweb| have to load application objects defined in its library
-and in cubes used by the instance. Application objects from the library are
-loaded first, then those provided by cubes are loaded in an ordered way (e.g. if
-your cube depends on an other, objects from the dependancy will be loaded
-first). Cube's modules or packages where appobject are looked at is explained in
-:ref:`cubelayout`.
+On startup |cubicweb| loads application objects defined in its library
+and in cubes used by the instance. Application objects from the
+library are loaded first, then those provided by cubes are loaded in
+dependency order (e.g. if your cube depends on an other, objects from
+the dependency will be loaded first). Cube's modules or packages where
+appobject are looked for is explained in :ref:`cubelayout`.
For each module:
* by default all objects are registered automatically
-* if some objects have to replace other objects, or be included only if some
- condition is true, you'll have to define a `registration_callback(vreg)`
- function in your module and explicitly register **all objects** in this module,
- using the api defined below.
+* if some objects have to replace other objects, or have to be
+ included only if some condition is met, you'll have to define a
+ `registration_callback(vreg)` function in your module and explicitly
+ register **all objects** in this module, using the api defined
+ below.
.. Note::
Once the function `registration_callback(vreg)` is implemented in a module,
@@ -71,7 +72,6 @@
.. automethod:: cubicweb.cwvreg.CubicWebVRegistry.register_if_interface_found
.. automethod:: cubicweb.cwvreg.CubicWebVRegistry.unregister
-
Examples:
.. sourcecode:: python
@@ -115,13 +115,15 @@
Runtime objects selection
~~~~~~~~~~~~~~~~~~~~~~~~~
-Now that we've all application objects loaded, the question is : when I want some
-specific object, for instance the primary view for a given entity, how do I get
-the proper object ? This is what we call the **selection mechanism**.
+Now that we have all application objects loaded, the question is : when
+I want some specific object, for instance the primary view for a given
+entity, how do I get the proper object ? This is what we call the
+**selection mechanism**.
As explained in the :ref:`Concepts` section:
-* each application object has a **selector**, defined by its `__select__` class attribute
+* each application object has a **selector**, defined by its
+ `__select__` class attribute
* this selector is responsible to return a **score** for a given context
@@ -141,9 +143,9 @@
In such cases you would need to review your design and make sure your selectors
or appobjects are properly defined.
-For instance, if you are selecting the primary (eg `__regid__ = 'primary'`) view (eg
-`__registry__ = 'views'`) for a result set containing a `Card` entity, 2 objects
-will probably be selectable:
+For instance, if you are selecting the primary (eg `__regid__ =
+'primary'`) view (eg `__registry__ = 'views'`) for a result set
+containing a `Card` entity, two objects will probably be selectable:
* the default primary view (`__select__ = implements('Any')`), meaning
that the object is selectable for any kind of entity type
--- a/doc/book/en/admin/create-instance.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/admin/create-instance.rst Mon Apr 19 13:52:55 2010 +0200
@@ -20,7 +20,7 @@
sufficient. You can anyway modify the configuration later on by editing
configuration files. When a user/psswd is requested to access the database
please use the login you create at the time you configured the database
-(:ref:`ConfigurationPostgresql`).
+(:ref:`PostgresqlConfiguration`).
It is important to distinguish here the user used to access the database and the
user used to login to the cubicweb instance. When an instance starts, it uses
@@ -36,17 +36,20 @@
start / stop
~~~~~~~~~~~~
+
When this command is completed, the definition of your instance is
-located in :file:`~/etc/cubicweb.d/myinstance/*`. To launch it, you just type ::
+located in :file:`~/etc/cubicweb.d/myinstance/*`. To launch it, you
+just type ::
cubicweb-ctl start -D myinstance
-The option `-D` specify the *debug mode* : the instance is not running in
-server mode and does not disconnect from the termnial, which simplifies debugging
-in case the instance is not properly launched. You can see how it looks by
-visiting the URL `http://localhost:8080` (the port number depends of your
-configuration). To login, please use the cubicweb administrator login/psswd you
-defined when you created the instance.
+The option `-D` specifies the *debug mode* : the instance is not
+running in server mode and does not disconnect from the terminal,
+which simplifies debugging in case the instance is not properly
+launched. You can see how it looks by visiting the URL
+`http://localhost:8080` (the port number depends of your
+configuration). To login, please use the cubicweb administrator
+login/psswd you defined when you created the instance.
To shutdown the instance, Crtl-C in the terminal window is enough.
If you did not use the option `-D`, then type ::
@@ -55,6 +58,12 @@
This is it! All is settled down to start developping your data model...
+.. note::
+
+ The output of `cubicweb-ctl start -D myinstance` can be
+ overwhelming. It is possible to reduce the log level with the
+ `--loglevel` parameter as in `cubicweb-ctl start -D myinstance -l
+ info` to filter out all logs under `info` gravity.
upgrade
~~~~~~~
@@ -63,5 +72,27 @@
cubicweb-ctl upgrade myinstance
-XXX write me
+A series of questions will be asked. It always starts with a proposal
+to make a backup of your sources (where it applies). Unless you know
+exactly what you are doing (i.e. typically fiddling in debug mode, but
+definitely NOT migrating a production instance), you should answer YES
+to that.
+
+The remaining questions concern the migration steps of |cubicweb|,
+then of the cubes that form the whole application, in reverse
+dependency order.
+In principle, if the migration scripts have been properly written and
+tested, you should answer YES to all questions.
+
+Somtimes, typically while debugging a migration script, something goes
+wrong and the migration fails. Unfortunately the databse may be in an
+incoherent state. You have two options here:
+
+* fix the bug, restore the database and restart the migration process
+ from scratch (quite recommended in a production environement)
+
+* try to replay the migration up to the last successful commit, that
+ is answering NO to all question up to the step that failed, and
+ finish by answering YES to the remaining questions.
+
--- a/doc/book/en/admin/instance-config.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/admin/instance-config.rst Mon Apr 19 13:52:55 2010 +0200
@@ -157,7 +157,7 @@
:`ui.encoding`:
Character encoding to use for the web
-:`navigation.short-line-size`: # XXX should be in ui
+:`navigation.short-line-size`:
number of characters for "short" display
:`navigation.page-size`:
maximum number of entities to show per results page
--- a/doc/book/en/admin/setup.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/admin/setup.rst Mon Apr 19 13:52:55 2010 +0200
@@ -457,6 +457,3 @@
--------------------------------
.. autodocstring:: cubicweb.cwconfig
-
-
-.. |cubicweb| replace:: *CubicWeb*
--- a/doc/book/en/annexes/rql/implementation.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/annexes/rql/implementation.rst Mon Apr 19 13:52:55 2010 +0200
@@ -2,6 +2,7 @@
Implementation
--------------
+
BNF grammar
~~~~~~~~~~~
@@ -126,7 +127,7 @@
~~~~~~~~~~~~~~~~~
- The current implementation does not support linking two relations of type 'is'
- with a OR. I do not think that the negation is supported on this type of
+ with an OR. I do not think that the negation is supported on this type of
relation (XXX FIXME to be confirmed).
- Relations defining the variables must be left to those using them. For
@@ -140,11 +141,11 @@
is not.
-- missing proper explicit type conversion, COALESCE and certainly other things...
+- missing proper explicit type conversion, COALESCE and certainly other things...
-- writing a rql query require knowledge of the schema used (with real relation
- names and entities, not those viewing in the user interface). On the other
- hand, we can not really bypass that, and it is the job of a user interface to
+- writing an rql query requires knowledge of the used schema (with real relation
+ names and entities, not those viewed in the user interface). On the other
+ hand, we cannot really bypass that, and it is the job of a user interface to
hide the RQL.
--- a/doc/book/en/annexes/rql/language.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/annexes/rql/language.rst Mon Apr 19 13:52:55 2010 +0200
@@ -373,3 +373,15 @@
DELETE X friend Y WHERE X is Person, X name 'foo'
+Virtual RQL relations
+~~~~~~~~~~~~~~~~~~~~~
+
+Those relations may only be used in RQL query and are not actual
+attributes of your entities.
+
+* `has_text`: relation to use to query the full text index (only for
+ entities having fulltextindexed attributes).
+
+* `identity`: relation to use to tell that a RQL variable should be
+ the same as another (but you've to use two different rql variables
+ for querying purpose)
--- a/doc/book/en/conf.py Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/conf.py Mon Apr 19 13:52:55 2010 +0200
@@ -45,7 +45,7 @@
# General substitutions.
project = 'CubicWeb'
-copyright = '2008-2010, Logilab'
+copyright = '2001-2010, Logilab'
# The default replacements for |version| and |release|, also used in various
# other places throughout the built documents.
@@ -188,4 +188,11 @@
# If false, no module index is generated.
#latex_use_modindex = True
+
#aafig_format = dict(latex='pdf', html='svg', text=None)
+
+rst_epilog = """
+.. |cubicweb| replace:: *CubicWeb*
+.. |yams| replace:: *Yams*
+.. |rql| replace:: *RQL*
+"""
--- a/doc/book/en/development/datamodel/baseschema.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/datamodel/baseschema.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,4 +1,4 @@
-.. _CWBaseEntityTypes:
+.. _pre_defined_entity_types:
Pre-defined entities in the library
-----------------------------------
--- a/doc/book/en/development/datamodel/definition.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/datamodel/definition.rst Mon Apr 19 13:52:55 2010 +0200
@@ -3,37 +3,72 @@
Yams *schema*
-------------
-The **schema** is the core piece of a *CubicWeb* instance as it defines
-the handled data model. It is based on entity types that are either already
-defined in the *CubicWeb* standard library; or more specific types defined
-in cubes. The schema for a cube is defined in a :file:schema.py file or in
-one or more Python files under the :file:`schema` directory (python package).
+The **schema** is the core piece of a *CubicWeb* instance as it
+defines and handles the data model. It is based on entity types that
+are either already defined in `Yams`_ and the *CubicWeb* standard
+library; or more specific types defined in cubes. The schema for a
+cube is defined in a `schema` python module or package.
+
+.. _`Yams`: http://www.logilab.org/project/yams
+
+Overview
+~~~~~~~~
-At this point, it is important to make clear the difference between
-*relation type* and *relation definition*: a *relation type* is only a relation
-name with potentially other additional properties (see below), whereas a
-*relation definition* is a complete triplet
-"<subject entity type> <relation type> <object entity type>".
+The core idea of the yams schema is not far from the classical
+`Entity-relationship`_ model. But while an E/R model (or `logical
+model`) traditionally has to be manually translated to a lower-level
+data description language (such as the SQL `create table`
+sublanguage), also often described as the `physical model`, no such
+step is required with |yams| and |cubicweb|.
+
+.. _`Entity-relationship`: http://en.wikipedia.org/wiki/Entity-relationship_model
+
+This is because in addition to high-level, logical |yams| models, one
+uses the |rql| data manipulation language to query, insert, update and
+delete data. |rql| abstracts as much of the underlying SQL database as
+a |yams| schema abstracts from the physical layout. The vagaries of
+SQL are avoided.
+
+As a bonus point, such abstraction make it quite comfortable to build
+or use different backends to which |rql| queries apply.
-Also, it should be clear that to properly handle data migration, an
-instance's schema
-is stored in the database, so the python schema file used to defined it is only read
-when the instance is created or upgraded.
+So, as in the E/R formalism, the building blocks are ``entities``
+(:ref:`EntityType`), ``relationships`` (:ref:`RelationType`,
+:ref:`RelationDefinition`) and ``attributes`` (handled like relation
+with |yams|).
+
+Let us detail a little the divergences between E/R and |yams|:
-The following built-in types are available: `String`, `Int`, `Float`,
-`Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte`
-and `Password`.
+* all relationship are binary which means that to represent a
+ non-binary relationship, one has to use an entity,
+* relationships do not support attributes (yet, see:
+ https://www.logilab.net/cwo/ticket/341318), hence the need to reify
+ it as an entity if need arises,
+* all entities have an `eid` attribute (an integer) that is its
+ primary key (but it is possible to declare uniqueness on other
+ attributes)
+
+Also |yams| supports the notions of:
-You'll also have access to :ref:`base CubicWeb entity types <CWBaseEntityTypes>`.
+* entity inheritance,
+* relation type: that is, relationships can be established over a set
+ of couple of entity types (henre the distinction made between
+ `RelationType` and `RelationDefinition` below)
+
+Finally |yams| has a few concepts of its own:
-The instance schema is accessible through the .schema attribute of the
-`vregistry`. It's an instance of :class:`cubicweb.schema.Schema`, which
-extends :class:`yams.schema.Schema`.
+* relationships being oriented and binary, we call the left hand
+ entity type the `subject` and the right hand entity type the
+ `object`
+
+.. note::
-:note:
- In previous yams versions, almost all classes where available without
- any import, but the should now be explicitly imported.
+ The |yams| schema is available at run time through the .schema
+ attribute of the `vregistry`. It's an instance of
+ :class:`cubicweb.schema.Schema`, which extends
+ :class:`yams.schema.Schema`.
+.. _EntityType:
Entity type
~~~~~~~~~~~
@@ -42,21 +77,34 @@
a set of attributes and relations, and some permissions which define who can add, read,
update or delete entities of this type.
-XXX yams inheritance
+The following built-in types are available: ``String``, ``Int``,
+``Float``, ``Decimal``, ``Boolean``, ``Date``, ``Datetime``, ``Time``,
+``Interval``, ``Byte`` and ``Password``. They can only be used as
+attributes of an other entity type.
+
+You can find more base entity types in
+:ref:`pre_defined_entity_types`.
+
+.. XXX yams inheritance
.. _RelationType:
Relation type
~~~~~~~~~~~~~
-A relation type is an instance of :class:`yams.schema.RelationSchema`. A relation type is simply
-a semantic definition of a kind of relationship that may occur in an application.
+A relation type is an instance of
+:class:`yams.schema.RelationSchema`. A relation type is simply a
+semantic definition of a kind of relationship that may occur in an
+application.
+
+It may be referenced by zero, one or more relation definitions.
-It is important to choose a good name, at least to avoid conflicts with some semantically
-different relation defined in other cubes (since we've no name space yet).
+It is important to choose a good name, at least to avoid conflicts
+with some semantically different relation defined in other cubes
+(since there's only a shared name space for these names).
-A relation type holds the following properties (which are hence shared between all
-relation definitions of that type):
+A relation type holds the following properties (which are hence shared
+between all relation definitions of that type):
* `inlined`: boolean handling the physical optimization for archiving
the relation in the subject entity table, instead of creating a specific
@@ -67,79 +115,91 @@
* `symmetric`: boolean indicating that the relation is symmetrical, which
means that `X relation Y` implies `Y relation X`.
+.. _RelationDefinition:
Relation definition
~~~~~~~~~~~~~~~~~~~
-A relation definition is an instance of :class:`yams.schema.RelationDefinition`. It is a complete triplet
+A relation definition is an instance of
+:class:`yams.schema.RelationDefinition`. It is a complete triplet
"<subject entity type> <relation type> <object entity type>".
When creating a new instance of that class, the corresponding
:class:`RelationType` instance is created on the fly if necessary.
-
Properties
``````````
-* Optional properties for attributes and relations:
+The available properties for relation definitions are enumerated
+here. There are several kind of properties, as some relation
+definitions are actually attribute definitions, and other are not.
- - `description`: a string describing an attribute or a relation. By default
- this string will be used in the editing form of the entity, which means
- that it is supposed to help the end-user and should be flagged by the
- function `_` to be properly internationalized.
+Some properties may be completely optional, other may have a default
+value.
+
+Common properties for attributes and relations:
- - `constraints`: a list of conditions/constraints that the relation has to
- satisfy (c.f. `Constraints`_)
+* `description`: an unicode string describing an attribute or a
+ relation. By default this string will be used in the editing form of
+ the entity, which means that it is supposed to help the end-user and
+ should be flagged by the function `_` to be properly
+ internationalized.
- - `cardinality`: a two character string specifying the cardinality of the
- relation. The first character defines the cardinality of the relation on
- the subject, and the second on the object. When a relation can have
- multiple subjects or objects, the cardinality applies to all,
- not on a one-to-one basis (so it must be consistent...). The possible
- values are inspired from regular expression syntax:
+* `constraints`: a list of conditions/constraints that the relation has to
+ satisfy (c.f. `Constraints`_)
+
+* `cardinality`: a two character string specifying the cardinality of
+ the relation. The first character defines the cardinality of the
+ relation on the subject, and the second on the object. When a
+ relation can have multiple subjects or objects, the cardinality
+ applies to all, not on a one-to-one basis (so it must be
+ consistent...). Default value is '**'. The possible values are
+ inspired from regular expression syntax:
* `1`: 1..1
* `?`: 0..1
* `+`: 1..n
* `*`: 0..n
-* optional properties for attributes:
+Attributes properties:
- - `unique`: boolean indicating if the value of the attribute has to be unique
- or not within all entities of the same type (false by default)
+* `unique`: boolean indicating if the value of the attribute has to be
+ unique or not within all entities of the same type (false by
+ default)
- - `indexed`: boolean indicating if an index needs to be created for this
- attribute in the database (false by default). This is useful only if
- you know that you will have to run numerous searches on the value of this
- attribute.
+* `indexed`: boolean indicating if an index needs to be created for
+ this attribute in the database (false by default). This is useful
+ only if you know that you will have to run numerous searches on the
+ value of this attribute.
- - `default`: default value of the attribute. In case of date types, the values
- which could be used correspond to the RQL keywords `TODAY` and `NOW`.
+* `default`: default value of the attribute. In case of date types, the values
+ which could be used correspond to the RQL keywords `TODAY` and `NOW`.
-* optional properties for type `String` attributes:
+Properties for `String` attributes:
- - `fulltextindexed`: boolean indicating if the attribute is part of
- the full text index (false by default) (*applicable on the type `Byte`
- as well*)
+* `fulltextindexed`: boolean indicating if the attribute is part of
+ the full text index (false by default) (*applicable on the type
+ `Byte` as well*)
- - `internationalizable`: boolean indicating if the value of the attribute
- is internationalizable (false by default)
+* `internationalizable`: boolean indicating if the value of the
+ attribute is internationalizable (false by default)
-* optional properties for relations:
+Relation properties:
- - `composite`: string indicating that the subject (composite == 'subject')
- is composed of the objects of the relations. For the opposite case (when
- the object is composed of the subjects of the relation), we just set
- 'object' as value. The composition implies that when the relation
- is deleted (so when the composite is deleted, at least), the composed are also deleted.
+* `composite`: string indicating that the subject (composite ==
+ 'subject') is composed of the objects of the relations. For the
+ opposite case (when the object is composed of the subjects of the
+ relation), we just set 'object' as value. The composition implies
+ that when the relation is deleted (so when the composite is deleted,
+ at least), the composed are also deleted.
- - `fulltext_container`: string indicating if the value if the full text
- indexation of the entity on one end of the relation should be used
- to find the entity on the other end. The possible values are
- 'subject' or 'object'. For instance the use_email relation has
- that property set to 'subject', since when performing a full text
- search people want to find the entity using an email address, and not
- the entity representing the email address.
+* `fulltext_container`: string indicating if the value if the full
+ text indexation of the entity on one end of the relation should be
+ used to find the entity on the other end. The possible values are
+ 'subject' or 'object'. For instance the use_email relation has that
+ property set to 'subject', since when performing a full text search
+ people want to find the entity using an email address, and not the
+ entity representing the email address.
Constraints
```````````
@@ -172,7 +232,7 @@
* `StaticVocabularyConstraint`: identical to "vocabulary=(...)"
-XXX Attribute, NOW
+.. XXX Attribute, NOW
RQL Based Constraints
......................
@@ -200,7 +260,9 @@
than a single result to be satisfied. In this query the variables `S` is
reserved for the relation subject entity. The other variables should be
specified with the second constructor argument (mainvars). This constraints
- should be used when UniqueConstraint doesn't fit. Here is a simple example ::
+ should be used when UniqueConstraint doesn't fit. Here is a simple example.
+
+.. sourcecode:: python
# Check that in the same Workflow each state's name is unique. Using
# UniqueConstraint (or unique=True) here would prevent states in different
@@ -210,15 +272,12 @@
RQLUniqueConstraint('S name N, S state_of WF, Y state_of WF, Y name N',
mainvars='Y',
- msg=_('workflow already have a state of that name'))
-
+ msg=_('workflow already has a state of that name'))
-
-XXX note about how to add new constraint
+.. XXX note about how to add new constraint
.. _securitymodel:
-
The security model
~~~~~~~~~~~~~~~~~~
@@ -557,3 +616,15 @@
* because of the genericity of the entity type `CWPermission`, we have to execute
a unification with the groups and/or the states if necessary in the expression
("U in_group G, P require_group G" in the above example)
+
+
+
+Handling schema changes
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Also, it should be clear that to properly handle data migration, an
+instance's schema is stored in the database, so the python schema file
+used to defined it is only read when the instance is created or
+upgraded.
+
+.. XXX complete me
--- a/doc/book/en/development/datamodel/metadata.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/datamodel/metadata.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,6 +1,6 @@
-Meta-data
----------
+Metadata
+--------
.. index::
schema: meta-data;
@@ -9,46 +9,29 @@
Each entity type in |cubicweb| has at least the following meta-data attributes and relations:
-eid
+`eid`
entity's identifier which is unique in an instance. We usually call this identifier `eid` for historical reason.
-creation_date
+`creation_date`
Date and time of the creation of the entity.
-modification_date
+`modification_date`
Date and time of the latest modification of an entity.
-cwuri
+`cwuri`
Reference URL of the entity, which is not expected to change.
-created_by
+`created_by`
Relation to the :ref:`users <CWUser>` who has created the entity
-owned_by
+`owned_by`
Relation to :ref:`users <CWUser>` whom the entity belongs; usually the creator but not
necessary, and it could have multiple owners notably for permission control
-is
+`is`
Relation to the :ref:`entity type <CWEType>` of which type the entity is.
-is_instance
+`is_instance`
Relation to the :ref:`entity types <CWEType>` of which type the
entity is an instance of.
-
-Virtual RQL relations
----------------------
-XXX move this to the RQL chapter.
-
-Those relations may only be used in RQL query and are not actual attributes of your entities...
-
-has_text
- Relation to use to query the full text index (only for entities having fulltextindexed attributes).
-
-identity
- Relation to use to tell that a RQL variable should be the same as entity another
- (but you've to use two different rql variables for querying purpose)
-
-
-
-.. |cubicweb| replace:: *CubicWeb*
\ No newline at end of file
--- a/doc/book/en/development/devcore/dbapi.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devcore/dbapi.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,6 +1,6 @@
-
+.. _dbapi:
-API Python/RQL
+Python/RQL API
~~~~~~~~~~~~~~
The Python API developped to interface with RQL is inspired from the standard db-api,
@@ -9,24 +9,19 @@
.. sourcecode:: python
- execute(rqlstring, args=None, cachekey=None, build_descr=True)
+ execute(rqlstring, args=None, build_descr=True)
:rqlstring: the RQL query to execute (unicode)
:args: if the query contains substitutions, a dictionary containing the values to use
-:cachekey:
- an implementation detail of the RQL cache implies that if a substitution
- is used to introduce an eid *susceptible to raise the ambiguities in the query
- type resolution*, then we have to specify the corresponding key in the dictionary
- through this argument
-
The `Connection` object owns the methods `commit` and `rollback`. You
*should never need to use them* during the development of the web
interface based on the *CubicWeb* framework as it determines the end
of the transaction depending on the query execution success. They are
-however useful in other contexts such as tests.
+however useful in other contexts such as tests or custom controllers.
.. note::
+
While executing update queries (SET, INSERT, DELETE), if a query generates
an error related to security, a rollback is automatically done on the current
transaction.
@@ -67,7 +62,8 @@
.. sourcecode:: python
- self._cw.execute('Any T WHERE T in_conf C, C name IN (%s)' % ','.join(['foo', 'bar']))
+ self._cw.execute('Any T WHERE T in_conf C, C name IN (%s)'
+ % ','.join(['foo', 'bar']))
Alternativelly, some of the common data related to an entity can be
obtained from the `entity.related()` method (which is used under the
@@ -78,6 +74,46 @@
entity.related('in_conf', 'object')
-Additionnaly this benefits from the fetch_attrs policy eventually
-defined on the class element, which says which attributes must be also
-loaded when the entity is loaded through the orm.
+Additionnaly this benefits from the fetch_attrs policy (see
+:ref:`FetchAttrs`) eventually defined on the class element, which says
+which attributes must be also loaded when the entity is loaded through
+the orm.
+
+
+.. _resultset:
+
+The `ResultSet` API
+~~~~~~~~~~~~~~~~~~~
+
+ResultSet instances are a very commonly manipulated object. They have
+a rich API as seen below, but we would like to highlight a bunch of
+methods that are quite useful in day-to-day practice:
+
+* `__str__()` (applied by `print`) gives a very useful overview of both
+ the underlying RQL expression and the data inside; unavoidable for
+ debugging purposes
+
+* `printable_rql()` produces back a well formed RQL expression as a
+ string; it is very useful to build views
+
+* `entities()` returns a generator on all entities of the result set
+
+* `get_entity(row, col)` gets the entity at row, col coordinates; one
+ of the most used result set method
+
+.. autoclass:: cubicweb.rset.ResultSet
+ :members:
+
+
+The `Cursor` API
+~~~~~~~~~~~~~~~~
+
+The whole cursor API is developped below.
+
+.. note:
+
+ In practice we use the `.execute` method on the _cw object of
+ appobjects. Usage of other methods is quite rare.
+
+.. autoclass:: cubicweb.dbapi.Cursor
+ :members:
--- a/doc/book/en/development/devrepo/hooks.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devrepo/hooks.rst Mon Apr 19 13:52:55 2010 +0200
@@ -41,7 +41,7 @@
* implement computed attributes
-Operations are Hook-like objects that maye be created by Hooks and
+Operations are Hook-like objects that may be created by Hooks and
scheduled to happen just before (or after) the `commit` event. Hooks
being fired immediately on data operations, it is sometime necessary
to delay the actual work down to a time where all other Hooks have
@@ -56,7 +56,7 @@
Operations are subclasses of the Operation class in `server/hook.py`,
implementing `precommit_event` and other standard methods (wholly
-described later in this chapter).
+described in :ref:`operations_api`).
Events
------
@@ -219,6 +219,7 @@
is no self.entity, but `self.eidfrom` and `self.eidto` hook attributes
which represent the subject and object eid of the relation.
+
Using Operations
----------------
@@ -325,6 +326,8 @@
A more realistic example can be found in the advanced tutorial
chapter :ref:`adv_tuto_security_propagation`.
+.. _operations_api:
+
Operation: a small API overview
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -416,7 +419,7 @@
manager.
This can be controlled more finely through the `category` Hook class
-attribute.
+attribute, which is a string.
.. sourcecode:: python
@@ -424,3 +427,10 @@
# ... do stuff
.. autoclass:: cubicweb.server.session.hooks_control
+
+The existing categories are: ``email``, ``syncsession``,
+``syncschema``, ``bookmark``, ``security``, ``worfklow``,
+``metadata``, ``notification``, ``integrity``, ``activeintegrity``.
+
+Nothing precludes one to invent new categories and use the
+hooks_control context manager to filter them (in or out).
--- a/doc/book/en/development/devweb/rtags.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/rtags.rst Mon Apr 19 13:52:55 2010 +0200
@@ -7,7 +7,7 @@
~~~~~~~~~~~~~
.. automodule:: cubicweb.rtags
-.. _uicfg_module:
+.. _uicfg:
The ``uicfg`` module
~~~~~~~~~~~~~~~~~~~~
--- a/doc/book/en/development/devweb/views/autoform.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/autoform.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,69 +1,92 @@
-The automatic entity form (:mod:`cubicweb.web.views.autoform`)
----------------------------------------------------------------
+The automatic entity form
+-------------------------
+
+(:mod:`cubicweb.web.views.autoform`)
Tags declaration
-~~~~~~~~~~~~~~~~~~~~
+````````````````
It is possible to manage attributes/relations in the simple or multiple
-editing form thanks of the methods bellow ::
+editing form using proper uicfg tags.
+
+.. sourcecode:: python
uicfg.autoform_section.tag_subject_of(<relation>, tag)
uicfg.autoform_section.tag_object_of(<relation>, tag)
uicfg.autoform_field.tag_attribute(<attribut_def>, tag)
-Where ``<relation>`` is a three elements tuple ``(Subject Entity Type,
-relation_type, Object Entity Type)``. ``<attribut_def>`` is a two elements tuple
-``(Entity Type, Attribut Name)``. Wildcard ``*`` could be used in place of
-``Entity Type``
+The details of the uicfg syntax can be found in the :ref:`uicfg`
+chapter.
Possible tags are detailled below
-Simple Tags
-~~~~~~~~~~~~~~~~~~~~
+Automatic form configuration
+````````````````````````````
+
+Attributes/relations display location
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-* `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 and represented as a combobox. Each item of the
- combobox is a link to an existing entity.
+``uicfg.autoform_section`` specifies where to display a relation in
+creation/edition entity form for a given form type. ``tag_attribute``,
+``tag_subject_of`` and ``tag_object_of`` methods for this relation tag expect
+two arguments additionally to the relation key: a ``formtype`` and a
+``section``.
+
+``formtype`` may be one of:
+
+* ``main``, the main entity form (via the modify action)
+* ``inlined``, the form for an entity inlined into another form
+* ``muledit``, the table form to edit multiple entities
+
+section may be one of:
+
+* ``hidden``, don't display
-* `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 will be included in the
- editing form and represented as a combobox. Each item of the combobox
- is a link to an existing entity.
+* ``attributes``, display in the attributes section
+
+* ``relations``, display in the relations section, using the generic relation
+ selector combobox (available in main form only, and not for attribute
+ relation)
-* `inlineview`, includes the target entity's form in the editing form
- of the current entity. It allows to create the target entity in the
- same time as the current entity.
+* ``inlined``, display target entity of the relation in an inlined form
+ (available in main form only, and not for attribute relation)
+
+* ``metadata``, display in a special metadata form (NOT YET IMPLEMENTED, subject
+ to changes)
-* `generic`, indicates that a relation has to be inserted in the simple
- editing form, in the generic box of relation creation.
+By default, mandatory relations are displayed in the ``attributes`` section,
+others in ``relations`` section.
+
+Change default fields
+^^^^^^^^^^^^^^^^^^^^^
-* `generated`, indicates that an attribute is dynamically computed
- or other, and that it should not be displayed in the editing form.
+Use ``autoform_field`` to replace the default field type of an attribute.
-If necessary, it is possible to overwrite the method
-`relation_category(rtype, x='subject')` to dynamically compute
-a relation editing category.
+.. warning::
+
+ ``autoform_field_kwargs`` should usually be used instead of
+ ``autoform_field``. Do not use both methods for the same relation!
-Advanced Tags
-~~~~~~~~~~~~~~~~~~~~
+Customize field options
+^^^^^^^^^^^^^^^^^^^^^^^
+
+In order to customize field options (see :class:`cubicweb.web.formfields.Field`
+for a detailed list of options), use ``autoform_field_kwargs``. This rtag takes
+a relation triplet and a dictionary as arguments.
-Tag can also reference a custom Field crafted with the help of
-``cubicweb.web.formfields`` and ``cubicweb.web.formwidget``. In the example
-bellow, the field ``path`` of ``ExecData`` entities will be done with a standard
-file input dialogue ::
+.. sourcecode:: python
- from cubicweb.web import uicfg, formfields, formwidgets
-
- uicfg.autoform_field.tag_attribute(('Execdata', 'path'),
- formfields.FileField(name='path', widget=formwidgets.FileInput()))
+ # Change the content of the combobox
+ # here ``ticket_done_in_choices`` is a function which returns a list of
+ # elements to populate the combobox
+ uicfg.autoform_field_kwargs.tag_subject_of(('Ticket', 'done_in', '*'), {'sort': False,
+ 'choices': ticket_done_in_choices})
-
+Overriding permissions
+^^^^^^^^^^^^^^^^^^^^^^
-
-
+``autoform_permissions_overrides`` provides a way to by-pass security checking
+for dark-corner case where it can't be verified properly. XXX documents.
--- a/doc/book/en/development/devweb/views/basetemplates.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/basetemplates.rst Mon Apr 19 13:52:55 2010 +0200
@@ -39,6 +39,8 @@
TheMainTemplate
---------------
+.. _the_main_template_sections:
+
Layout and sections
```````````````````
--- a/doc/book/en/development/devweb/views/baseviews.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/baseviews.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,14 +1,14 @@
.. -*- coding: utf-8 -*-
-Base views (:mod:`cubicweb.web.views.baseviews`)
-------------------------------------------------
+Base views
+----------
-*CubicWeb* provides a lot of standard views. You can find them in
-``cubicweb/web/views/``.
+*CubicWeb* provides a lot of standard views, that can be found in
+ :mod:`cubicweb.web.views` and :mod:`cubicweb.web.views.baseviews`.
-A certain number of views are used to build the web interface, which apply
-to one or more entities. Their identifier is what distinguish them from
-each others and the main ones are:
+A certain number of views are used to build the web interface, which
+apply to one or more entities. Their identifier is what distinguish
+them from each others and the main ones are:
HTML views
~~~~~~~~~~
@@ -24,22 +24,27 @@
Display the value of a cell without trasnformation (in case of a non final
entity, we see the eid). Applicable on any result set.
+.. note::
+
+ `final` entities are merely attributes.
+
*null*
This view is the default view used when nothing needs to be rendered.
- It is always applicable and it does not return anything
+ It is always applicable.
Entity views
````````````
+
*incontext, outofcontext*
Those are used to display a link to an entity, depending on the
entity having to be displayed in or out of context
- (of another entity). By default it respectively returns the
+ (of another entity). By default it respectively produces the
result of `textincontext` and `textoutofcontext` wrapped in a link
leading to the primary view of the entity.
*oneline*
This view is used when we can't tell if the entity should be considered as
- displayed in or out of context. By default it returns the result of `text`
+ displayed in or out of context. By default it produces the result of `text`
in a link leading to the primary view of the entity.
List
@@ -67,6 +72,7 @@
Text entity views
~~~~~~~~~~~~~~~~~
+
*text*
This is the simplest text view for an entity. By default it returns the
result of the `.dc_title` method, which is cut to fit the
--- a/doc/book/en/development/devweb/views/boxes.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/boxes.rst Mon Apr 19 13:52:55 2010 +0200
@@ -33,3 +33,4 @@
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).
+
--- a/doc/book/en/development/devweb/views/breadcrumbs.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/breadcrumbs.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,3 +1,58 @@
-Breadcrumbs (:mod:`cubicweb.web.views.ibreadcrumbs`)
-----------------------------------------------------
-XXX feedme
\ No newline at end of file
+Breadcrumbs
+-----------
+
+Breadcrumbs are a navigation component to help the user locate himself
+along a path of entities.
+
+Display
+~~~~~~~
+
+Breadcrumbs are displayed by default in the header section (see
+:ref:`the_main_template_sections`). With the default main
+template, the header section is composed by the logo, the application
+name, breadcrumbs and, at the most right, the login box. Breadcrumbs
+are displayed just next to the application name, thus breadcrumbs
+begin with a separator.
+
+Here is the header section of the CubicWeb's forge:
+
+.. image:: ../../../images/breadcrumbs_header.png
+
+There are three breadcrumbs components defined in
+:mod:`cubicweb.web.views.ibreadcrumbs`:
+
+- `BreadCrumbEntityVComponent`: displayed for a result set with one line
+ if the entity implements the ``IBreadCrumbs`` interface.
+- `BreadCrumbETypeVComponent`: displayed for a result set with more than
+ one line, but with all entities of the same type which implement the
+ ``IBreadCrumbs`` interface.
+- `BreadCrumbAnyRSetVComponent`: displayed for any other result set.
+
+Building breadcrumbs
+~~~~~~~~~~~~~~~~~~~~
+
+The ``IBreadCrumbs`` interface is defined in the
+:mod:`cubicweb.interfaces` module. It specifies that an entity which
+implements this interface must have a ``breadcrumbs`` method.
+
+.. note::
+
+ Redefining the breadcrumbs is the hammer way to do it. Another way
+ is to define the `parent` method on an entity (as defined in the
+ `ITree` interface). If available, it will be used to compute
+ breadcrumbs.
+
+Here is the API of the ``breadcrumbs`` method:
+
+.. automethod:: cubicweb.interfaces.IBreadCrumbs.breadcrumbs
+
+If the breadcrumbs method return a list of entities, the
+``cubicweb.web.views.ibreadcrumbs.BreadCrumbView`` is used to display
+the elements.
+
+By default, for any entity, if recurs=True, breadcrumbs method returns
+a list of entities, else a list of a simple string.
+
+In order to see a hierarchical breadcrumbs, entities must have a
+``parent`` method which returns the parent entity. By default this
+method doesn't exist on entity, given that it can not be guessed.
--- a/doc/book/en/development/devweb/views/editforms.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/editforms.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,3 +1,6 @@
-Standard forms (:mod:`cubicweb.web.views.editforms`)
-----------------------------------------------------
+Standard forms
+--------------
+
+ (:mod:`cubicweb.web.views.editforms`)
+
XXX feed me
--- a/doc/book/en/development/devweb/views/embedding.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/embedding.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,9 +1,9 @@
.. -*- coding: utf-8 -*-
-Embedding external pages (:mod:`cubicweb.web.views.embedding`)
----------------------------------------------------------------
+Embedding external pages
+------------------------
+
+(:mod:`cubicweb.web.views.embedding`)
including external content
-XXX feeed me
-
--- a/doc/book/en/development/devweb/views/facets.rst Mon Apr 19 13:51:16 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Facets (:mod:`cubicweb.web.views.facets`)
------------------------------------------
-XXX feed me
--- a/doc/book/en/development/devweb/views/idownloadable.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/idownloadable.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,3 +1,5 @@
-The 'download' view (:mod:`cubicweb.web.views.idownloadable`)
----------------------------------------------------------------
+The 'download' view
+-------------------
+(:mod:`cubicweb.web.views.idownloadable`)
+
--- a/doc/book/en/development/devweb/views/index.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/index.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,8 +1,6 @@
The View system
===============
-.. |cubicweb| replace:: *CubicWeb*
-
This chapter aims to describe the concept of a `view` used all along
the development of a web application and how it has been implemented
in |cubicweb|.
@@ -27,7 +25,6 @@
urlpublish
breadcrumbs
-.. facets
.. wdoc
.. embedding
.. idownloadable
--- a/doc/book/en/development/devweb/views/primary.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/primary.rst Mon Apr 19 13:52:55 2010 +0200
@@ -203,7 +203,7 @@
overwrite ``render_entity`` unless you want a completely different layout.
Example of customization and creation
--------------------------------------
+`````````````````````````````````````
We'll show you now an example of a ``primary`` view and how to customize it.
--- a/doc/book/en/development/devweb/views/startup.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/startup.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,11 +1,10 @@
Startup views
-------------
- (:mod:`cubicweb.web.views.startup`)
+(:mod:`cubicweb.web.views.startup`)
-Usual selector: no_rset or yes.
-
-Views that don't apply to a result set
+The usual selectors are no_rset or yes. These views don't apply to a
+result set.
*index*
This view defines the home page of your application. It does not require
--- a/doc/book/en/development/devweb/views/table.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/table.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,5 +1,7 @@
-Table views (:mod:`cubicweb.web.views.table`)
-----------------------------------------------
+Table view
+----------
+
+(:mod:`cubicweb.web.views.tableview`)
*table*
Creates a HTML table (`<table>`) and call the view `cell` for each cell of
@@ -8,3 +10,10 @@
*cell*
By default redirects to the `final` view if this is a final entity or
`outofcontext` view otherwise
+
+
+API
+```
+
+.. autoclass:: cubicweb.web.views.tableview.TableView
+ :members:
--- a/doc/book/en/development/devweb/views/urlpublish.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/urlpublish.rst Mon Apr 19 13:52:55 2010 +0200
@@ -25,3 +25,49 @@
:members:
+``SimpleReqRewriter`` is enough for a certain number of simple cases. If it is not sufficient, ``SchemaBasedRewriter`` allows to do more elaborate things.
+
+Here is an example of ``SimpleReqRewriter`` usage with plain string:
+
+.. sourcecode:: python
+
+ from cubicweb.web.views.urlrewrite import SimpleReqRewriter
+ class TrackerSimpleReqRewriter(SimpleReqRewriter):
+ rules = [
+ ('/versions', dict(vid='versionsinfo')),
+ ]
+
+When the url is `<base_url>/versions`, the view with the __regid__ `versionsinfo` is displayed.
+
+Here is an example of ``SimpleReqRewriter`` usage with regular expressions:
+
+.. sourcecode:: python
+
+ from cubicweb.web.views.urlrewrite import (
+ SimpleReqRewriter, rgx)
+
+ class BlogReqRewriter(SimpleReqRewriter):
+ rules = [
+ (rgx('/blogentry/([a-z_]+)\.rss'),
+ dict(rql=('Any X ORDERBY CD DESC LIMIT 20 WHERE X is BlogEntry,'
+ 'X creation_date CD, X created_by U, '
+ 'U login "%(user)s"'
+ % {'user': r'\1'}, vid='rss'))),
+ ]
+
+When a url matches the regular expression, the view with the __regid__
+`rss` which match the result set is displayed.
+
+Here is an example of ``SchemaBasedRewriter`` usage:
+
+.. sourcecode:: python
+
+ from cubicweb.web.views.urlrewrite import (
+ SchemaBasedRewriter, rgx, build_rset)
+
+ class TrackerURLRewriter(SchemaBasedRewriter):
+ rules = [
+ (rgx('/project/([^/]+)/([^/]+)/tests'),
+ build_rset(rql='Version X WHERE X version_of P, P name %(project)s, X num %(num)s',
+ rgxgroups=[('project', 1), ('num', 2)], vid='versiontests')),
+ ]
--- a/doc/book/en/development/devweb/views/views.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/views.rst Mon Apr 19 13:52:55 2010 +0200
@@ -15,14 +15,29 @@
.. _views_base_class:
+Discovering possible views
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is possible to configure the web user interface to have a left box
+showing all the views than can be applied to the current result set.
+
+To enable this, click on your login at the top right corner. Chose
+"user preferences", then "boxes", then "possible views box" and check
+"visible = yes" before validating your changes.
+
+The views listed there we either not selected because of a lower
+score, or they were deliberately excluded by the main template logic.
+
+
Basic class for views
~~~~~~~~~~~~~~~~~~~~~
Class `View` (`cubicweb.view`)
```````````````````````````````
-This class is an abstraction of a view class, used as a base class for every
-renderable object such as views, templates, graphic components, etc.
+This class is an abstraction of a view class, used as a base class for
+every renderable object such as views, templates and other user
+interface components.
A `View` is instantiated to render a result set or part of a result
set. `View` subclasses may be parametrized using the following class
@@ -109,8 +124,6 @@
__select__ = one_line_rset() & match_search_state('linksearch') & implements('Any')
-
-
XML views, binaries views...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- a/doc/book/en/development/devweb/views/wdoc.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/wdoc.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,7 +1,9 @@
.. -*- coding: utf-8 -*-
-Online documentation system (:mod:`cubicweb.web.views.wdoc`)
--------------------------------------------------------------
+Online documentation system
+---------------------------
+
+(:mod:`cubicweb.web.views.wdoc`)
XXX describe the on-line documentation system
--- a/doc/book/en/development/devweb/views/xmlrss.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/devweb/views/xmlrss.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,7 +1,9 @@
.. _XmlAndRss:
-XML and RSS views (:mod:`cubicweb.web.views.xmlrss`)
-----------------------------------------------------
+XML and RSS views
+-----------------
+
+(:mod:`cubicweb.web.views.xmlrss`)
Overview
+++++++++
@@ -14,7 +16,6 @@
Create a RSS/XML view for each entity based on the results of the dublin core
methods of the entity (`dc_*`)
-
RSS Channel Example
++++++++++++++++++++
@@ -57,6 +58,3 @@
of blog entries, thus providing a RSS channel
* show that a different selection (by category) means a different channel
-
-
-
--- a/doc/book/en/development/vreg.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/development/vreg.rst Mon Apr 19 13:52:55 2010 +0200
@@ -1,16 +1,16 @@
The VRegistry, selectors and application objects
================================================
-This chapter talk about core concepts of the |cubicweb| framework, that make it
-different from other framework (and probably not easy to grasp at a first
-glance). You won't be able to do advanced development with |cubicweb| without
-a good understanding of what's explain below.
+This chapter talks about core concepts of the |cubicweb| framework,
+that make it different from other frameworks (and maybe not easy to
+grasp at a first glance). To be able to do advanced development with
+|cubicweb| you need a good understanding of what is explained below.
-This chapter goes deep into details. You don't have to remember them all but keep
-it in mind so you can go back there later...
+This chapter goes deep into details. You don't have to remember them
+all but keep it in mind so you can go back there later.
-.. toctree::
- :maxdepth: 1
+An overview of AppObjects, the VRegistry and Selectors is given in the
+:ref:`VRegistryIntro` chapter.
.. autodocstring:: cubicweb.cwvreg
.. autodocstring:: cubicweb.selectors
@@ -105,6 +105,3 @@
You'll also find some other (very) specific selectors hidden in other modules
than :mod:`cubicweb.selectors`.
-
-
-.. |cubicweb| replace:: *CubicWeb*
Binary file doc/book/en/images/breadcrumbs_header.png has changed
--- a/doc/book/en/intro/concepts.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/intro/concepts.rst Mon Apr 19 13:52:55 2010 +0200
@@ -181,8 +181,8 @@
object's `__registry__` : object's `__regid__` : [list of app objects]
-E.g. The `vregistry` contains several registries which hold a list of
-appobjects associated to an identifier.
+E.g. the `vregistry` contains several (sub-)registries which hold a
+list of appobjects associated to an identifier.
The base class of appobjects is :class:`cubicweb.appobject.AppObject`.
@@ -214,7 +214,6 @@
- `entities`
- `views`
- `sobjects`
-- `hooks`
Once initialized, there are three common ways to retrieve some application object
@@ -238,7 +237,8 @@
The RQL query language
----------------------
-**No need for a complicated ORM when you have a powerful query language**
+**No need for a complicated ORM when you have a powerful data
+ manipulation language**
All the persistent data in a |cubicweb| instance is retrieved and modified by
using the Relation Query Language.
@@ -247,7 +247,7 @@
emphasize browsing relations.
-db-api
+DB-API
~~~~~~
The repository exposes a `db-api`_ like api but using the RQL instead of SQL.
--- a/doc/book/en/intro/history.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/intro/history.rst Mon Apr 19 13:52:55 2010 +0200
@@ -7,8 +7,11 @@
developing in 2001 as an offspring of its Narval_ research project. *CubicWeb*
is written in Python and includes a data server and a web engine.
-Its data server publishes data federated from different sources like SQL
-databases, LDAP directories or even from other CubicWeb data servers.
+Its data server publishes data federated from different sources like
+SQL databases, LDAP directories, `VCS`_ repositories or even from other
+CubicWeb data servers.
+
+.. _`VCS`: http://en.wikipedia.org/wiki/Revision_control
Its web engine was designed to let the final user control what content to select
and how to display it. It allows one to browse the federated data sources and
--- a/doc/book/en/tutorials/base/create-cube.rst Mon Apr 19 13:51:16 2010 +0200
+++ b/doc/book/en/tutorials/base/create-cube.rst Mon Apr 19 13:52:55 2010 +0200
@@ -69,10 +69,6 @@
cubicweb-ctl newcube --directory=~/src/cubes blog
-
-
-
-
.. _DefineDataModel:
Define your data model
@@ -302,7 +298,7 @@
Excepted side boxes, we can see all of them already in action in the
blog entry view. This is all described in more details in
-:ref:`primary`.
+:ref:`primary_view`.
We can for example add in front of the publication date a prefix
specifying that the date we see is the publication date.
--- a/entity.py Mon Apr 19 13:51:16 2010 +0200
+++ b/entity.py Mon Apr 19 13:52:55 2010 +0200
@@ -269,6 +269,14 @@
return '<Entity %s %s %s at %s>' % (
self.e_schema, self.eid, self.keys(), id(self))
+ def __json_encode__(self):
+ """custom json dumps hook to dump the entity's eid
+ which is not part of dict structure itself
+ """
+ dumpable = dict(self)
+ dumpable['eid'] = self.eid
+ return dumpable
+
def __nonzero__(self):
return True
--- a/etwist/server.py Mon Apr 19 13:51:16 2010 +0200
+++ b/etwist/server.py Mon Apr 19 13:52:55 2010 +0200
@@ -140,10 +140,8 @@
CW_EVENT_MANAGER.bind('after-registry-reload', self.set_url_rewriter)
def start_service(self):
- config = self.config
- interval = min(config['cleanup-session-time'] or 120,
- config['cleanup-anonymous-session-time'] or 720) / 2.
- start_task(interval, self.appli.session_handler.clean_sessions)
+ start_task(self.appli.session_handler.clean_sessions_interval,
+ self.appli.session_handler.clean_sessions)
def set_url_rewriter(self):
self.url_rewriter = self.appli.vreg['components'].select_or_none('urlrewriter')
--- a/etwist/twconfig.py Mon Apr 19 13:51:16 2010 +0200
+++ b/etwist/twconfig.py Mon Apr 19 13:52:55 2010 +0200
@@ -58,8 +58,8 @@
'group': 'main', 'level': 1,
}),
('session-time',
- {'type' : 'int',
- 'default': 30*60,
+ {'type' : 'time',
+ 'default': '30min',
'help': 'session expiration time, default to 30 minutes',
'group': 'main', 'level': 1,
}),
--- a/interfaces.py Mon Apr 19 13:51:16 2010 +0200
+++ b/interfaces.py Mon Apr 19 13:52:55 2010 +0200
@@ -1,11 +1,16 @@
-"""Specific views for entities implementing IDownloadable
+# organization: Logilab
+# copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
+# contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+# license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
+"""
+Standard interfaces.
-:organization: Logilab
-:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
+.. note::
+
+ The `implements` selector matches not only entity classes but also
+ their interfaces. Writing __select__ = implements('IGeocodable') is
+ a perfectly fine thing to do.
"""
-
__docformat__ = "restructuredtext en"
from logilab.common.interface import Interface
@@ -159,6 +164,7 @@
class IBreadCrumbs(Interface):
"""interface for entities which can be "located" on some path"""
+ # XXX fix recurs !
def breadcrumbs(self, view, recurs=False):
"""return a list containing some:
--- a/misc/migration/3.7.4_Any.py Mon Apr 19 13:51:16 2010 +0200
+++ b/misc/migration/3.7.4_Any.py Mon Apr 19 13:52:55 2010 +0200
@@ -1,5 +1,1 @@
sync_schema_props_perms('TrInfo', syncprops=False)
-
-config['http-session-time'] /= 60
-config['cleanup-session-time'] /= 60
-config['cleanup-anonymous-session-time'] /= 60
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.7.5_Any.py Mon Apr 19 13:52:55 2010 +0200
@@ -0,0 +1,4 @@
+if versions_map['cubicweb'][0] == (3, 7, 4):
+ config['http-session-time'] *= 60
+ config['cleanup-session-time'] *= 60
+ config['cleanup-anonymous-session-time'] *= 60
--- a/mixins.py Mon Apr 19 13:51:16 2010 +0200
+++ b/mixins.py Mon Apr 19 13:52:55 2010 +0200
@@ -1,11 +1,8 @@
-"""mixins of entity/views organized somewhat in a graph or tree structure
-
-
-:organization: Logilab
-:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
-"""
+# organization: Logilab
+# copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
+# contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+# license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
+"""mixins of entity/views organized somewhat in a graph or tree structure"""
__docformat__ = "restructuredtext en"
from itertools import chain
@@ -17,7 +14,7 @@
class TreeMixIn(object):
- """base tree-mixin providing the tree interface
+ """base tree-mixin implementing the tree interface
This mixin has to be inherited explicitly and configured using the
tree_attribute, parent_target and children_target class attribute to
@@ -275,8 +272,7 @@
class ProgressMixIn(object):
- """provide default implementations for IProgress interface methods"""
- # This is an adapter isn't it ?
+ """provide a default implementations for IProgress interface methods"""
@property
def cost(self):
--- a/rset.py Mon Apr 19 13:51:16 2010 +0200
+++ b/rset.py Mon Apr 19 13:52:55 2010 +0200
@@ -1,4 +1,4 @@
-"""The `ResultSet` class which is returned as result of a rql query
+"""The `ResultSet` class which is returned as result of an rql query
:organization: Logilab
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
@@ -15,21 +15,22 @@
class ResultSet(object):
- """a result set wrap a RQL query result. This object implements a partial
- list protocol to allow direct use as a list of result rows.
+ """A result set wraps a RQL query result. This object implements
+ partially the list protocol to allow direct use as a list of
+ result rows.
:type rowcount: int
- :ivar rowcount: number of rows in the result
+ :param rowcount: number of rows in the result
:type rows: list
- :ivar rows: list of rows of result
+ :param rows: list of rows of result
:type description: list
- :ivar description:
+ :param description:
result's description, using the same structure as the result itself
:type rql: str or unicode
- :ivar rql: the original RQL query string
+ :param rql: the original RQL query string
"""
def __init__(self, results, rql, args=None, description=(), rqlst=None):
self.rows = results
@@ -202,7 +203,8 @@
return rset
def split_rset(self, keyfunc=None, col=0, return_dict=False):
- """Splits the result set in multiple result set according to a given key
+ """splits the result set in multiple result sets according to
+ a given key
:type keyfunc: callable(entity or FinalType)
:param keyfunc:
@@ -250,7 +252,7 @@
return result
def limited_rql(self):
- """return a printable rql for the result set associated to the object,
+ """returns a printable rql for the result set associated to the object,
with limit/offset correctly set according to maximum page size and
currently displayed page when necessary
"""
@@ -375,12 +377,14 @@
@cached
def get_entity(self, row, col):
- """special method for query retreiving a single entity, returns a
+ """convenience method for query retrieving a single entity, returns a
partially initialized Entity instance.
- WARNING: due to the cache wrapping this function, you should NEVER
- give row as a named parameter (i.e. rset.get_entity(req, 0)
- is OK but rset.get_entity(row=0, req=req) isn't
+ .. warning::
+
+ Due to the cache wrapping this function, you should NEVER
+ give row as a named parameter (i.e. rset.get_entity(req, 0)
+ is OK but rset.get_entity(row=0, req=req) isn't)
:type row,col: int, int
:param row,col:
--- a/rtags.py Mon Apr 19 13:51:16 2010 +0200
+++ b/rtags.py Mon Apr 19 13:52:55 2010 +0200
@@ -4,7 +4,10 @@
#:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
-A RelationTag object is an object which allows to link a configuration information to a relation definition. For instance, the standard primary view uses a RelationTag object (uicfg.primaryview_section) to get the section to display relations.
+A RelationTag object is an object which allows to link a configuration
+information to a relation definition. For instance, the standard
+primary view uses a RelationTag object (uicfg.primaryview_section) to
+get the section to display relations.
.. sourcecode:: python
--- a/selectors.py Mon Apr 19 13:51:16 2010 +0200
+++ b/selectors.py Mon Apr 19 13:52:55 2010 +0200
@@ -12,37 +12,33 @@
You can combine selectors using the `&`, `|` and `~` operators.
-When two selectors are combined using the `&` operator (formerly `chainall`), it
-means that both should return a positive score. On success, the sum of scores is returned.
+When two selectors are combined using the `&` operator, it means that
+both should return a positive score. On success, the sum of scores is
+returned.
-When two selectors are combined using the `|` operator (former `chainfirst`), it
-means that one of them should return a positive score. On success, the first
+When two selectors are combined using the `|` operator, it means that
+one of them should return a positive score. On success, the first
positive score is returned.
You can also "negate" a selector by precedeing it by the `~` unary operator.
-Of course you can use parens to balance expressions.
-
-.. Note:
- When one chains selectors, the final score is the sum of the score of each
- individual selector (unless one of them returns 0, in which case the object is
- non selectable)
-
+Of course you can use parenthesis to balance expressions.
Example
~~~~~~~
-The goal: when on a Blog, one wants the RSS link to refer to blog entries, not to
+The goal: when on a blog, one wants the RSS link to refer to blog entries, not to
the blog entity itself.
-To do that, one defines a method on entity classes that returns the RSS stream
-url for a given entity. The default implementation on
-:class:`~cubicweb.entities.AnyEntity` (the generic entity class used as base for
-all others) and a specific implementation on Blog will do what we want.
+To do that, one defines a method on entity classes that returns the
+RSS stream url for a given entity. The default implementation on
+:class:`~cubicweb.entities.AnyEntity` (the generic entity class used
+as base for all others) and a specific implementation on `Blog` will
+do what we want.
-But when we have a result set containing several Blog entities (or different
-entities), we don't know on which entity to call the aforementioned method. In
-this case, we keep the generic behaviour.
+But when we have a result set containing several `Blog` entities (or
+different entities), we don't know on which entity to call the
+aforementioned method. In this case, we keep the generic behaviour.
Hence we have two cases here, one for a single-entity rsets, the other for
multi-entities rsets.
@@ -52,7 +48,7 @@
.. sourcecode:: python
class RSSIconBox(ExtResourcesBoxTemplate):
- '''just display the RSS icon on uniform result set'''
+ ''' just display the RSS icon on uniform result set '''
__select__ = ExtResourcesBoxTemplate.__select__ & non_final_entity()
It takes into account:
@@ -116,8 +112,9 @@
The proper way to implement this with |cubicweb| is two have two different
classes sharing the same identifier but with different selectors so you'll get
-the correct one according to the context:
+the correct one according to the context.
+.. sourcecode:: python
class UserLink(component.Component):
'''display a link to the connected user object with a loggout link'''
@@ -137,8 +134,9 @@
# display login link
...
-The big advantage, aside readibily once you're familiar with the system, is that
-your cube becomes much more easily customizable by improving componentization.
+The big advantage, aside readability once you're familiar with the
+system, is that your cube becomes much more easily customizable by
+improving componentization.
.. _CustomSelectors:
@@ -148,7 +146,7 @@
.. autodocstring:: cubicweb.appobject::objectify_selector
-In other case, you can take a look at the following abstract base classes:
+In other cases, you can take a look at the following abstract base classes:
.. autoclass:: cubicweb.selectors.ExpectedValueSelector
.. autoclass:: cubicweb.selectors.EClassSelector
@@ -160,7 +158,7 @@
.. autofunction:: cubicweb.selectors.lltrace
-.. Note::
+.. note::
Selectors __call__ should *always* return a positive integer, and shall never
return `None`.
@@ -254,11 +252,14 @@
.. sourcecode:: python
- >>> with traced_selection( ('oid1', 'oid2') ):
+ >>> with traced_selection( ('regid1', 'regid2') ):
... # some code in which you want to debug selectors
- ... # for objects with id 'oid1' and 'oid2'
+ ... # for objects with __regid__ 'regid1' and 'regid2'
+ A potentially usefull point to set up such a tracing function is
+ the `cubicweb.vregistry.Registry.select` method body.
"""
+
def __init__(self, traced='all'):
self.traced = traced
--- a/server/serverconfig.py Mon Apr 19 13:51:16 2010 +0200
+++ b/server/serverconfig.py Mon Apr 19 13:52:55 2010 +0200
@@ -109,8 +109,8 @@
'group': 'main', 'level': (CubicWebConfiguration.mode == 'installed') and 0 or 1,
}),
('session-time',
- {'type' : 'int',
- 'default': 30*60,
+ {'type' : 'time',
+ 'default': '30min',
'help': 'session expiration time, default to 30 minutes',
'group': 'main', 'level': 1,
}),
--- a/server/sources/ldapuser.py Mon Apr 19 13:51:16 2010 +0200
+++ b/server/sources/ldapuser.py Mon Apr 19 13:52:55 2010 +0200
@@ -136,15 +136,15 @@
}),
('synchronization-interval',
- {'type' : 'int',
- 'default': 24*60*60,
+ {'type' : 'time',
+ 'default': '1d',
'help': 'interval between synchronization with the ldap \
directory (default to once a day).',
'group': 'ldap-source', 'level': 2,
}),
('cache-life-time',
- {'type' : 'int',
- 'default': 2*60,
+ {'type' : 'time',
+ 'default': '2h',
'help': 'life time of query cache in minutes (default to two hours).',
'group': 'ldap-source', 'level': 2,
}),
--- a/toolsutils.py Mon Apr 19 13:51:16 2010 +0200
+++ b/toolsutils.py Mon Apr 19 13:52:55 2010 +0200
@@ -82,7 +82,7 @@
if askconfirm:
print
print diffs
- action = ASK.ask('Replace ?', ('N', 'y', 'q'), 'N')
+ action = ASK.ask('Replace ?', ('Y', 'n', 'q'), 'Y').lower()
else:
action = 'y'
if action == 'y':
--- a/utils.py Mon Apr 19 13:51:16 2010 +0200
+++ b/utils.py Mon Apr 19 13:52:55 2010 +0200
@@ -318,6 +318,21 @@
class CubicWebJsonEncoder(JSONEncoder):
"""define a simplejson encoder to be able to encode yams std types"""
+
+ # _iterencode is the only entry point I've found to use a custom encode
+ # hook early enough: .default() is called if nothing else matched before,
+ # .iterencode() is called once on the main structure to encode and then
+ # never gets called again.
+ # For the record, our main use case is in FormValidateController with:
+ # dumps((status, args, entity), cls=CubicWebJsonEncoder)
+ # where we want all the entity attributes, including eid, to be part
+ # of the json object dumped.
+ # This would have once more been easier if Entity didn't extend dict.
+ def _iterencode(self, obj, markers=None):
+ if hasattr(obj, '__json_encode__'):
+ obj = obj.__json_encode__()
+ return JSONEncoder._iterencode(self, obj, markers)
+
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y/%m/%d %H:%M:%S')
--- a/web/application.py Mon Apr 19 13:51:16 2010 +0200
+++ b/web/application.py Mon Apr 19 13:52:55 2010 +0200
@@ -38,14 +38,22 @@
self.session_time = vreg.config['http-session-time'] or None
if self.session_time is not None:
assert self.session_time > 0
- self.session_time *= 60 # convert minutes to seconds
self.cleanup_session_time = self.session_time
else:
- self.cleanup_session_time = (vreg.config['cleanup-session-time'] or 1440) * 60
+ self.cleanup_session_time = vreg.config['cleanup-session-time'] or 1440 * 60
assert self.cleanup_session_time > 0
- self.cleanup_anon_session_time = (vreg.config['cleanup-anonymous-session-time'] or 5) * 60
+ self.cleanup_anon_session_time = vreg.config['cleanup-anonymous-session-time'] or 5 * 60
assert self.cleanup_anon_session_time > 0
self.authmanager = vreg['components'].select('authmanager', vreg=vreg)
+ if vreg.config.anonymous_user() is not None:
+ self.clean_sessions_interval = min(
+ 5 * 60,
+ self.cleanup_session_time / 2.,
+ self.cleanup_anon_session_time / 2.)
+ else:
+ self.clean_sessions_interval = min(
+ 5 * 60,
+ self.cleanup_session_time / 2.)
def clean_sessions(self):
"""cleanup sessions which has not been unused since a given amount of
@@ -156,6 +164,10 @@
global SESSION_MANAGER
SESSION_MANAGER = self.session_manager
+ @property
+ def clean_sessions_interval(self):
+ return self.session_manager.clean_sessions_interval
+
def clean_sessions(self):
"""cleanup sessions which has not been unused since a given amount of
time
--- a/web/uicfg.py Mon Apr 19 13:51:16 2010 +0200
+++ b/web/uicfg.py Mon Apr 19 13:52:55 2010 +0200
@@ -31,77 +31,6 @@
uicfg.actionbox_appearsin_addmenu.tag_object_of(('*', 'entry_of', 'Blog'), True)
-
-Automatic form configuration
-````````````````````````````
-
-Attributes/relations display location
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``uicfg.autoform_section`` specifies where to display a relation in
-creation/edition entity form for a given form type. ``tag_attribute``,
-``tag_subject_of`` and ``tag_object_of`` methods for this relation tag expect
-two arguments additionally to the relation key: a ``formtype`` and a
-``section``.
-
-formtype may be one of:
-
-* ``main``, the main entity form (via the modify action)
-* ``inlined``, the form for an entity inlined into another form
-* ``muledit``, the table form to edit multiple entities
-
-section may be one of:
-
-* ``hidden``, don't display
-
-* ``attributes``, display in the attributes section
-
-* ``relations``, display in the relations section, using the generic relation
- selector combobox (available in main form only, and not for attribute
- relation)
-
-* ``inlined``, display target entity of the relation in an inlined form
- (available in main form only, and not for attribute relation)
-
-* ``metadata``, display in a special metadata form (NOT YET IMPLEMENTED, subject
- to changes)
-
-By default, mandatory relations are displayed in the ``attributes`` section,
-others in ``relations`` section.
-
-Change default fields
-^^^^^^^^^^^^^^^^^^^^^
-
-Use ``autoform_field`` to replace the default field type of an attribute.
-
-.. Warning:
- ``autoform_field_kwargs`` should usually be used instead of
- ``autoform_field``. Do not use both methods for the same relation!
-
-
-Customize field options
-^^^^^^^^^^^^^^^^^^^^^^^
-
-In order to customize field options (see :class:`cubicweb.web.formfields.Field`
-for a detailed list of options), use ``autoform_field_kwargs``. This rtag takes
-a relation triplet and a dictionary as arguments.
-
-.. sourcecode:: python
-
- # Change the content of the combobox
- # here ``ticket_done_in_choices`` is a function which returns a list of
- # elements to populate the combobox
- uicfg.autoform_field_kwargs.tag_subject_of(('Ticket', 'done_in', '*'), {'sort': False,
- 'choices': ticket_done_in_choices})
-
-
-
-Overriding permissions
-^^^^^^^^^^^^^^^^^^^^^^
-
-``autoform_permissions_overrides`` provides a way to by-pass security checking
-for dark-corner case where it can't be verified properly. XXX documents.
-
"""
__docformat__ = "restructuredtext en"
--- a/web/views/tableview.py Mon Apr 19 13:51:16 2010 +0200
+++ b/web/views/tableview.py Mon Apr 19 13:52:55 2010 +0200
@@ -23,6 +23,11 @@
from cubicweb.web.facet import prepare_facets_rqlst, filter_hiddens
class TableView(AnyRsetView):
+ """The table view accepts any non-empty rset. It uses
+ introspection on the result set to compute column names and the
+ proper way to display the cells.
+ It is however highly configurable and accepts a wealth of options.
+ """
__regid__ = 'table'
title = _('table')
finalview = 'final'
@@ -50,29 +55,30 @@
def _generate_form(self, divid, baserql, fwidgets, hidden=True, vidargs={}):
"""display a form to filter table's content. This should only
- occurs when a context eid is given
+ occur when a context eid is given
"""
+ w = self.w
self._cw.add_css('cubicweb.facets.css')
self._cw.add_js( ('cubicweb.ajax.js', 'cubicweb.facets.js'))
# drop False / None values from vidargs
vidargs = dict((k, v) for k, v in vidargs.iteritems() if v)
- self.w(u'<form method="post" cubicweb:facetargs="%s" action="">' %
- xml_escape(dumps([divid, 'table', False, vidargs])))
- self.w(u'<fieldset id="%sForm" class="%s">' % (divid, hidden and 'hidden' or ''))
- self.w(u'<input type="hidden" name="divid" value="%s" />' % divid)
- self.w(u'<input type="hidden" name="fromformfilter" value="1" />')
- filter_hiddens(self.w, facets=','.join(wdg.facet.__regid__ for wdg in fwidgets),
+ w(u'<form method="post" cubicweb:facetargs="%s" action="">' %
+ xml_escape(dumps([divid, 'table', False, vidargs])))
+ w(u'<fieldset id="%sForm" class="%s">' % (divid, hidden and 'hidden' or ''))
+ w(u'<input type="hidden" name="divid" value="%s" />' % divid)
+ w(u'<input type="hidden" name="fromformfilter" value="1" />')
+ filter_hiddens(w, facets=','.join(wdg.facet.__regid__ for wdg in fwidgets),
baserql=baserql)
- self.w(u'<table class="filter">\n')
- self.w(u'<tr>\n')
+ w(u'<table class="filter">\n')
+ w(u'<tr>\n')
for wdg in fwidgets:
- self.w(u'<td>')
- wdg.render(w=self.w)
- self.w(u'</td>\n')
- self.w(u'</tr>\n')
- self.w(u'</table>\n')
- self.w(u'</fieldset>\n')
- self.w(u'</form>\n')
+ w(u'<td>')
+ wdg.render(w=w)
+ w(u'</td>\n')
+ w(u'</tr>\n')
+ w(u'</table>\n')
+ w(u'</fieldset>\n')
+ w(u'</form>\n')
def main_var_index(self):
"""returns the index of the first non-attribute variable among the RQL
@@ -100,7 +106,7 @@
def call(self, title=None, subvid=None, displayfilter=None, headers=None,
displaycols=None, displayactions=None, actions=(), divid=None,
cellvids=None, cellattrs=None, mainindex=None):
- """Dumps a table displaying a composite query
+ """Produces a table displaying a composite query
:param title: title added before table
:param subvid: cell view
--- a/web/views/urlrewrite.py Mon Apr 19 13:51:16 2010 +0200
+++ b/web/views/urlrewrite.py Mon Apr 19 13:52:55 2010 +0200
@@ -188,8 +188,8 @@
class SchemaBasedRewriter(URLRewriter):
- """Here, the rules dict maps regexps or plain strings to
- callbacks that will be called with (input, uri, req, schema)
+ """Here, the rules dict maps regexps or plain strings to callbacks
+ that will be called with inputurl, uri, req, schema as parameters.
"""
__regid__ = 'schemabased'
rules = [
--- a/web/webconfig.py Mon Apr 19 13:51:16 2010 +0200
+++ b/web/webconfig.py Mon Apr 19 13:52:55 2010 +0200
@@ -113,17 +113,17 @@
'group': 'web', 'level': 2,
}),
('http-session-time',
- {'type' : 'int',
+ {'type' : 'time',
'default': 0,
- 'help': "duration in minutes of the cookie used to store session "
- "identifier. If 0, the cookie will expire when the user exist its "
- "browser. Should be 0 or greater than repository\'s session-time.",
- 'group': 'web', 'level': 2,
+ 'help': "duration of the cookie used to store session identifier. "
+ "If 0, the cookie will expire when the user exist its browser. "
+ "Should be 0 or greater than repository\'s session-time.",
+ 'group': 'web', 'inputlevel': 2,
}),
('cleanup-session-time',
- {'type' : 'int',
- 'default': 1440,
- 'help': 'duration of inactivity in minutes after which a connection '
+ {'type' : 'time',
+ 'default': '24h',
+ 'help': 'duration of inactivity after which a connection '
'will be closed, to limit memory consumption (avoid sessions that '
'never expire and cause memory leak when http-session-time is 0). '
'So even if http-session-time is 0 and the user don\'t close his '
@@ -132,8 +132,8 @@
'group': 'web', 'level': 2,
}),
('cleanup-anonymous-session-time',
- {'type' : 'int',
- 'default': 5,
+ {'type' : 'time',
+ 'default': '5min',
'help': 'Same as cleanup-session-time but specific to anonymous '
'sessions. You can have a much smaller timeout here since it will be '
'transparent to the user. Default to 5min.',
@@ -331,7 +331,6 @@
files = [w.strip() for w in val.split(',') if w.strip()]
self.ext_resources[resource] = files
-
# static files handling ###################################################
@property