doc/book/en/development/devcore/vreg.rst
changeset 4437 21f2e01fdd6a
parent 3581 669854258b90
child 4442 7bc0e4ed4109
equal deleted inserted replaced
4436:294e084f1263 4437:21f2e01fdd6a
     1 . -*- coding: utf-8 -*-
       
     2 
       
     3 The VRegistry
     1 The VRegistry
     4 --------------
     2 --------------
     5 
     3 
     6 The recording process on startup
     4 The recording process on startup
     7 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     8 
     6 
     9 Details of the recording process
     7 Details of the recording process
    10 ````````````````````````````````
     8 ````````````````````````````````
    11 
     9 
    12 XXX this part needs to be updated and checked
    10 .. index::
       
    11    vregistry: registration_callback
       
    12 
       
    13 On startup, |cubicweb| have to fill the vregistry with appobjects defined
       
    14 in its library and in cubes used by the instance. Appobjects from the library
       
    15 are loaded first, then appobjects provided by cubes are loaded in an ordered
       
    16 way (e.g. if your cube depends on an other, appobjects from the dependancy will
       
    17 be loaded first). Cube's modules or packages where appobject are looked at is explained
       
    18 in :ref:`cubelayout`.
       
    19 
       
    20 For each module:
    13 
    21 
    14 * by default all objects are registered automatically
    22 * by default all objects are registered automatically
    15 
    23 
    16 * if some objects have to replace other objects or be included only if a
    24 * if some objects have to replace other objects or be included only if a
    17   condition is true,
    25   condition is true, you'll have to define a `registration_callback(vreg)`
    18   - explicitly register the object by defining `registration_callback(vreg)`
    26   function in your module and explicitly register *all objects* in this
    19   - call registration methods on objects listed in the vreg registry
    27   module, using the vregistry api defined below.
    20 
    28 
    21 .. note::
    29 .. note::
    22     Once the function `registration_callback(vreg)` is implemented, all the objects
    30     Once the function `registration_callback(vreg)` is implemented, all the objects
    23     have to be explicitly registered as it disables the automatic object registering.
    31     have to be explicitly registered as it disables the automatic object registering.
    24 
    32 
    25 Examples:
       
    26 
    33 
       
    34 API d'enregistrement des objets
       
    35 ```````````````````````````````
       
    36 .. automethod:: cubicweb.cwvreg.CubicWebVRegistry.register_all
       
    37 .. automethod:: cubicweb.cwvreg.CubicWebVRegistry.register_and_replace
       
    38 .. automethod:: cubicweb.cwvreg.CubicWebVRegistry.register
       
    39 .. automethod:: cubicweb.cwvreg.CubicWebVRegistry.register_if_interface_found
       
    40 .. automethod:: cubicweb.cwvreg.CubicWebVRegistry.unregister
       
    41 
       
    42 
       
    43 Examples
       
    44 ````````
    27 .. sourcecode:: python
    45 .. sourcecode:: python
    28 
    46 
    29    # web/views/basecomponents.py
    47    # web/views/basecomponents.py
    30    def registration_callback(vreg):
    48    def registration_callback(vreg):
    31       # register everything in the module except SeeAlsoComponent
    49       # register everything in the module except SeeAlsoComponent
    35           vreg.register(SeeAlsoVComponent)
    53           vreg.register(SeeAlsoVComponent)
    36 
    54 
    37    # goa/appobjects/sessions.py
    55    # goa/appobjects/sessions.py
    38    def registration_callback(vreg):
    56    def registration_callback(vreg):
    39       vreg.register(SessionsCleaner)
    57       vreg.register(SessionsCleaner)
    40       vreg.register(GAEAuthenticationManager, clear=True)
    58       # replace AuthenticationManager by GAEAuthenticationManager 
    41       vreg.register(GAEPersistentSessionManager, clear=True)
    59       vreg.register_and_replace(GAEAuthenticationManager, AuthenticationManager)
    42 
    60       # replace PersistentSessionManager by GAEPersistentSessionManager
    43 
    61       vreg.register_and_replace(GAEPersistentSessionManager, PersistentSessionManager)
    44 API d'enregistrement des objets
       
    45 ```````````````````````````````
       
    46 
       
    47 .. sourcecode:: python
       
    48 
       
    49    register(obj, registryname=None, oid=None, clear=False)
       
    50 
       
    51    register_all(objects, modname, butclasses=())
       
    52 
       
    53    unregister(obj, registryname=None)
       
    54 
       
    55    register_and_replace(obj, replaced, registryname=None)
       
    56 
       
    57    register_if_interface_found(obj, ifaces, **kwargs)
       
    58 
    62 
    59 
    63 
    60 Runtime objects selection
    64 Runtime objects selection
    61 ~~~~~~~~~~~~~~~~~~~~~~~~~
    65 ~~~~~~~~~~~~~~~~~~~~~~~~~
    62 
    66 
    63 Defining selectors
    67 Using and combining existant selectors
    64 ``````````````````
    68 ``````````````````````````````````````
    65 
    69 
    66 The object's selector is defined by its `__select__` class attribute.
    70 The object's selector is defined by its `__select__` class attribute.
    67 
    71 
    68 When two selectors are combined using the `&` operator (formerly `chainall`), it
    72 When two selectors are combined using the `&` operator (formerly `chainall`), it
    69 means that both should return a positive score. On success, the sum of scores is returned.
    73 means that both should return a positive score. On success, the sum of scores is returned.
    73 positive score is returned.
    77 positive score is returned.
    74 
    78 
    75 Of course you can use paren to balance expressions.
    79 Of course you can use paren to balance expressions.
    76 
    80 
    77 
    81 
    78 For instance, if you are selecting the primary (eg `id = 'primary'`) view (eg
    82 For instance, if you are selecting the primary (eg `__regid__ = 'primary'`) view (eg
    79 `__registry__ = 'view'`) for a result set containing a `Card` entity, 2 objects
    83 `__registry__ = 'view'`) for a result set containing a `Card` entity, 2 objects
    80 will probably be selectable:
    84 will probably be selectable:
    81 
    85 
    82 * the default primary view (`__select__ = implements('Any')`), meaning
    86 * the default primary view (`__select__ = implements('Any')`), meaning
    83   that the object is selectable for any kind of entity type
    87   that the object is selectable for any kind of entity type
   146   stream url on AnyEntity
   150   stream url on AnyEntity
   147 
   151 
   148 * redefine this method on Blog.
   152 * redefine this method on Blog.
   149 
   153 
   150 When to use selectors?
   154 When to use selectors?
   151 ```````````````````````
   155 ``````````````````````
   152 
   156 
   153 Selectors are to be used whenever arises the need of dispatching on
   157 Selectors are to be used whenever arises the need of dispatching on the shape or
   154 the shape or content of a result set. That is, almost all the time.
   158 content of a result set or whatever else context (value in._cwuest form params,
       
   159 authenticated user groups, etc...). That is, almost all the time.
       
   160 
       
   161 XXX add and example of a single view w/ big "if" inside splitted into two views
       
   162 with appropriate selectors.
       
   163 
       
   164 
       
   165 Defining your own selectors
       
   166 ```````````````````````````
       
   167 XXX objectify_selector, EntitySelector, EClassSelector...
       
   168 
   155 
   169 
   156 Debugging
   170 Debugging
   157 `````````
   171 `````````
   158 
   172 
   159 Once in a while, one needs to understand why a view (or any AppObject)
   173 Once in a while, one needs to understand why a view (or any AppObject)
   163 
   177 
   164 Here is an example:
   178 Here is an example:
   165 
   179 
   166 .. sourcecode:: python
   180 .. sourcecode:: python
   167 
   181 
   168     def possible_objects(self, registry, *args, **kwargs):
   182      from cubicweb.selectors import traced_selection
   169         """return an iterator on possible objects in a registry for this result set
   183      with traced_selection():
   170 
   184          mycomp = self._cw.vreg['views'].select('wfhistory', self._cw, rset=rset)
   171         actions returned are classes, not instances
       
   172         """
       
   173         from cubicweb.selectors import traced_selection
       
   174         with traced_selection():
       
   175             for vobjects in self.registry(registry).values():
       
   176                 try:
       
   177                     yield self.select(vobjects, *args, **kwargs)
       
   178                 except NoSelectableObject:
       
   179                     continue
       
   180 
   185 
   181 Don't forget the 'from __future__ import with_statement' at the module
   186 Don't forget the 'from __future__ import with_statement' at the module
   182 top-level.
   187 top-level if you're using python 2.5.
   183 
   188 
   184 This will yield additional WARNINGs in the logs, like this::
   189 This will yield additional WARNINGs in the logs, like this::
   185 
   190 
   186     2009-01-09 16:43:52 - (cubicweb.selectors) WARNING: selector one_line_rset returned 0 for <class 'cubicweb.web.views.basecomponents.WFHistoryVComponent'>
   191     2009-01-09 16:43:52 - (cubicweb.selectors) WARNING: selector one_line_rset returned 0 for <class 'cubicweb.web.views.basecomponents.WFHistoryVComponent'>
       
   192 
       
   193 
       
   194 
       
   195 Take care not filtering-out messages whose log level is <= LOG_WARNING!