backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 15 Apr 2010 12:48:40 +0200
changeset 5274 16461f675734
parent 5272 f7d2df59231a (current diff)
parent 5273 c4caef6f09c9 (diff)
child 5297 cc747dcef851
backport stable
_exceptions.py
cwconfig.py
cwvreg.py
devtools/__init__.py
devtools/testlib.py
doc/book/en/development/devweb/views.rst
doc/book/en/development/webstdlib/autoform.rst
doc/book/en/development/webstdlib/basetemplates.rst
doc/book/en/development/webstdlib/baseviews.rst
doc/book/en/development/webstdlib/boxes.rst
doc/book/en/development/webstdlib/breadcrumbs.rst
doc/book/en/development/webstdlib/editcontroller.rst
doc/book/en/development/webstdlib/editforms.rst
doc/book/en/development/webstdlib/embedding.rst
doc/book/en/development/webstdlib/facets.rst
doc/book/en/development/webstdlib/idownloadable.rst
doc/book/en/development/webstdlib/index.rst
doc/book/en/development/webstdlib/primary.rst
doc/book/en/development/webstdlib/startup.rst
doc/book/en/development/webstdlib/table.rst
doc/book/en/development/webstdlib/urlpublish.rst
doc/book/en/development/webstdlib/wdoc.rst
doc/book/en/development/webstdlib/xmlrss.rst
doc/book/en/intro/book-map.rst
doc/book/en/intro/tutorial/blog-in-five-minutes.rst
doc/book/en/intro/tutorial/components.rst
doc/book/en/intro/tutorial/conclusion.rst
doc/book/en/intro/tutorial/create-cube.rst
doc/book/en/intro/tutorial/index.rst
doc/book/en/intro/tutorial/maintemplate.rst
etwist/server.py
--- a/_exceptions.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/_exceptions.py	Thu Apr 15 12:48:40 2010 +0200
@@ -122,8 +122,6 @@
 class UnknownProperty(RegistryException):
     """property found in database but unknown in registry"""
 
-class RegistryOutOfDate(RegistryException):
-    """raised when a source file modification is detected"""
 
 # query exception #############################################################
 
--- a/cwconfig.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/cwconfig.py	Thu Apr 15 12:48:40 2010 +0200
@@ -1,10 +1,8 @@
 # -*- coding: utf-8 -*-
-#: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
-
-# docstring included in doc/book/en/admin/setup.rst
+# organization: Logilab
+# copyright 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
+# contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+# Licensed under the GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
 .. _ResourceMode:
 
@@ -13,7 +11,7 @@
 
 A resource *mode* is a predifined set of settings for various resources
 directories, such as cubes, instances, etc. to ease development with the
-framework. There are two running modes with |cubicweb|:
+framework. There are two running modes with *CubicWeb*:
 
 * 'user', resources are searched / created in the user home directory:
 
@@ -80,7 +78,7 @@
 Python
 ``````
 
-If you installed |cubicweb| by cloning the Mercurial forest or from source
+If you installed *CubicWeb* by cloning the Mercurial forest or from source
 distribution, then you will need to update the environment variable PYTHONPATH by
 adding the path to the forest `cubicweb`:
 
@@ -89,7 +87,7 @@
 
     export PYTHONPATH=/full/path/to/cubicweb-forest
 
-If you installed |cubicweb| with packages, no configuration is required and your
+If you installed *CubicWeb* with packages, no configuration is required and your
 new cubes will be placed in `/usr/share/cubicweb/cubes` and your instances will
 be placed in `/etc/cubicweb.d`.
 
@@ -97,11 +95,11 @@
 CubicWeb
 ````````
 
-Here are all environment variables that may be used to configure |cubicweb|:
+Here are all environment variables that may be used to configure *CubicWeb*:
 
 .. envvar:: CW_MODE
 
-   Resource mode: user or system, as explained in :ref:ResourceMode.
+   Resource mode: user or system, as explained in :ref:`ResourceMode`.
 
 .. envvar:: CW_CUBES_PATH
 
--- a/cwvreg.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/cwvreg.py	Thu Apr 15 12:48:40 2010 +0200
@@ -185,7 +185,7 @@
 
 from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid,
                       ObjectNotFound, NoSelectableObject, RegistryNotFound,
-                      RegistryOutOfDate, CW_EVENT_MANAGER, onevent)
+                      CW_EVENT_MANAGER, onevent)
 from cubicweb.utils import dump_class
 from cubicweb.vregistry import VRegistry, Registry, class_regid
 from cubicweb.rtags import RTAGS
@@ -460,8 +460,8 @@
     def itervalues(self):
         return (value for key, value in self.items())
 
-    def reset(self, path=None, force_reload=None):
-        super(CubicWebVRegistry, self).reset(path, force_reload)
+    def reset(self):
+        super(CubicWebVRegistry, self).reset()
         self._needs_iface = {}
         # two special registries, propertydefs which care all the property
         # definitions, and propertyvals which contains values for those
@@ -471,23 +471,12 @@
             self['propertyvalues'] = self.eprop_values = {}
             for key, propdef in self.config.eproperty_definitions():
                 self.register_property(key, **propdef)
-        if path is not None and force_reload:
-            cleanup_sys_modules(path)
-            cubes = self.config.cubes()
-            # if the fs code use some cubes not yet registered into the instance
-            # we should cleanup sys.modules for those as well to avoid potential
-            # bad class reference pb after reloading
-            cfg = self.config
-            for cube in cfg.expand_cubes(cubes, with_recommends=True):
-                if not cube in cubes:
-                    cpath = cfg.build_vregistry_cube_path([cfg.cube_dir(cube)])
-                    cleanup_sys_modules(cpath)
 
     def set_schema(self, schema):
         """set instance'schema and load application objects"""
         self._set_schema(schema)
         # now we can load application's web objects
-        self._reload(self.config.vregistry_path(), force_reload=False)
+        self.reload(self.config.vregistry_path())
         # map lowered entity type names to their actual name
         self.case_insensitive_etypes = {}
         for eschema in self.schema.entities():
@@ -496,12 +485,26 @@
             clear_cache(eschema, 'ordered_relations')
             clear_cache(eschema, 'meta_attributes')
 
-    def _reload(self, path, force_reload):
+    def reload_if_needed(self):
+        path = self.config.vregistry_path()
+        if self.is_reload_needed(path):
+            self.reload(path)
+
+    def reload(self, path):
+        """modification detected, reset and reload the vreg"""
         CW_EVENT_MANAGER.emit('before-registry-reload')
-        # modification detected, reset and reload
-        self.reset(path, force_reload)
-        super(CubicWebVRegistry, self).register_objects(
-            path, force_reload, self.config.extrapath)
+        cleanup_sys_modules(path)
+        cubes = self.config.cubes()
+        # if the fs code use some cubes not yet registered into the instance we
+        # should cleanup sys.modules for those as well to avoid potential bad
+        # class reference pb after reloading
+        cfg = self.config
+        for cube in cfg.expand_cubes(cubes, with_recommends=True):
+            if not cube in cubes:
+                cpath = cfg.build_vregistry_cube_path([cfg.cube_dir(cube)])
+                cleanup_sys_modules(cpath)
+        self.reset()
+        self.register_objects(path, True)
         CW_EVENT_MANAGER.emit('after-registry-reload')
 
     def _set_schema(self, schema):
@@ -546,15 +549,10 @@
         if ifaces:
             self._needs_iface[obj] = ifaces
 
-    def register_objects(self, path, force_reload=None):
+    def register_objects(self, path, force_reload=False):
         """overriden to remove objects requiring a missing interface"""
-        if force_reload is None:
-            force_reload = self.config.debugmode
-        try:
-            super(CubicWebVRegistry, self).register_objects(
-                path, force_reload, self.config.extrapath)
-        except RegistryOutOfDate:
-            self._reload(path, force_reload)
+        super(CubicWebVRegistry, self).register_objects(
+            path, force_reload, self.config.extrapath)
 
     def initialization_completed(self):
         """cw specific code once vreg initialization is completed:
--- a/devtools/__init__.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/devtools/__init__.py	Thu Apr 15 12:48:40 2010 +0200
@@ -214,8 +214,10 @@
     driver = config.sources()['system']['db-driver']
     if driver == 'sqlite':
         reset_test_database_sqlite(config)
-    elif driver == 'sqlserver2005':
-        reset_test_database_sqlserver2005(config)
+    elif driver in ('sqlserver2005', 'postgres'):
+        # XXX do something with dump/restore ?
+        print 'resetting the database is not done for', driver
+        print 'you should handle it manually'
     else:
         raise ValueError('no reset function for driver %r' % driver)
 
@@ -236,9 +238,6 @@
         from cubicweb.server import init_repository
         init_repository(config, interactive=False, drop=True, vreg=vreg)
 
-def reset_test_database_sqlserver2005(config):
-    pass
-
 ### sqlite test database handling ##############################################
 
 def cleanup_sqlite(dbfile, removetemplate=False):
--- a/devtools/testlib.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/devtools/testlib.py	Thu Apr 15 12:48:40 2010 +0200
@@ -134,6 +134,7 @@
 
 class CubicWebTC(TestCase):
     """abstract class for test using an apptest environment
+
     attributes:
 
     * `vreg`, the vregistry
@@ -145,7 +146,6 @@
     * `repo`, the repository object
     * `admlogin`, login of the admin user
     * `admpassword`, password of the admin user
-
     """
     appid = 'data'
     configcls = devtools.ApptestConfiguration
--- a/doc/book/en/admin/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/admin/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -2,9 +2,9 @@
 
 .. _Part3:
 
--------------------------
-Part III - Administration
--------------------------
+--------------
+Administration
+--------------
 
 This part is for installation and administration of the *CubicWeb* framework and
 instances based on that framework.
--- a/doc/book/en/admin/setup.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/admin/setup.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -141,6 +141,15 @@
 
 Please be careful to select the right python (2.5) and postgres (8.4) versions.
 
+A windows compiled recent version of gettext::
+
+  http://ftp.logilab.org/pub/gettext/gettext-0.17-win32-setup.exe
+
+A pre-compiled version of rql for windows (take care of retrieving the
+most recent version available there)::
+
+  http://ftp.logilab.org/pub/rql/rql-0.23.0.win32-py2.5.exe
+
 Pyro enables remote access to cubicweb repository instances. Get it there::
 
   http://sourceforge.net/projects/pyro/files/
--- a/doc/book/en/annexes/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/annexes/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -2,9 +2,9 @@
 
 .. _Part4:
 
---------------------
-Part IV - Appendixes
---------------------
+----------
+Appendixes
+----------
 
 The following chapters are reference material.
 
--- a/doc/book/en/conf.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/conf.py	Thu Apr 15 12:48:40 2010 +0200
@@ -32,10 +32,10 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'logilab.common.sphinx_ext']#, 'sphinxcontrib.aafig']
+extensions = ['sphinx.ext.autodoc', 'logilab.common.sphinx_ext']
 autoclass_content = 'both'
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['.templates']
+#templates_path = []
 
 # The suffix of source filenames.
 source_suffix = '.rst'
@@ -97,8 +97,8 @@
 # The name for this set of Sphinx documents.  If None, it defaults to
 # "<project> v<release> documentation".
 html_title = '%s %s' % (project, release)
-html_theme = 'lglb_doc'
-html_theme_path = ['_theme']
+html_theme = 'standard_theme'
+html_theme_path = ['.']
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
 #html_short_title = None
@@ -189,4 +189,3 @@
 # If false, no module index is generated.
 #latex_use_modindex = True
 #aafig_format = dict(latex='pdf', html='svg', text=None)
-
--- a/doc/book/en/development/devcore/cwconfig.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/devcore/cwconfig.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -1,5 +1,5 @@
-:mod:`Configuration <cubicweb.cwconfig>`
-----------------------------------------
+Configuration
+-------------
 
-.. .. automodule:: cubicweb.cwconfig
-..   :members:
+.. automodule:: cubicweb.cwconfig
+      :members:
--- a/doc/book/en/development/devcore/dbapi.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/devcore/dbapi.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -8,6 +8,7 @@
 The most important method is the `execute` method of a cursor.
 
 .. sourcecode:: python
+
   execute(rqlstring, args=None, cachekey=None, build_descr=True)
 
 :rqlstring: the RQL query to execute (unicode)
--- a/doc/book/en/development/devcore/reqbase.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/devcore/reqbase.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -1,3 +1,5 @@
+Request and ResultSet methods
+-----------------------------
 
 Those are methods you'll find on both request objects and on repository session:
 
--- a/doc/book/en/development/devrepo/hooks.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/devrepo/hooks.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -320,6 +320,11 @@
 * when several hooks need to instantiate the same operation (e.g. an
   entity and a relation hook).
 
+.. note::
+
+  A more realistic example can be found in the advanced tutorial
+  chapter :ref:`adv_tuto_security_propagation`.
+
 Operation: a small API overview
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
--- a/doc/book/en/development/devweb/controllers.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/devweb/controllers.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -1,3 +1,5 @@
+.. _controllers:
+
 Controllers
 -----------
 
@@ -10,7 +12,7 @@
 The following controllers are provided out-of-the box in CubicWeb. We
 list them by category.
 
-Browsing:
+`Browsing`:
 
 * the View controller (web/views/basecontrollers.py) is associated
   with most browsing actions within a CubicWeb application: it always
@@ -27,9 +29,9 @@
 * the Login/Logout controllers (web/views/basecontrollers.py) make
   effective user login or logout requests
 
-Edition:
+`Edition`:
 
-* the Edit controller (web/views/editcontroller.py) handles CRUD
+* the Edit controller (see :ref:`edit_controller`) handles CRUD
   operations in response to a form being submitted; it works in close
   association with the Forms, to which it delegates some of the work
 
@@ -40,7 +42,7 @@
   Form validator controller, and the UI is decorated with failure
   information, either global or per-field , until it is valid)
 
-Other:
+`Other`:
 
 * the SendMail controller (web/views/basecontrollers.py) is reponsible
   for outgoing email notifications
@@ -76,4 +78,122 @@
   process.
 
 
+.. _edit_controller:
 
+The `edit controller`
++++++++++++++++++++++
+
+It can be found in (:mod:`cubicweb.web.views.editcontroller`).
+
+Editing control
+~~~~~~~~~~~~~~~~
+
+Re-requisites: the parameters related to entities to edit are
+specified as follows ::
+
+  <field name>:<entity eid>
+
+where entity eid could be a letter in case of an entity to create. We
+name those parameters as *qualified*.
+
+1. Retrieval of entities to edit by looking for the forms parameters
+   starting by `eid:` and also having a parameter `__type` associated
+   (also *qualified* by eid)
+
+2. For all the attributes and the relations of an entity to edit:
+
+   1. search for a parameter `edits-<relation name>` or `edito-<relation name>`
+      qualified in the case of a relation where the entity is object
+   2. if found, the value returned is considered as the initial value
+      for this relaiton and we then look for the new value(s)  in the parameter
+      <relation name> (qualified)
+   3. if the value returned is different from the initial value, an database update
+      request is done
+
+3. For each entity to edit:
+
+   1. if a qualified parameter `__linkto` is specified, its value has to be
+      a string (or a list of string) such as: ::
+
+        <relation type>:<eids>:<target>
+
+      where <target> is either `subject` or `object` and each eid could be
+      separated from the others by a `_`. Target specifies if the *edited entity*
+      is subject or object of the relation and each relation specified will
+      be inserted.
+
+    2. if a qualified parameter `__clone_eid` is specified for an entity, the
+       relations of the specified entity passed as value of this parameter are
+       copied on the edited entity.
+
+    3. if a qualified parameter `__delete` is specified, its value must be
+       a string or a list of string such as follows: ::
+
+          <ssubjects eids>:<relation type>:<objects eids>
+
+       where each eid subject or object can be seperated from the other
+       by `_`. Each relation specified will be deleted.
+
+    4. if a qualified parameter `__insert` is specified, its value should
+       follow the same pattern as `__delete`, but each relation specified is
+       inserted.
+
+4. If the parameters `__insert` and/or `__delete` are found not qualified,
+   they are interpreted as explained above (independantly from the number
+   of entities edited).
+
+5. If no entity is edited but the form contains the parameters `__linkto`
+   and `eid`, this one is interpreted by using the value specified for `eid`
+   to designate the entity on which to add the relations.
+
+
+.. note::
+
+   * If the parameter `__action_delete` is found, all the entities specified
+     as to be edited will be deleted.
+
+   * If the parameter `__action_cancel` is found, no action is completed.
+
+   * If the parameter `__action_apply` is found, the editing is
+     applied normally but the redirection is done on the form (see
+     :ref:`RedirectionControl`).
+
+   * The parameter `__method` is also supported as for the main template
+
+   * If no entity is found to be edited and if there is no parameter
+     `__action_delete`, `__action_cancel`, `__linkto`, `__delete` or
+     `__insert`, an error is raised.
+
+   * Using the parameter `__message` in the form will allow to use its value
+     as a message to provide the user once the editing is completed.
+
+
+.. _RedirectionControl:
+
+Redirection control
+~~~~~~~~~~~~~~~~~~~
+Once editing is completed, there is still an issue left: where should we go
+now? If nothing is specified, the controller will do his job but it does not
+mean we will be happy with the result. We can control that by using the
+following parameters:
+
+* `__redirectpath`: path of the URL (relative to the root URL of the site,
+  no form parameters
+
+* `__redirectparams`: forms parameters to add to the path
+
+* `__redirectrql`: redirection RQL request
+
+* `__redirectvid`: redirection view identifier
+
+* `__errorurl`: initial form URL, used for redirecting in case a validation
+  error is raised during editing. If this one is not specified, an error page
+  is displayed instead of going back to the form (which is, if necessary,
+  responsible for displaying the errors)
+
+* `__form_id`: initial view form identifier, used if `__action_apply` is
+  found
+
+In general we use either `__redirectpath` and `__redirectparams` or
+`__redirectrql` and `__redirectvid`.
+
--- a/doc/book/en/development/devweb/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/devweb/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -4,14 +4,14 @@
 In this chapter, we will describe the core api for web development in the *CubicWeb* framework.
 
 .. toctree::
-   :maxdepth: 1
+   :maxdepth: 2
 
    request
    publisher
    controllers
    property
    rtags
-   views
+   views/index
    form
    facets
    httpcaching
--- a/doc/book/en/development/devweb/rtags.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/devweb/rtags.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -1,14 +1,21 @@
 Configuring the user interface
 ------------------------------
 
+.. _relation_tags:
 
 Relation tags
 ~~~~~~~~~~~~~
 .. automodule:: cubicweb.rtags
 
-
+.. _uicfg_module:
 
 The ``uicfg`` module
 ~~~~~~~~~~~~~~~~~~~~
+
+.. note::
+
+ The part of uicfg that deals with primary views is in the
+ :ref:`primary_view_configuration` chapter.
+
 .. automodule:: cubicweb.web.uicfg
 
--- a/doc/book/en/development/devweb/views.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-
-.. _Views:
-
-Views
------
-
-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*.
-
-We'll start with a description of the interface providing you with a basic
-understanding of the available classes and methods, then detail the view
-selection principle which makes *CubicWeb* web interface very flexible.
-
-A `View` is an object applied to another object such as an entity.
-
-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.
-
-A `View` is instantiated to render a result set or part of a result set. `View`
-subclasses may be parametrized using the following class attributes:
-
-* `templatable` indicates if the view may be embedded in a main
-  template or if it has to be rendered standalone (i.e. XML views must
-  not be embedded in the main template for HTML pages)
-
-* if the view is not templatable, it should set the `content_type`
-  class attribute to the correct MIME type (text/xhtml by default)
-
-* the `category` attribute may be used in the interface to regroup
-  related objects together
-
-A view writes to its output stream thanks to its attribute `w` (an
-`UStreamIO`, except for binary views).
-
-At instantiation time, the standard `_cw` and `cw_rset` attributes are
-added and the `w` attribute will be set at rendering time.
-
-The basic interface for views is as follows (remember that the result set has a
-tabular structure with rows and columns, hence cells):
-
-* `render(**context)`, render the view by calling `call` or
-  `cell_call` depending on the given parameters
-
-* `call(**kwargs)`, call the view for a complete result set or null
-  (the default implementation calls `cell_call()` on each cell of the
-  result set)
-
-* `cell_call(row, col, **kwargs)`, call the view for a given cell of a
-  result set (`row` and `col` being integers used to access the cell)
-
-* `url()`, returns the URL enabling us to get the view with the current
-  result set
-
-* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of
-  identifier `__vid` on the given result set. It is possible to give a
-  fallback view identifier that will be used if the requested view is
-  not applicable to the result set.
-
-* `html_headers()`, returns a list of HTML headers to be set by the
-  main template
-
-* `page_title()`, returns the title to use in the HTML header `title`
-
-Other basic view classes
-````````````````````````
-Here are some of the subclasses of `View` defined in `cubicweb.common.view`
-that are more concrete as they relate to data rendering within the application:
-
-* `EntityView`, view applying to lines or cell containing an entity (e.g. an eid)
-* `StartupView`, start view that does not require a result set to apply to
-* `AnyRsetView`, view applicable to any result set
-
-Examples of views class
------------------------
-
-- Using `templatable`, `content_type` and HTTP cache configuration
-
-.. sourcecode:: python
-
-    class RSSView(XMLView):
-        __regid__ = 'rss'
-        title = _('rss')
-        templatable = False
-        content_type = 'text/xml'
-        http_cache_manager = MaxAgeHTTPCacheManager
-        cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
-
-
-- Using custom selector
-
-.. sourcecode:: python
-
-    class SearchForAssociationView(EntityView):
-        """view called by the edition view when the user asks
-        to search for something to link to the edited eid
-        """
-        __regid__ = 'search-associate'
-        title = _('search for association')
-        __select__ = one_line_rset() & match_search_state('linksearch') & implements('Any')
-
-
-
-Example of view customization and creation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-We'll show you now an example of a ``primary`` view and how to customize it.
-
-If you want to change the way a ``BlogEntry`` is displayed, just override
-the method ``cell_call()`` of the view ``primary`` in ``BlogDemo/views.py``:
-
-.. sourcecode:: python
-
-  from cubicweb.selectors import implements
-  from cubicweb.web.views.primary improt Primaryview
-
-  class BlogEntryPrimaryView(PrimaryView):
-    __select__ = PrimaryView.__select__ & implements('BlogEntry')
-
-      def render_entity_attributes(self, entity):
-          self.w(u'<p>published on %s</p>' %
-                 entity.publish_date.strftime('%Y-%m-%d'))
-          super(BlogEntryPrimaryView, self).render_entity_attributes(entity)
-
-The above source code defines a new primary view for
-``BlogEntry``. The `id` class attribute is not repeated there since it
-is inherited through the `primary.PrimaryView` class.
-
-The selector for this view chains the selector of the inherited class
-with its own specific criterion.
-
-The view method ``self.w()`` is used to output data. Here `lines
-08-09` output HTML for the publication date of the entry.
-
-.. image:: ../../images/lax-book.09-new-view-blogentry.en.png
-   :alt: blog entries now look much nicer
-
-Let us now improve the primary view of a blog
-
-.. sourcecode:: python
-
- from logilab.mtconverter import xml_escape
- from cubicweb.selectors import implements, one_line_rset
- from cubicweb.web.views.primary import Primaryview
-
- class BlogPrimaryView(PrimaryView):
-     __regid__ = 'primary'
-     __select__ = PrimaryView.__select__ & implements('Blog')
-     rql = 'Any BE ORDERBY D DESC WHERE BE entry_of B, BE publish_date D, B eid %(b)s'
-
-     def render_entity_relations(self, entity):
-         rset = self._cw.execute(self.rql, {'b' : entity.eid})
-         for entry in rset.entities():
-             self.w(u'<p>%s</p>' % entry.view('inblogcontext'))
-
- class BlogEntryInBlogView(EntityView):
-     __regid__ = 'inblogcontext'
-     __select__ = implements('BlogEntry')
-
-     def cell_call(self, row, col):
-         entity = self.cw_rset.get_entity(row, col)
-         self.w(u'<a href="%s" title="%s">%s</a>' %
-                entity.absolute_url(),
-                xml_escape(entity.content[:50]),
-                xml_escape(entity.description))
-
-This happens in two places. First we override the
-render_entity_relations method of a Blog's primary view. Here we want
-to display our blog entries in a custom way.
-
-At `line 10`, a simple request is made to build a result set with all
-the entities linked to the current ``Blog`` entity by the relationship
-``entry_of``. The part of the framework handling the request knows
-about the schema and infers that such entities have to be of the
-``BlogEntry`` kind and retrieves them (in the prescribed publish_date
-order).
-
-The request returns a selection of data called a result set. Result
-set objects have an .entities() method returning a generator on
-requested entities (going transparently through the `ORM` layer).
-
-At `line 13` the view 'inblogcontext' is applied to each blog entry to
-output HTML. (Note that the 'inblogcontext' view is not defined
-whatsoever in *CubicWeb*. You are absolutely free to define whole view
-families.) We juste arrange to wrap each blogentry output in a 'p'
-html element.
-
-Next, we define the 'inblogcontext' view. This is NOT a primary view,
-with its well-defined sections (title, metadata, attribtues,
-relations/boxes). All a basic view has to define is cell_call.
-
-Since views are applied to result sets which can be tables of data, we
-have to recover the entity from its (row,col)-coordinates (`line
-20`). Then we can spit some HTML.
-
-But careful: all strings manipulated in *CubicWeb* are actually
-unicode strings. While web browsers are usually tolerant to incoherent
-encodings they are being served, we should not abuse it. Hence we have
-to properly escape our data. The xml_escape() function has to be used
-to safely fill (X)HTML elements from Python unicode strings.
-
-
-**This is to be compared to interfaces and protocols in object-oriented
-languages. Applying a given view called 'a_view' to all the entities
-of a result set only requires to have for each entity of this result set,
-an available view called 'a_view' which accepts the entity.**
-
-**Instead of merely using type based dispatch, we do predicate dispatch
-which is quite more powerful.**
-
-Assuming we added entries to the blog titled `MyLife`, displaying it
-now allows to read its description and all its entries.
-
-.. image:: ../../images/lax-book.10-blog-with-two-entries.en.png
-   :alt: a blog and all its entries
-
-**Before we move forward, remember that the selection/view principle is
-at the core of *CubicWeb*. Everywhere in the engine, data is requested
-using the RQL language, then HTML/XML/text/PNG is output by applying a
-view to the result set returned by the query. That is where most of the
-flexibility comes from.**
-
-[WRITE ME]
-
-* implementing interfaces, calendar for blog entries
-* show that a calendar view can export data to ical
-
-We will implement the `cubicweb.interfaces.ICalendarable` interfaces on
-entities.BlogEntry and apply the OneMonthCalendar and iCalendar views
-to result sets like "Any E WHERE E is BlogEntry"
-
-* create view "blogentry table" with title, publish_date, category
-
-We will show that by default the view that displays
-"Any E,D,C WHERE E publish_date D, E category C" is the table view.
-Of course, the same can be obtained by calling
-self.wview('table',rset)
-
-* in view blog, select blogentries and apply view "blogentry table"
-* demo ajax by filtering blogentry table on category
-
-we did the same with 'primary', but with tables we can turn on filters
-and show that ajax comes for free.
-[FILLME]
-
-
-XML views, binaries views...
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For views generating other formats than HTML (an image generated dynamically
-for example), and which can not simply be included in the HTML page generated
-by the main template (see above), you have to:
-
-* set the attribute `templatable` of the class to `False`
-* set, through the attribute `content_type` of the class, the MIME type generated
-  by the view to `application/octet-stream`
-
-For views dedicated to binary content creation (like dynamically generated
-images), we have to set the attribute `binary` of the class to `True` (which
-implies that `templatable == False`, so that the attribute `w` of the view could be
-replaced by a binary flow instead of unicode).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/autoform.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,69 @@
+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 ::
+
+  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``
+
+Possible tags are detailled below
+
+Simple Tags
+~~~~~~~~~~~~~~~~~~~~
+
+* `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.
+
+* `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.
+
+* `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.
+
+* `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 necessary, it is possible to overwrite the method
+`relation_category(rtype, x='subject')` to dynamically compute
+a relation editing category.
+
+
+Advanced Tags
+~~~~~~~~~~~~~~~~~~~~
+
+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 ::
+
+  from cubicweb.web import uicfg, formfields, formwidgets
+
+  uicfg.autoform_field.tag_attribute(('Execdata', 'path'),
+      formfields.FileField(name='path', widget=formwidgets.FileInput()))
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/basetemplates.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,189 @@
+.. -*- coding: utf-8 -*-
+
+.. _templates:
+
+Templates
+=========
+
+[WRITE ME]
+
+* talk about main templates, etc.
+
+
+
+Look at ``cubicweb/web/views/basetemplates.py`` and you will
+find the base templates used to generate HTML for your application.
+
+A page is composed as indicated on the schema below :
+
+.. image:: ../../../images/main_template.png
+
+In this section we will go through a couple of the primary templates
+you must be interested in, that is to say, the HTMLPageHeader,
+the HTMLPageFooter and the TheMainTemplate.
+
+
+HTMLPageHeader
+--------------
+
+Customize header
+~~~~~~~~~~~~~~~~
+
+Let's now move the search box in the header and remove the login form
+from the header. We'll show how to move it to the left column of the application.
+
+Let's say we do not want anymore the login menu to be in the header, but we
+prefer it to be in the left column just below the logo. As the left column is
+rendered by ``TheMainTemplate``, we will show how to do it in TheMainTemplate_.
+
+First, to remove the login menu, we just need to comment out the display of the
+login component such as follows : ::
+
+  class MyHTMLPageHeader(HTMLPageHeader):
+
+      def main_header(self, view):
+          """build the top menu with authentification info and the rql box"""
+          self.w(u'<table id="header"><tr>\n')
+          self.w(u'<td id="firstcolumn">')
+          self._cw.vreg.select_component('logo', self._cw, self.cw_rset).dispatch(w=self.w)
+          self.w(u'</td>\n')
+          # appliname and breadcrumbs
+          self.w(u'<td id="headtext">')
+          comp = self._cw.vreg.select_component('appliname', self._cw, self.cw_rset)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w)
+          comp = self._cw.vreg.select_component('breadcrumbs', self._cw, self.cw_rset, view=view)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w, view=view)
+          self.w(u'</td>')
+          # logged user and help
+          #self.w(u'<td>\n')
+          #comp = self._cw.vreg.select_component('loggeduserlink', self._cw, self.cw_rset)
+          #comp.dispatch(w=self.w)
+          #self.w(u'</td><td>')
+
+          self.w(u'<td>')
+          helpcomp = self._cw.vreg.select_component('help', self._cw, self.cw_rset)
+          if helpcomp: # may not be available if Card is not defined in the schema
+              helpcomp.dispatch(w=self.w)
+          self.w(u'</td>')
+          # lastcolumn
+          self.w(u'<td id="lastcolumn">')
+          self.w(u'</td>\n')
+          self.w(u'</tr></table>\n')
+          self.template('logform', rset=self.cw_rset, id='popupLoginBox', klass='hidden',
+                        title=False, message=False)
+
+
+
+.. image:: ../../../images/lax-book.06-header-no-login.en.png
+
+Let's now move the search box in the top-right header area. To do so, we will
+first create a method to get the search box display and insert it in the header
+table.
+
+::
+
+ from cubicweb.web.views.basetemplates import HTMLPageHeader
+ class MyHTMLPageHeader(HTMLPageHeader):
+    def main_header(self, view):
+        """build the top menu with authentification info and the rql box"""
+        self.w(u'<table id="header"><tr>\n')
+        self.w(u'<td id="firstcolumn">')
+        self._cw.vreg.select_component('logo', self._cw, self.cw_rset).dispatch(w=self.w)
+        self.w(u'</td>\n')
+        # appliname and breadcrumbs
+        self.w(u'<td id="headtext">')
+        comp = self._cw.vreg.select_component('appliname', self._cw, self.cw_rset)
+        if comp and comp.propval('visible'):
+            comp.dispatch(w=self.w)
+        comp = self._cw.vreg.select_component('breadcrumbs', self._cw, self.cw_rset, view=view)
+        if comp and comp.propval('visible'):
+            comp.dispatch(w=self.w, view=view)
+        self.w(u'</td>')
+
+        # logged user and help
+        #self.w(u'<td>\n')
+        #comp = self._cw.vreg.select_component('loggeduserlink', self._cw, self.cw_rset)
+        #comp.dispatch(w=self.w)
+        #self.w(u'</td><td>')
+
+        # search box
+        self.w(u'<td>')
+        self.get_searchbox(view, 'left')
+        self.w(u'</td>')
+
+        self.w(u'<td>')
+        helpcomp = self._cw.vreg.select_component('help', self._cw, self.cw_rset)
+        if helpcomp: # may not be available if Card is not defined in the schema
+            helpcomp.dispatch(w=self.w)
+        self.w(u'</td>')
+        # lastcolumn
+        self.w(u'<td id="lastcolumn">')
+        self.w(u'</td>\n')
+        self.w(u'</tr></table>\n')
+        self.template('logform', rset=self.cw_rset, id='popupLoginBox', klass='hidden',
+                      title=False, message=False)
+
+    def get_searchbox(self, view, context):
+        boxes = list(self._cw.vreg.poss_visible_objects('boxes', self._cw, self.cw_rset,
+                                                    view=view, context=context))
+        if boxes:
+            for box in boxes:
+                if box.__regid__ == 'search_box':
+                    box.dispatch(w=self.w, view=view)
+
+
+
+
+HTMLPageFooter
+--------------
+
+If you want to change the footer for example, look
+for HTMLPageFooter and override it in your views file as in :
+::
+
+  form cubicweb.web.views.basetemplates import HTMLPageFooter
+  class MyHTMLPageFooter(HTMLPageFooter):
+      def call(self, **kwargs):
+          self.w(u'<div class="footer">')
+          self.w(u'This website has been created with <a href="http://cubicweb.org">CubicWeb</a>.')
+          self.w(u'</div>')
+
+Updating a view does not require any restart of the server. By reloading
+the page you can see your new page footer.
+
+
+TheMainTemplate
+---------------
+.. _TheMainTemplate:
+
+TheMainTemplate is responsible for the general layout of the entire application.
+It defines the template of ``__regid__ = main`` that is used by the instance.
+
+The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
+builds the page based on the following pattern:
+
+.. image:: ../../../images/main_template_layout.png
+
+The rectangle containing `view.dispatch()` represents the area where the content
+view has to be displayed. The others represents sub-templates called to complete
+the page. A default implementation of those is provided in
+`cubicweb.views.basetemplates`. You can, of course, overload those sub-templates
+to implement your own customization of the HTML page.
+
+We can also control certain aspects of the main template thanks to the following
+forms parameters:
+
+* `__notemplate`, if present (whatever the value assigned), only the content view
+  is returned
+* `__force_display`, if present and its value is not null, no navigation
+  whatever the number of entities to display
+* `__method`, if the result set to render contains only one entity and this
+  parameter is set, it refers to a method to call on the entity by passing it
+  the dictionary of the forms parameters, before going the classic way (through
+  step 1 and 2 described juste above)
+
+The MainTemplate is a bit complex as it tries to accomodate many
+different cases. We are now about to go through it and cutomize entirely
+our application.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/baseviews.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,78 @@
+.. -*- coding: utf-8 -*-
+
+Base views (:mod:`cubicweb.web.views.baseviews`)
+------------------------------------------------
+
+*CubicWeb* provides a lot of standard views. You can find them in
+``cubicweb/web/views/``.
+
+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
+~~~~~~~~~~
+
+Special views
+`````````````
+
+*noresult*
+    This view is the default view used when no result has been found
+    (e.g. empty result set).
+
+*final*
+    Display the value of a cell without trasnformation (in case of a non final
+    entity, we see the eid). Applicable on any result set.
+
+*null*
+    This view is the default view used when nothing needs to be rendered.
+    It is always applicable and it does not return anything
+
+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
+    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`
+    in a link leading to the primary view of the entity.
+
+List
+`````
+
+*list*
+    This view displays a list of entities by creating a HTML list (`<ul>`)
+    and call the view `listitem` for each entity of the result set.
+
+*listitem*
+    This view redirects by default to the `outofcontext` view.
+
+*sameetypelist*
+    This view displays a list of entities of the same type, in HTML section (`<div>`)
+    and call the view `sameetypelistitem` for each entity of the result set.
+
+*sameetypelistitem*
+    This view redirects by default to the `listitem` view.
+
+*csv*
+    This view applies to entity groups, which are individually
+    displayed using the `incontext` view. It displays each entity as a
+    coma separated list. It is NOT related to the well-known text file
+    format.
+
+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
+    `navigation.short-line-size` property if necessary.
+
+*textincontext, textoutofcontext*
+    Similar to the `text` view, but called when an entity is considered out or
+    in context. By default it returns respectively the result of the
+    methods `.dc_title` and `.dc_long_title` of the entity.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/boxes.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,34 @@
+Boxes (:mod:`cubicweb.web.views.boxes`)
+---------------------------------------------------------------
+
+*sidebox*
+  This view displays usually a side box of some related entities
+  in a primary view.
+
+The action box
+~~~~~~~~~~~~~~~
+
+The ``add_related`` is an automatic menu in the action 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 explicitly specify them thanks to the
+`cubicweb.web.uicfg.rmode` *relation tag*:
+
+* `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 necessary, 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).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/breadcrumbs.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,3 @@
+Breadcrumbs (:mod:`cubicweb.web.views.ibreadcrumbs`)
+----------------------------------------------------
+XXX feedme
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/editforms.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,3 @@
+Standard forms (:mod:`cubicweb.web.views.editforms`)
+----------------------------------------------------
+XXX feed me
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/embedding.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Embedding external pages (:mod:`cubicweb.web.views.embedding`)
+---------------------------------------------------------------
+
+including external content
+
+XXX feeed me
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/facets.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,3 @@
+Facets (:mod:`cubicweb.web.views.facets`)
+-----------------------------------------
+XXX feed me
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/idownloadable.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,3 @@
+The 'download' view (:mod:`cubicweb.web.views.idownloadable`)
+---------------------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,30 @@
+The views 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|.
+
+
+.. toctree::
+   :maxdepth: 3
+
+   views
+   basetemplates
+   primary
+   baseviews
+   startup
+   boxes
+   table
+   xmlrss
+   autoform
+   editforms
+   urlpublish
+   breadcrumbs
+   facets
+   wdoc
+   embedding
+   idownloadable
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/primary.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,312 @@
+.. _primary_view:
+
+The Primary View
+-----------------
+
+(:mod:`cubicweb.web.views.primary`)
+
+By default, *CubicWeb* provides a view that fits every available
+entity type. This is the first view you might be interested in
+modifying. It is also one of the richest and most complex.
+
+It is automatically selected on a one line result set containing an
+entity.
+
+This view is supposed to render a maximum of informations about the
+entity.
+
+.. _primary_view_layout:
+
+Layout
+``````
+
+The primary view has the following layout.
+
+.. image:: ../../../images/primaryview_template.png
+
+.. _primary_view_configuration:
+
+Primary view configuration
+``````````````````````````
+
+If you want to customize the primary view of an entity, overriding the primary
+view class may not be necessary. For simple adjustments (attributes or relations
+display locations and styles), a much simpler way is to use uicfg.
+
+Attributes/relations display location
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the primary view, there are 3 sections where attributes and
+relations can be displayed (represented in pink in the image above):
+
+* attributes
+* relations
+* sideboxes
+
+**Attributes** can only be displayed in the attributes section (default
+  behavior). They can also be hidden.
+
+For instance, to hide the ``title`` attribute of the ``Blog`` entity:
+
+.. sourcecode:: python
+
+   from cubicweb.web import uicfg
+   uicfg.primaryview_section.tag_attribute(('Blog', 'title'), 'hidden')
+
+**Relations** can be either displayed in one of the three sections or hidden.
+
+For relations, there are two methods:
+
+* ``tag_object_of`` for modifying the primary view of the object
+* ``tag_subject_of`` for modifying the primary view of the subject
+
+These two methods take two arguments:
+
+* a triplet ``(subject, relation_name, object)``, where subject or object can be replaced with ``'*'``
+* the section name or ``hidden``
+
+.. sourcecode:: python
+
+   pv_section = uicfg.primaryview_section
+   # hide every relation `entry_of` in the `Blog` primary view
+   pv_section.tag_object_of(('*', 'entry_of', 'Blog'), 'hidden')
+
+   # display `entry_of` relations in the `relations`
+   # section in the `BlogEntry` primary view
+   pv_section.tag_subject_of(('BlogEntry', 'entry_of', '*'), 'relations')
+
+
+Display content
+^^^^^^^^^^^^^^^
+
+You can use ``primaryview_display_ctrl`` to customize the display of attributes
+or relations. Values of ``primaryview_display_ctrl`` are dictionaries.
+
+
+Common keys for attributes and relations are:
+
+* ``vid``: specifies the regid of the view for displaying the attribute or the relation.
+
+  If ``vid`` is not specified, the default value depends on the section:
+    * ``attributes`` section: 'reledit' view
+    * ``relations`` section: 'autolimited' view
+    * ``sideboxes`` section: 'sidebox' view
+
+* ``order``: int used to control order within a section. When not specified,
+  automatically set according to order in which tags are added.
+
+.. sourcecode:: python
+
+   # let us remind the schema of a blog entry
+   class BlogEntry(EntityType):
+       title = String(required=True, fulltextindexed=True, maxsize=256)
+       publish_date = Date(default='TODAY')
+       content = String(required=True, fulltextindexed=True)
+       entry_of = SubjectRelation('Blog', cardinality='?*')
+
+   # now, we want to show attributes
+   # with an order different from that in the schema definition
+   view_ctrl = uicfg.primaryview_display_ctrl
+   for index, attr in enumerate('title', 'content', 'publish_date'):
+       view_ctrl.tag_attribute(('BlogEntry', attr), {'order': index})
+
+Keys for relations only:
+
+* ``label``: label for the relations section or side box
+
+* ``showlabel``: boolean telling whether the label is displayed
+
+* ``limit``: boolean telling if the results should be limited. If so, a link to all results is displayed
+
+* ``filter``: callback taking the related result set as argument and returning it filtered
+
+.. sourcecode:: python
+
+   pv_section = uicfg.primaryview_section
+   # in `CWUser` primary view, display `created_by`
+   # relations in relations section
+   pv_section.tag_object_of(('*', 'created_by', 'CWUser'), 'relations')
+
+   # display this relation as a list, sets the label,
+   # limit the number of results and filters on comments
+   def filter_comment(rset):
+       return rset.filtered_rset(lambda x: x.e_schema == 'Comment')
+   pv_ctrl = uicfg.primaryview_display_ctrl
+   pv_ctrl.tag_object_of(('*', 'created_by', 'CWUser'),
+                         {'vid': 'list', 'label': _('latest comment(s):'),
+                          'limit': True,
+                          'filter': filter_comment})
+
+.. warning:: with the ``primaryview_display_ctrl`` rtag, the subject or the
+   object of the relation is ignored for respectively ``tag_object_of`` or
+   ``tag_subject_of``. To avoid warnings during execution, they should be set to
+   ``'*'``.
+
+Rendering methods and attributes
+````````````````````````````````
+
+The basic layout of a primary view is as in the
+:ref:`primary_view_layout` section. This layout is actually drawn by
+the `render_entity` method.
+
+The methods you may want to modify while customizing a ``PrimaryView``
+are:
+
+*render_entity_title(self, entity)*
+    Renders the entity title using the ``def dc_title(self)`` method.
+
+*render_entity_metadata(self, entity)*
+    Renders the entity metadata by calling the ``metadata`` view on the
+    entity. This generic view is in cubicweb.views.baseviews.
+
+*render_entity_attributes(self, entity)*
+    Renders all the attribute of an entity with the exception of
+    attribute of type `Password` and `Bytes`. The skip_none class
+    attribute controls the display of None valued attributes.
+
+*render_entity_relations(self, entity)*
+    Renders all the relations of the entity in the main section of the page.
+
+*render_side_boxes(self, entity, boxes)*
+    Renders relations of the entity in a side box.
+
+The placement of relations in the relations section or in side boxes
+can be controlled through the :ref:`primary_view_configuration` mechanism.
+
+*content_navigation_components(self, context)*
+    This method is applicable only for entity type implementing the interface
+    `IPrevNext`. This interface is for entities which can be linked to a previous
+    and/or next entity. This method will render the navigation links between
+    entities of this type, either at the top or at the bottom of the page
+    given the context (navcontent{top|bottom}).
+
+Also, please note that by setting the following attributes in your
+subclass, you can already customize some of the rendering:
+
+*show_attr_label*
+    Renders the attribute label next to the attribute value if set to True.
+    Otherwise, does only display the attribute value.
+
+*show_rel_label*
+    Renders the relation label next to the relation value if set to True.
+    Otherwise, does only display the relation value.
+
+*skip_none*
+    Does not render an attribute value that is None if set to True.
+
+*main_related_section*
+    Renders the relations of the entity if set to True.
+
+A good practice is for you to identify the content of your entity type for which
+the default rendering does not answer your need so that you can focus on the specific
+method (from the list above) that needs to be modified. We do not advise you to
+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.
+
+We continue along the basic tutorial :ref:`tuto_blog`.
+
+If you want to change the way a ``BlogEntry`` is displayed, just override
+the method ``cell_call()`` of the view ``primary`` in ``BlogDemo/views.py``:
+
+.. sourcecode:: python
+
+  from cubicweb.selectors import implements
+  from cubicweb.web.views.primary improt Primaryview
+
+  class BlogEntryPrimaryView(PrimaryView):
+    __select__ = PrimaryView.__select__ & implements('BlogEntry')
+
+      def render_entity_attributes(self, entity):
+          self.w(u'<p>published on %s</p>' %
+                 entity.publish_date.strftime('%Y-%m-%d'))
+          super(BlogEntryPrimaryView, self).render_entity_attributes(entity)
+
+The above source code defines a new primary view for
+``BlogEntry``. The `id` class attribute is not repeated there since it
+is inherited through the `primary.PrimaryView` class.
+
+The selector for this view chains the selector of the inherited class
+with its own specific criterion.
+
+The view method ``self.w()`` is used to output data. Here `lines
+08-09` output HTML for the publication date of the entry.
+
+.. image:: ../../../images/lax-book.09-new-view-blogentry.en.png
+   :alt: blog entries now look much nicer
+
+Let us now improve the primary view of a blog
+
+.. sourcecode:: python
+
+ from logilab.mtconverter import xml_escape
+ from cubicweb.selectors import implements, one_line_rset
+ from cubicweb.web.views.primary import Primaryview
+
+ class BlogPrimaryView(PrimaryView):
+     __regid__ = 'primary'
+     __select__ = PrimaryView.__select__ & implements('Blog')
+     rql = 'Any BE ORDERBY D DESC WHERE BE entry_of B, BE publish_date D, B eid %(b)s'
+
+     def render_entity_relations(self, entity):
+         rset = self._cw.execute(self.rql, {'b' : entity.eid})
+         for entry in rset.entities():
+             self.w(u'<p>%s</p>' % entry.view('inblogcontext'))
+
+ class BlogEntryInBlogView(EntityView):
+     __regid__ = 'inblogcontext'
+     __select__ = implements('BlogEntry')
+
+     def cell_call(self, row, col):
+         entity = self.cw_rset.get_entity(row, col)
+         self.w(u'<a href="%s" title="%s">%s</a>' %
+                entity.absolute_url(),
+                xml_escape(entity.content[:50]),
+                xml_escape(entity.description))
+
+This happens in two places. First we override the
+render_entity_relations method of a Blog's primary view. Here we want
+to display our blog entries in a custom way.
+
+At `line 10`, a simple request is made to build a result set with all
+the entities linked to the current ``Blog`` entity by the relationship
+``entry_of``. The part of the framework handling the request knows
+about the schema and infers that such entities have to be of the
+``BlogEntry`` kind and retrieves them (in the prescribed publish_date
+order).
+
+The request returns a selection of data called a result set. Result
+set objects have an .entities() method returning a generator on
+requested entities (going transparently through the `ORM` layer).
+
+At `line 13` the view 'inblogcontext' is applied to each blog entry to
+output HTML. (Note that the 'inblogcontext' view is not defined
+whatsoever in *CubicWeb*. You are absolutely free to define whole view
+families.) We juste arrange to wrap each blogentry output in a 'p'
+html element.
+
+Next, we define the 'inblogcontext' view. This is NOT a primary view,
+with its well-defined sections (title, metadata, attribtues,
+relations/boxes). All a basic view has to define is cell_call.
+
+Since views are applied to result sets which can be tables of data, we
+have to recover the entity from its (row,col)-coordinates (`line
+20`). Then we can spit some HTML.
+
+.. warning::
+
+  Be careful: all strings manipulated in *CubicWeb* are actually
+  unicode strings. While web browsers are usually tolerant to
+  incoherent encodings they are being served, we should not abuse
+  it. Hence we have to properly escape our data. The xml_escape()
+  function has to be used to safely fill (X)HTML elements from Python
+  unicode strings.
+
+Assuming we added entries to the blog titled `MyLife`, displaying it
+now allows to read its description and all its entries.
+
+.. image:: ../../../images/lax-book.10-blog-with-two-entries.en.png
+   :alt: a blog and all its entries
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/startup.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,13 @@
+Startup views (:mod:`cubicweb.web.views.startup`)
+-------------------------------------------------
+Usual selector: no_rset or yes.
+
+Views that don't apply to a result set
+
+*index*
+    This view defines the home page of your application. It does not require
+    a result set to apply to.
+
+*schema*
+    A view dedicated to the display of the schema of the instance
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/table.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,10 @@
+Table views (:mod:`cubicweb.web.views.table`)
+----------------------------------------------
+
+*table*
+    Creates a HTML table (`<table>`) and call the view `cell` for each cell of
+    the result set. Applicable on any result set.
+
+*cell*
+    By default redirects to the `final` view if this is a final entity or
+    `outofcontext` view otherwise
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/urlpublish.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,7 @@
+.. -*- coding: utf-8 -*-
+
+URL Rewriting (:mod:`cubicweb.web.views.urlpublish`) and (:mod:`cubicweb.web.views.urlrewrite`)
+------------------------------------------------------------------------------------------------
+
+XXX feed me
+show how urls are mapped to selections and views and explain URLRewriting
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/views.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,127 @@
+
+.. _Views:
+
+Principles
+----------
+
+We'll start with a description of the interface providing a basic
+understanding of the available classes and methods, then detail the
+view selection principle.
+
+A `View` is an object responsible for the rendering of data from the
+model into an end-user consummable form. They typically churn out an
+XHTML stream, but there are views concerned with email other non-html
+outputs.
+
+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.
+
+A `View` is instantiated to render a result set or part of a result
+set. `View` subclasses may be parametrized using the following class
+attributes:
+
+* `templatable` indicates if the view may be embedded in a main
+  template or if it has to be rendered standalone (i.e. pure XML views
+  must not be embedded in the main template of HTML pages)
+
+* if the view is not templatable, it should set the `content_type`
+  class attribute to the correct MIME type (text/xhtml being the
+  default)
+
+* the `category` attribute may be used in the interface to regroup
+  related view kinds together
+
+A view writes to its output stream thanks to its attribute `w` (the
+append method of an `UStreamIO`, except for binary views).
+
+At instantiation time, the standard `_cw` and `cw_rset` attributes are
+added and the `w` attribute will be set at rendering time.
+
+The basic interface for views is as follows (remember that the result
+set has a tabular structure with rows and columns, hence cells):
+
+* `render(**context)`, render the view by calling `call` or
+  `cell_call` depending on the context
+
+* `call(**kwargs)`, call the view for a complete result set or null
+  (the default implementation calls `cell_call()` on each cell of the
+  result set)
+
+* `cell_call(row, col, **kwargs)`, call the view for a given cell of a
+  result set (`row` and `col` being integers used to access the cell)
+
+* `url()`, returns the URL enabling us to get the view with the current
+  result set
+
+* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of
+  identifier `__vid` on the given result set. It is possible to give a
+  fallback view identifier that will be used if the requested view is
+  not applicable to the result set.
+
+* `html_headers()`, returns a list of HTML headers to be set by the
+  main template
+
+* `page_title()`, returns the title to use in the HTML header `title`
+
+Other basic view classes
+````````````````````````
+Here are some of the subclasses of `View` defined in `cubicweb.common.view`
+that are more concrete as they relate to data rendering within the application:
+
+* `EntityView`, view applying to lines or cell containing an entity (e.g. an eid)
+* `StartupView`, start view that does not require a result set to apply to
+* `AnyRsetView`, view applicable to any result set
+
+Examples of views class
+```````````````````````
+
+- Using `templatable`, `content_type` and HTTP cache configuration
+
+.. sourcecode:: python
+
+    class RSSView(XMLView):
+        __regid__ = 'rss'
+        title = _('rss')
+        templatable = False
+        content_type = 'text/xml'
+        http_cache_manager = MaxAgeHTTPCacheManager
+        cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
+
+
+- Using a custom selector
+
+.. sourcecode:: python
+
+    class SearchForAssociationView(EntityView):
+        """view called by the edition view when the user asks
+        to search for something to link to the edited eid
+        """
+        __regid__ = 'search-associate'
+        title = _('search for association')
+        __select__ = one_line_rset() & match_search_state('linksearch') & implements('Any')
+
+
+
+
+XML views, binaries views...
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For views generating other formats than HTML (an image generated dynamically
+for example), and which can not simply be included in the HTML page generated
+by the main template (see above), you have to:
+
+* set the attribute `templatable` of the class to `False`
+* set, through the attribute `content_type` of the class, the MIME
+  type generated by the view to `application/octet-stream` or any
+  relevant and more specialised mime type
+
+For views dedicated to binary content creation (like dynamically generated
+images), we have to set the attribute `binary` of the class to `True` (which
+implies that `templatable == False`, so that the attribute `w` of the view could be
+replaced by a binary flow instead of unicode).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/wdoc.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,7 @@
+.. -*- coding: utf-8 -*-
+
+Online documentation system (:mod:`cubicweb.web.views.wdoc`)
+-------------------------------------------------------------
+
+XXX  describe the on-line documentation system
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/devweb/views/xmlrss.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,62 @@
+.. _XmlAndRss:
+
+XML and RSS views (:mod:`cubicweb.web.views.xmlrss`)
+----------------------------------------------------
+
+Overview
++++++++++
+
+*rss*
+    Creates a RSS/XML view and call the view `rssitem` for each entity of
+    the result set.
+
+*rssitem*
+    Create a RSS/XML view for each entity based on the results of the dublin core
+    methods of the entity (`dc_*`)
+
+
+RSS Channel Example
+++++++++++++++++++++
+
+Assuming you have several blog entries, click on the title of the
+search box in the left column. A larger search box should appear. Enter::
+
+   Any X ORDERBY D WHERE X is BlogEntry, X creation_date D
+
+and you get a list of blog entries.
+
+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.
+
+Enter the same query in the search box and you will see the same list,
+plus a box titled "possible views" in the left column. Click on
+"entityview", then "RSS".
+
+You just applied the "RSS" view to the RQL selection you requested.
+
+That's it, you have a RSS channel for your blog.
+
+Try again with::
+
+    Any X ORDERBY D WHERE X is BlogEntry, X creation_date D,
+    X entry_of B, B title "MyLife"
+
+Another RSS channel, but a bit more focused.
+
+A last one for the road::
+
+    Any C ORDERBY D WHERE C is Comment, C creation_date D LIMIT 15
+
+displayed with the RSS view, that's a channel for the last fifteen
+comments posted.
+
+[WRITE ME]
+
+* show that the RSS view can be used to display an ordered selection
+  of blog entries, thus providing a RSS channel
+
+* show that a different selection (by category) means a different channel
+
+
+
--- a/doc/book/en/development/entityclasses/data-as-objects.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/entityclasses/data-as-objects.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -53,7 +53,7 @@
 
   * `set_relations(**kwargs)`, add relations to the given object. To
      set a relation where this entity is the object of the relation,
-     use 'reverse_'<relation> as argument name.  Values may be an
+     use `reverse_<relation>` as argument name.  Values may be an
      entity, a list of entities, or None (meaning that all relations of
      the given type from or to this object should be deleted).
 
--- a/doc/book/en/development/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -1,8 +1,8 @@
 .. _Part2:
 
----------------------
-Part II - Development
----------------------
+-----------
+Development
+-----------
 
 This part is about developing web applications with the *CubicWeb* framework.
 
@@ -19,5 +19,4 @@
    devrepo/index
    testing.rst
    migration.rst
-   webstdlib/index
    profiling.rst
--- a/doc/book/en/development/testing.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/development/testing.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -3,9 +3,6 @@
 Tests
 =====
 
-.. toctree::
-   :maxdepth: 1
-
 Unit tests
 ----------
 
@@ -87,9 +84,12 @@
 The test case itself checks that an Operation does it job of
 preventing cycles amongst Keyword entities.
 
+You can see an example of security tests in the
+:ref:`adv_tuto_security`.
 
-XXX ref to advanced use case
-XXX apycot plug
+It is possible to have these tests run continuously using `apycot`_.
+
+.. _apycot: http://www.logilab.org/project/apycot
 
 Managing connections or users
 +++++++++++++++++++++++++++++
@@ -104,17 +104,31 @@
 Before a self.login, one has to release the connection pool in use
 with a self.commit, self.rollback or self.close.
 
+The `login` method returns a connection object that can be used as a
+context manager:
+
+.. sourcecode:: python
+
+   with self.login('user1') as user:
+       req = user.req
+       req.execute(...)
+
+On exit of the context manager, either a commit or rollback is issued,
+which releases the connection.
+
 When one is logged in as a normal user and wants to switch back to the
-admin user, one has to use self.restore_connection().
+admin user without committing, one has to use
+self.restore_connection().
 
-Usually it looks like this:
+Usage with restore_connection:
 
 .. sourcecode:: python
 
     # execute using default admin connection
     self.execute(...)
     # I want to login with another user, ensure to free admin connection pool
-    # (could have used rollback but not close here, we should never close defaut admin connection)
+    # (could have used rollback but not close here
+    # we should never close defaut admin connection)
     self.commit()
     cnx = self.login('user')
     # execute using user connection
@@ -130,8 +144,6 @@
    Do not use the references kept to the entities created with a
    connection from another !
 
-XXX the new context manager ?
-
 Email notifications tests
 -------------------------
 
@@ -182,21 +194,65 @@
 test. The code here has to be uncommented to be usable, without
 further modification.
 
-XXX more to come
+The ``auto_populate`` method uses a smart algorithm to create
+pseudo-random data in the database, thus enabling the views to be
+invoked and tested.
+
+Depending on the schema, hooks and operations constraints, it is not
+always possible for the automatic auto_populate to proceed.
 
+It is possible of course to completely redefine auto_populate. A
+lighter solution is to give hints (fill some class attributes) about
+what entities and relations have to be skipped by the auto_populate
+mechanism. These are:
+
+* `no_auto_populate`, may contain a list of entity types to skip
+* `ignored_relations`, may contain a list of relation types to skip
+* `application_rql`, may contain a list of rql expressions that
+  auto_populate cannot guess by itself; these must yield resultsets
+  against which views may be selected.
+
+
+Test APIS
+---------
 
 Using Pytest
 ````````````
 
-.. automodule:: logilab.common.testlib
+The `pytest` utility (shipping with `logilab-common`_, which is a
+mandatory dependency of CubicWeb) extends the Python unittest
+functionality and is the preferred way to run the CubicWeb test
+suites. Bare unittests also work the usual way.
+
+.. _logilab-common: http://www.logilab.org/project/logilab-common
+
+To use it, you may:
+
+* just launch `pytest` in your cube to execute all tests (it will
+  discover them automatically)
+* launch `pytest unittest_foo.py` to execute one test file
+* launch `pytest unittest_foo.py bar` to execute all test methods and
+  all test cases whose name contain `bar`
+
+Additionally, the `-x` option tells pytest to exit at the first error
+or failure. The `-i` option tells pytest to drop into pdb whenever an
+exception occurs in a test.
+
+When the `-x` option has been used and the run stopped on a test, it
+is possible, after having fixed the test, to relaunch pytest with the
+`-R` option to tell it to start testing again from where it previously
+failed.
+
+Using the `TestCase` base class
+```````````````````````````````
+
+The base class of CubicWebTC is logilab.common.testlib.TestCase, which
+provides a lot of convenient assertion methods.
+
 .. autoclass:: logilab.common.testlib.TestCase
    :members:
 
-XXX pytestconf.py & options (e.g --source to use a different db
-backend than sqlite)
-
 CubicWebTC API
 ``````````````
 .. autoclass:: cubicweb.devtools.testlib.CubicWebTC
    :members:
-
--- a/doc/book/en/development/webstdlib/autoform.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-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 ::
-
-  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``
-
-Possible tags are detailled below
-
-Simple Tags
-~~~~~~~~~~~~~~~~~~~~
-
-* `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.
-
-* `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.
-
-* `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.
-
-* `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 necessary, it is possible to overwrite the method
-`relation_category(rtype, x='subject')` to dynamically compute
-a relation editing category.
-
-
-Advanced Tags
-~~~~~~~~~~~~~~~~~~~~
-
-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 ::
-
-  from cubicweb.web import uicfg, formfields, formwidgets
-
-  uicfg.autoform_field.tag_attribute(('Execdata', 'path'),
-      formfields.FileField(name='path', widget=formwidgets.FileInput()))
-
-
-
-
-
-
-
--- a/doc/book/en/development/webstdlib/basetemplates.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _templates:
-
-Templates
-=========
-
-[WRITE ME]
-
-* talk about main templates, etc.
-
-
-
-Look at ``cubicweb/web/views/basetemplates.py`` and you will
-find the base templates used to generate HTML for your application.
-
-A page is composed as indicated on the schema below :
-
-.. image:: ../../images/lax-book.06-main-template-layout.en.png
-
-In this section we will go through a couple of the primary templates
-you must be interested in, that is to say, the HTMLPageHeader,
-the HTMLPageFooter and the TheMainTemplate.
-
-
-HTMLPageHeader
---------------
-
-Customize header
-~~~~~~~~~~~~~~~~
-
-Let's now move the search box in the header and remove the login form
-from the header. We'll show how to move it to the left column of the application.
-
-Let's say we do not want anymore the login menu to be in the header, but we
-prefer it to be in the left column just below the logo. As the left column is
-rendered by ``TheMainTemplate``, we will show how to do it in TheMainTemplate_.
-
-First, to remove the login menu, we just need to comment out the display of the
-login component such as follows : ::
-
-  class MyHTMLPageHeader(HTMLPageHeader):
-
-      def main_header(self, view):
-          """build the top menu with authentification info and the rql box"""
-          self.w(u'<table id="header"><tr>\n')
-          self.w(u'<td id="firstcolumn">')
-          self._cw.vreg.select_component('logo', self._cw, self.cw_rset).dispatch(w=self.w)
-          self.w(u'</td>\n')
-          # appliname and breadcrumbs
-          self.w(u'<td id="headtext">')
-          comp = self._cw.vreg.select_component('appliname', self._cw, self.cw_rset)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w)
-          comp = self._cw.vreg.select_component('breadcrumbs', self._cw, self.cw_rset, view=view)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w, view=view)
-          self.w(u'</td>')
-          # logged user and help
-          #self.w(u'<td>\n')
-          #comp = self._cw.vreg.select_component('loggeduserlink', self._cw, self.cw_rset)
-          #comp.dispatch(w=self.w)
-          #self.w(u'</td><td>')
-
-          self.w(u'<td>')
-          helpcomp = self._cw.vreg.select_component('help', self._cw, self.cw_rset)
-          if helpcomp: # may not be available if Card is not defined in the schema
-              helpcomp.dispatch(w=self.w)
-          self.w(u'</td>')
-          # lastcolumn
-          self.w(u'<td id="lastcolumn">')
-          self.w(u'</td>\n')
-          self.w(u'</tr></table>\n')
-          self.template('logform', rset=self.cw_rset, id='popupLoginBox', klass='hidden',
-                        title=False, message=False)
-
-
-
-.. image:: ../../images/lax-book.06-header-no-login.en.png
-
-Let's now move the search box in the top-right header area. To do so, we will
-first create a method to get the search box display and insert it in the header
-table.
-
-::
-
- from cubicweb.web.views.basetemplates import HTMLPageHeader
- class MyHTMLPageHeader(HTMLPageHeader):
-    def main_header(self, view):
-        """build the top menu with authentification info and the rql box"""
-        self.w(u'<table id="header"><tr>\n')
-        self.w(u'<td id="firstcolumn">')
-        self._cw.vreg.select_component('logo', self._cw, self.cw_rset).dispatch(w=self.w)
-        self.w(u'</td>\n')
-        # appliname and breadcrumbs
-        self.w(u'<td id="headtext">')
-        comp = self._cw.vreg.select_component('appliname', self._cw, self.cw_rset)
-        if comp and comp.propval('visible'):
-            comp.dispatch(w=self.w)
-        comp = self._cw.vreg.select_component('breadcrumbs', self._cw, self.cw_rset, view=view)
-        if comp and comp.propval('visible'):
-            comp.dispatch(w=self.w, view=view)
-        self.w(u'</td>')
-
-        # logged user and help
-        #self.w(u'<td>\n')
-        #comp = self._cw.vreg.select_component('loggeduserlink', self._cw, self.cw_rset)
-        #comp.dispatch(w=self.w)
-        #self.w(u'</td><td>')
-
-        # search box
-        self.w(u'<td>')
-        self.get_searchbox(view, 'left')
-        self.w(u'</td>')
-
-        self.w(u'<td>')
-        helpcomp = self._cw.vreg.select_component('help', self._cw, self.cw_rset)
-        if helpcomp: # may not be available if Card is not defined in the schema
-            helpcomp.dispatch(w=self.w)
-        self.w(u'</td>')
-        # lastcolumn
-        self.w(u'<td id="lastcolumn">')
-        self.w(u'</td>\n')
-        self.w(u'</tr></table>\n')
-        self.template('logform', rset=self.cw_rset, id='popupLoginBox', klass='hidden',
-                      title=False, message=False)
-
-    def get_searchbox(self, view, context):
-        boxes = list(self._cw.vreg.poss_visible_objects('boxes', self._cw, self.cw_rset,
-                                                    view=view, context=context))
-        if boxes:
-            for box in boxes:
-                if box.__regid__ == 'search_box':
-                    box.dispatch(w=self.w, view=view)
-
-
-
-
-HTMLPageFooter
---------------
-
-If you want to change the footer for example, look
-for HTMLPageFooter and override it in your views file as in :
-::
-
-  form cubicweb.web.views.basetemplates import HTMLPageFooter
-  class MyHTMLPageFooter(HTMLPageFooter):
-      def call(self, **kwargs):
-          self.w(u'<div class="footer">')
-          self.w(u'This website has been created with <a href="http://cubicweb.org">CubicWeb</a>.')
-          self.w(u'</div>')
-
-Updating a view does not require any restart of the server. By reloading
-the page you can see your new page footer.
-
-
-TheMainTemplate
----------------
-.. _TheMainTemplate:
-
-TheMainTemplate is responsible for the general layout of the entire application.
-It defines the template of ``__regid__ = main`` that is used by the instance.
-
-The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
-builds the page based on the following pattern:
-
-.. image:: ../../images/main_template_layout.png
-
-The rectangle containing `view.dispatch()` represents the area where the content
-view has to be displayed. The others represents sub-templates called to complete
-the page. A default implementation of those is provided in
-`cubicweb.views.basetemplates`. You can, of course, overload those sub-templates
-to implement your own customization of the HTML page.
-
-We can also control certain aspects of the main template thanks to the following
-forms parameters:
-
-* `__notemplate`, if present (whatever the value assigned), only the content view
-  is returned
-* `__force_display`, if present and its value is not null, no navigation
-  whatever the number of entities to display
-* `__method`, if the result set to render contains only one entity and this
-  parameter is set, it refers to a method to call on the entity by passing it
-  the dictionary of the forms parameters, before going the classic way (through
-  step 1 and 2 described juste above)
-
-The MainTemplate is a bit complex as it tries to accomodate many
-different cases. We are now about to go through it and cutomize entirely
-our application.
--- a/doc/book/en/development/webstdlib/baseviews.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Base views (:mod:`cubicweb.web.views.baseviews`)
-------------------------------------------------
-
-*CubicWeb* provides a lot of standard views. You can find them in
-``cubicweb/web/views/``.
-
-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
-~~~~~~~~~~
-
-Special views
-`````````````
-
-*noresult*
-    This view is the default view used when no result has been found
-    (e.g. empty result set).
-
-*final*
-    Display the value of a cell without trasnformation (in case of a non final
-    entity, we see the eid). Applicable on any result set.
-
-*null*
-    This view is the default view used when nothing needs to be rendered.
-    It is always applicable and it does not return anything
-
-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
-    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`
-    in a link leading to the primary view of the entity.
-
-List
-`````
-
-*list*
-    This view displays a list of entities by creating a HTML list (`<ul>`)
-    and call the view `listitem` for each entity of the result set.
-
-*listitem*
-    This view redirects by default to the `outofcontext` view.
-
-*sameetypelist*
-    This view displays a list of entities of the same type, in HTML section (`<div>`)
-    and call the view `sameetypelistitem` for each entity of the result set.
-
-*sameetypelistitem*
-    This view redirects by default to the `listitem` view.
-
-*csv*
-    This view applies to entity groups, which are individually
-    displayed using the `incontext` view. It displays each entity as a
-    coma separated list. It is NOT related to the well-known text file
-    format.
-
-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
-    `navigation.short-line-size` property if necessary.
-
-*textincontext, textoutofcontext*
-    Similar to the `text` view, but called when an entity is considered out or
-    in context. By default it returns respectively the result of the
-    methods `.dc_title` and `.dc_long_title` of the entity.
--- a/doc/book/en/development/webstdlib/boxes.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-Boxes (:mod:`cubicweb.web.views.boxes`)
----------------------------------------------------------------
-
-*sidebox*
-  This view displays usually a side box of some related entities
-  in a primary view.
-
-The action box
-~~~~~~~~~~~~~~~
-
-The ``add_related`` is an automatic menu in the action 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 explicitly specify them thanks to the
-`cubicweb.web.uicfg.rmode` *relation tag*:
-
-* `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 necessary, 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).
--- a/doc/book/en/development/webstdlib/breadcrumbs.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Breadcrumbs (:mod:`cubicweb.web.views.ibreadcrumbs`)
-----------------------------------------------------
-XXX feedme
\ No newline at end of file
--- a/doc/book/en/development/webstdlib/editcontroller.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-The 'edit' controller (:mod:`cubicweb.web.views.editcontroller`)
-----------------------------------------------------------------
-
-Editing control
-~~~~~~~~~~~~~~~~
-
-Re-requisites: the parameters related to entities to edit are
-specified as follows ::
-
-  <field name>:<entity eid>
-
-where entity eid could be a letter in case of an entity to create. We
-name those parameters as *qualified*.
-
-1. Retrieval of entities to edit by looking for the forms parameters
-   starting by `eid:` and also having a parameter `__type` associated
-   (also *qualified* by eid)
-
-2. For all the attributes and the relations of an entity to edit:
-
-   1. search for a parameter `edits-<relation name>` or `edito-<relation name>`
-      qualified in the case of a relation where the entity is object
-   2. if found, the value returned is considered as the initial value
-      for this relaiton and we then look for the new value(s)  in the parameter
-      <relation name> (qualified)
-   3. if the value returned is different from the initial value, an database update
-      request is done
-
-3. For each entity to edit:
-
-   1. if a qualified parameter `__linkto` is specified, its value has to be
-      a string (or a list of string) such as: ::
-
-        <relation type>:<eids>:<target>
-
-      where <target> is either `subject` or `object` and each eid could be
-      separated from the others by a `_`. Target specifies if the *edited entity*
-      is subject or object of the relation and each relation specified will
-      be inserted.
-
-    2. if a qualified parameter `__clone_eid` is specified for an entity, the
-       relations of the specified entity passed as value of this parameter are
-       copied on the edited entity.
-
-    3. if a qualified parameter `__delete` is specified, its value must be
-       a string or a list of string such as follows: ::
-
-          <ssubjects eids>:<relation type>:<objects eids>
-
-       where each eid subject or object can be seperated from the other
-       by `_`. Each relation specified will be deleted.
-
-    4. if a qualified parameter `__insert` is specified, its value should
-       follow the same pattern as `__delete`, but each relation specified is
-       inserted.
-
-4. If the parameters `__insert` and/or `__delete` are found not qualified,
-   they are interpreted as explained above (independantly from the number
-   of entities edited).
-
-5. If no entity is edited but the form contains the parameters `__linkto`
-   and `eid`, this one is interpreted by using the value specified for `eid`
-   to designate the entity on which to add the relations.
-
-
-.. note::
-
-   * If the parameter `__action_delete` is found, all the entities specified
-     as to be edited will be deleted.
-
-   * If the parameter`__action_cancel` is found, no action is completed.
-
-   * If the parameter `__action_apply` is found, the editing is applied
-     normally but the redirection is done on the form
-     (see :ref:`RedirectionControl`).
-
-   * The parameter `__method` is also supported as for the main template
-     (XXX not very consistent, maybe __method should be dealed in the view
-     controller).
-
-   * If no entity is found to be edited and if there is no parameter
-     `__action_delete`, `__action_cancel`, `__linkto`, `__delete` or
-     `__insert`, an error is raised.
-
-   * Using the parameter `__message` in the form will allow to use its value
-     as a message to provide the user once the editing is completed.
-
-
-.. _RedirectionControl:
-
-Redirection control
-~~~~~~~~~~~~~~~~~~~
-Once editing is completed, there is still an issue left: where should we go
-now? If nothing is specified, the controller will do his job but it does not
-mean we will be happy with the result. We can control that by using the
-following parameters:
-
-* `__redirectpath`: path of the URL (relative to the root URL of the site,
-  no form parameters
-
-* `__redirectparams`: forms parameters to add to the path
-
-* `__redirectrql`: redirection RQL request
-
-* `__redirectvid`: redirection view identifier
-
-* `__errorurl`: initial form URL, used for redirecting in case a validation
-  error is raised during editing. If this one is not specified, an error page
-  is displayed instead of going back to the form (which is, if necessary,
-  responsible for displaying the errors)
-
-* `__form_id`: initial view form identifier, used if `__action_apply` is
-  found
-
-In general we use either `__redirectpath` and `__redirectparams` or
-`__redirectrql` and `__redirectvid`.
-
--- a/doc/book/en/development/webstdlib/editforms.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Standard forms (:mod:`cubicweb.web.views.editforms`)
-----------------------------------------------------
-XXX feed me
--- a/doc/book/en/development/webstdlib/embedding.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Embedding external pages (:mod:`cubicweb.web.views.embedding`)
----------------------------------------------------------------
-
-including external content
-
-XXX feeed me
-
--- a/doc/book/en/development/webstdlib/facets.rst	Thu Apr 15 12:47:02 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/webstdlib/idownloadable.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-The 'download' view (:mod:`cubicweb.web.views.idownloadable`)
----------------------------------------------------------------
-
--- a/doc/book/en/development/webstdlib/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-Standard features for web interface development
-===============================================
-
-This chapter describes generic web features built as CubicWeb application objects.
-
-They are used for CubicWeb default automatic interface, but you're free to use
-them or not for you're own application.
-
-.. toctree::
-   :maxdepth: 1
-
-   basetemplates
-   primary
-   baseviews
-   startup
-   boxes
-   table
-   xmlrss
-   autoform
-   editforms
-   editcontroller
-   urlpublish
-   breadcrumbs
-   facets
-   wdoc
-   embedding
-   idownloadable
\ No newline at end of file
--- a/doc/book/en/development/webstdlib/primary.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-.. _primary:
-
-The Primary View
------------------
-
-(:mod:`cubicweb.web.views.primary`)
-
-By default, *CubicWeb* provides a view that fits every available
-entity type. This is the first view you might be interested in
-modifying. It is also one of the richest and most complex.
-
-It is automatically selected on a one line result set containing an
-entity.
-
-This view is supposed to render a maximum of informations about the
-entity.
-
-.. _primary_view_layout:
-
-Layout
-``````
-
-The primary view has the following layout.
-
-.. image:: ../../images/primaryview_template.png
-
-.. _primary_view_configuration:
-
-Primary view configuration
-``````````````````````````
-
-If you want to customize the primary view of an entity, overriding the primary
-view class may not be necessary. For simple adjustments (attributes or relations
-display locations and styles), a much simpler way is to use uicfg.
-
-Attributes/relations display location
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In the primary view, there are 3 sections where attributes and
-relations can be displayed (represented in pink in the image above):
-
-* attributes
-* relations
-* sideboxes
-
-**Attributes** can only be displayed in the attributes section (default
-  behavior). They can also be hidden.
-
-For instance, to hide the ``title`` attribute of the ``Blog`` entity:
-
-.. sourcecode:: python
-
-   from cubicweb.web import uicfg
-   uicfg.primaryview_section.tag_attribute(('Blog', 'title'), 'hidden')
-
-**Relations** can be either displayed in one of the three sections or hidden.
-
-For relations, there are two methods:
-
-* ``tag_object_of`` for modifying the primary view of the object
-* ``tag_subject_of`` for modifying the primary view of the subject
-
-These two methods take two arguments:
-
-* a triplet ``(subject, relation_name, object)``, where subject or object can be replaced with ``'*'``
-* the section name or ``hidden``
-
-.. sourcecode:: python
-
-   pv_section = uicfg.primaryview_section
-   # hide every relation `entry_of` in the `Blog` primary view
-   pv_section.tag_object_of(('*', 'entry_of', 'Blog'), 'hidden')
-
-   # display `entry_of` relations in the `relations`
-   # section in the `BlogEntry` primary view
-   pv_section.tag_subject_of(('BlogEntry', 'entry_of', '*'), 'relations')
-
-
-Display content
-^^^^^^^^^^^^^^^
-
-You can use ``primaryview_display_ctrl`` to customize the display of attributes
-or relations. Values of ``primaryview_display_ctrl`` are dictionaries.
-
-
-Common keys for attributes and relations are:
-
-* ``vid``: specifies the regid of the view for displaying the attribute or the relation.
-
-  If ``vid`` is not specified, the default value depends on the section:
-    * ``attributes`` section: 'reledit' view
-    * ``relations`` section: 'autolimited' view
-    * ``sideboxes`` section: 'sidebox' view
-
-* ``order``: int used to control order within a section. When not specified,
-  automatically set according to order in which tags are added.
-
-.. sourcecode:: python
-
-   # let us remind the schema of a blog entry
-   class BlogEntry(EntityType):
-       title = String(required=True, fulltextindexed=True, maxsize=256)
-       publish_date = Date(default='TODAY')
-       content = String(required=True, fulltextindexed=True)
-       entry_of = SubjectRelation('Blog', cardinality='?*')
-
-   # now, we want to show attributes
-   # with an order different from that in the schema definition
-   view_ctrl = uicfg.primaryview_display_ctrl
-   for index, attr in enumerate('title', 'content', 'publish_date'):
-       view_ctrl.tag_attribute(('BlogEntry', attr), {'order': index})
-
-Keys for relations only:
-
-* ``label``: label for the relations section or side box
-
-* ``showlabel``: boolean telling whether the label is displayed
-
-* ``limit``: boolean telling if the results should be limited. If so, a link to all results is displayed
-
-* ``filter``: callback taking the related result set as argument and returning it filtered
-
-.. sourcecode:: python
-
-   pv_section = uicfg.primaryview_section
-   # in `CWUser` primary view, display `created_by`
-   # relations in relations section
-   pv_section.tag_object_of(('*', 'created_by', 'CWUser'), 'relations')
-
-   # display this relation as a list, sets the label,
-   # limit the number of results and filters on comments
-   def filter_comment(rset):
-       return rset.filtered_rset(lambda x: x.e_schema == 'Comment')
-   pv_ctrl = uicfg.primaryview_display_ctrl
-   pv_ctrl.tag_object_of(('*', 'created_by', 'CWUser'),
-                         {'vid': 'list', 'label': _('latest comment(s):'),
-                          'limit': True,
-                          'filter': filter_comment})
-
-.. warning:: with the ``primaryview_display_ctrl`` rtag, the subject or the
-   object of the relation is ignored for respectively ``tag_object_of`` or
-   ``tag_subject_of``. To avoid warnings during execution, they should be set to
-   ``'*'``.
-
-Rendering methods and attributes
-````````````````````````````````
-
-The basic layout of a primary view is as in the
-:ref:`primary_view_layout` section. This layout is actually drawn by
-the `render_entity` method.
-
-The methods you may want to modify while customizing a ``PrimaryView``
-are:
-
-*render_entity_title(self, entity)*
-    Renders the entity title using the ``def dc_title(self)`` method.
-
-*render_entity_metadata(self, entity)*
-    Renders the entity metadata by calling the ``metadata`` view on the
-    entity. This generic view is in cubicweb.views.baseviews.
-
-*render_entity_attributes(self, entity)*
-    Renders all the attribute of an entity with the exception of
-    attribute of type `Password` and `Bytes`. The skip_none class
-    attribute controls the display of None valued attributes.
-
-*render_entity_relations(self, entity)*
-    Renders all the relations of the entity in the main section of the page.
-
-*render_side_boxes(self, entity, boxes)*
-    Renders relations of the entity in a side box.
-
-The placement of relations in the relations section or in side boxes
-can be controlled through the :ref:`primary_view_configuration` mechanism.
-
-*content_navigation_components(self, context)*
-    This method is applicable only for entity type implementing the interface
-    `IPrevNext`. This interface is for entities which can be linked to a previous
-    and/or next entity. This method will render the navigation links between
-    entities of this type, either at the top or at the bottom of the page
-    given the context (navcontent{top|bottom}).
-
-Also, please note that by setting the following attributes in your
-subclass, you can already customize some of the rendering:
-
-*show_attr_label*
-    Renders the attribute label next to the attribute value if set to True.
-    Otherwise, does only display the attribute value.
-
-*show_rel_label*
-    Renders the relation label next to the relation value if set to True.
-    Otherwise, does only display the relation value.
-
-*skip_none*
-    Does not render an attribute value that is None if set to True.
-
-*main_related_section*
-    Renders the relations of the entity if set to True.
-
-A good practice is for you to identify the content of your entity type for which
-the default rendering does not answer your need so that you can focus on the specific
-method (from the list above) that needs to be modified. We do not advise you to
-overwrite ``render_entity`` unless you want a completely different layout.
--- a/doc/book/en/development/webstdlib/startup.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-Startup views (:mod:`cubicweb.web.views.startup`)
--------------------------------------------------
-Usual selector: no_rset or yes.
-
-Views that don't apply to a result set
-
-*index*
-    This view defines the home page of your application. It does not require
-    a result set to apply to.
-
-*schema*
-    A view dedicated to the display of the schema of the instance
-
--- a/doc/book/en/development/webstdlib/table.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-Table views (:mod:`cubicweb.web.views.table`)
-----------------------------------------------
-
-*table*
-    Creates a HTML table (`<table>`) and call the view `cell` for each cell of
-    the result set. Applicable on any result set.
-
-*cell*
-    By default redirects to the `final` view if this is a final entity or
-    `outofcontext` view otherwise
--- a/doc/book/en/development/webstdlib/urlpublish.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-URL Rewriting (:mod:`cubicweb.web.views.urlpublish`) and (:mod:`cubicweb.web.views.urlrewrite`)
-------------------------------------------------------------------------------------------------
-
-XXX feed me
-show how urls are mapped to selections and views and explain URLRewriting
--- a/doc/book/en/development/webstdlib/wdoc.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Online documentation system (:mod:`cubicweb.web.views.wdoc`)
--------------------------------------------------------------
-
-XXX  describe the on-line documentation system
-
--- a/doc/book/en/development/webstdlib/xmlrss.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-.. _XmlAndRss:
-
-XML and RSS views (:mod:`cubicweb.web.views.xmlrss`)
-----------------------------------------------------
-
-Overview
-+++++++++
-
-*rss*
-    Creates a RSS/XML view and call the view `rssitem` for each entity of
-    the result set.
-
-*rssitem*
-    Create a RSS/XML view for each entity based on the results of the dublin core
-    methods of the entity (`dc_*`)
-
-
-RSS Channel Example
-++++++++++++++++++++
-
-Assuming you have several blog entries, click on the title of the
-search box in the left column. A larger search box should appear. Enter::
-
-   Any X ORDERBY D WHERE X is BlogEntry, X creation_date D
-
-and you get a list of blog entries.
-
-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.
-
-Enter the same query in the search box and you will see the same list,
-plus a box titled "possible views" in the left column. Click on
-"entityview", then "RSS".
-
-You just applied the "RSS" view to the RQL selection you requested.
-
-That's it, you have a RSS channel for your blog.
-
-Try again with::
-
-    Any X ORDERBY D WHERE X is BlogEntry, X creation_date D,
-    X entry_of B, B title "MyLife"
-
-Another RSS channel, but a bit more focused.
-
-A last one for the road::
-
-    Any C ORDERBY D WHERE C is Comment, C creation_date D LIMIT 15
-
-displayed with the RSS view, that's a channel for the last fifteen
-comments posted.
-
-[WRITE ME]
-
-* show that the RSS view can be used to display an ordered selection
-  of blog entries, thus providing a RSS channel
-
-* show that a different selection (by category) means a different channel
-
-
-
Binary file doc/book/en/images/main_template.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/images/main_template.svg	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1036.6421"
+   height="845.07812"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="main_template.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0"
+   inkscape:export-filename="/home/auc/cw/doc/book/en/images/main_template.png"
+   inkscape:export-xdpi="60.659016"
+   inkscape:export-ydpi="60.659016">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.80355603"
+     inkscape:cx="510.91495"
+     inkscape:cy="422.53906"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="925"
+     inkscape:window-height="1168"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:snap-bbox="true" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(162.2968,90.697922)">
+    <rect
+       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect2439"
+       width="854.37006"
+       height="698.2019"
+       x="20.307629"
+       y="-20.575344" />
+    <rect
+       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3301"
+       width="816.3457"
+       height="508.15628"
+       x="31.751091"
+       y="96.33345" />
+    <g
+       id="g3220"
+       transform="matrix(1.0035394,0,0,1,0.5745006,0)">
+      <rect
+         y="-89.447922"
+         x="-161.0468"
+         height="55.714287"
+         width="1031.1713"
+         id="rect3240"
+         style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.50000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <text
+         id="text3264"
+         y="-51.771908"
+         x="757.85767"
+         style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         xml:space="preserve"><tspan
+           id="tspan3266"
+           y="-51.771908"
+           x="757.85767"
+           sodipodi:role="line">header</tspan></text>
+    </g>
+    <rect
+       style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.775;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3270"
+       width="167.87744"
+       height="707.71222"
+       x="-160.02441"
+       y="-24.671618" />
+    <g
+       id="g2434"
+       transform="matrix(0.975467,0,0,1,0.6942419,-3.6587365)">
+      <rect
+         y="35.365849"
+         x="29.548275"
+         height="55.714287"
+         width="842.59979"
+         id="rect3279"
+         style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <text
+         id="text3281"
+         y="72.885193"
+         x="681.65283"
+         style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         xml:space="preserve"><tspan
+           id="tspan3283"
+           y="72.885193"
+           x="681.65283"
+           sodipodi:role="line">contentheader</tspan></text>
+    </g>
+    <g
+       id="g3170"
+       transform="matrix(1.0023324,0,0,1,-2.0421673,-10.976211)">
+      <rect
+         y="698.6355"
+         x="-158.28485"
+         height="55.714287"
+         width="1032.5997"
+         id="rect3285"
+         style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <text
+         id="text3287"
+         y="736.52045"
+         x="770.28204"
+         style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         xml:space="preserve"><tspan
+           id="tspan3289"
+           y="736.52045"
+           x="770.28204"
+           sodipodi:role="line">footer</tspan></text>
+    </g>
+    <g
+       id="g3211" />
+    <g
+       id="g3215"
+       transform="matrix(0.9712065,0,0,1,0.7659296,-17.074106)">
+      <rect
+         style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="rect3291"
+         width="844.62012"
+         height="55.714287"
+         x="27.850754"
+         y="629.88562" />
+      <text
+         id="text3293"
+         y="666.60339"
+         x="692.85773"
+         style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         xml:space="preserve"><tspan
+           id="tspan3295"
+           y="666.60339"
+           x="692.85773"
+           sodipodi:role="line">contentfooter</tspan></text>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:23.38711166px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="-143.67273"
+       y="20.58094"
+       id="text3297"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan2432"
+         x="-143.67273"
+         y="20.58094">left column</tspan></text>
+    <text
+       transform="scale(0.9876573,1.0124969)"
+       id="text3175"
+       y="12.071429"
+       x="721.0575"
+       style="font-size:23.09845161px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         id="tspan3177"
+         y="12.071429"
+         x="721.0575"
+         sodipodi:role="line">contentcol</tspan></text>
+    <text
+       transform="scale(0.9876573,1.0124969)"
+       id="text3179"
+       y="126.27104"
+       x="701.45959"
+       style="font-size:23.09845161px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         id="tspan3181"
+         y="126.27104"
+         x="701.45959"
+         sodipodi:role="line">contentmain</tspan></text>
+  </g>
+</svg>
Binary file doc/book/en/images/primaryview_template.png has changed
--- a/doc/book/en/images/primaryview_template.svg	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/images/primaryview_template.svg	Thu Apr 15 12:48:40 2010 +0200
@@ -36,16 +36,16 @@
      borderopacity="1.0"
      inkscape:pageopacity="0.0"
      inkscape:pageshadow="2"
-     inkscape:zoom="0.49497475"
-     inkscape:cx="432.61573"
-     inkscape:cy="370.11733"
+     inkscape:zoom="0.9357135"
+     inkscape:cx="518.32104"
+     inkscape:cy="337.0428"
      inkscape:document-units="px"
      inkscape:current-layer="layer1"
      showgrid="false"
-     inkscape:window-width="824"
-     inkscape:window-height="1094"
+     inkscape:window-width="1307"
+     inkscape:window-height="1168"
      inkscape:window-x="0"
-     inkscape:window-y="45" />
+     inkscape:window-y="0" />
   <metadata
      id="metadata7">
     <rdf:RDF>
@@ -62,193 +62,173 @@
      inkscape:groupmode="layer"
      id="layer1"
      transform="translate(162.2968,90.697922)">
+    <g
+       id="g3869"
+       transform="matrix(1,0,0,1.0373644,0,-72.039777)">
+      <rect
+         y="-15.840891"
+         x="-159.08963"
+         height="770.11017"
+         width="1033.0049"
+         id="rect3301"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.90144825;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <text
+         id="text3865"
+         y="19.784882"
+         x="-150.07172"
+         style="font-size:28.67479324px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         xml:space="preserve"><tspan
+           id="tspan3867"
+           y="19.784882"
+           x="-150.07172"
+           sodipodi:role="line">contentmain</tspan></text>
+    </g>
     <rect
-       style="fill:#ffffff;fill-rule:evenodd;stroke:#ff0000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect3301"
-       width="842.59973"
-       height="562.81085"
-       x="28.555748"
-       y="53.761448" />
-    <rect
-       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.45654476;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="rect2383"
-       width="629.62366"
-       height="54.69112"
-       x="54.112095"
-       y="73.831123" />
+       width="772.32111"
+       height="43.888428"
+       x="-131.1837"
+       y="86.559296" />
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="500.19885"
-       y="104.27108"
-       id="text2385"><tspan
+       style="font-size:16px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;line-height:125%"
+       x="-122.69418"
+       y="115.50363"
+       id="text2385"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="500.19885"
-         y="104.27108"
+         x="-122.69418"
+         y="115.50363"
          id="tspan3163">navcontenttop</tspan></text>
     <rect
-       style="fill:#ffd5d5;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="fill:#ffd5d5;fill-rule:evenodd;stroke:#000000;stroke-width:3.06523442;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="rect3167"
-       width="628.2298"
-       height="165.69759"
-       x="54.809006"
-       y="142.37053" />
+       width="770.26868"
+       height="203.16078"
+       x="-125.88269"
+       y="172.90417" />
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="311.65164"
-       y="283.88312"
-       id="text3169"><tspan
+       style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="348.26724"
+       y="205.34305"
+       id="text3169"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="311.65164"
-         y="283.88312"
-         id="tspan3171">view.render_entity_attributes()</tspan></text>
+         x="348.26724"
+         y="205.34305"
+         id="tspan3171">render_entity_attributes()</tspan></text>
     <rect
-       style="fill:#ffd5d5;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="fill:#ffd5d5;fill-rule:evenodd;stroke:#000000;stroke-width:3.06523442;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="rect3173"
-       width="627.95807"
-       height="193.9873"
-       x="56.373432"
-       y="320.51138" />
+       width="769.93549"
+       height="237.84663"
+       x="-125.03326"
+       y="391.32156" />
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="320.29282"
-       y="488.45456"
-       id="text3175"><tspan
+       style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="360.99954"
+       y="428.38055"
+       id="text3175"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="320.29282"
-         y="488.45456"
-         id="tspan3177">view.render_entity_relations()</tspan></text>
+         x="360.99954"
+         y="428.38055"
+         id="tspan3177">render_entity_relations()</tspan></text>
     <rect
-       style="fill:#ffd5d5;fill-rule:evenodd;stroke:#000000;stroke-width:1.76090598;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="fill:#ffd5d5;fill-rule:evenodd;stroke:#000000;stroke-width:2.15903592;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="rect3185"
-       width="145.94266"
-       height="499.44452"
-       x="702.43958"
-       y="70.384262" />
+       width="178.93939"
+       height="612.36584"
+       x="667.10443"
+       y="84.64225" />
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="74.177475"
-       y="-823.00977"
+       style="font-size:22px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;line-height:125%"
+       x="105.32364"
+       y="-810.65997"
        id="text3187"
-       transform="matrix(0,1,-1,0,0,0)"><tspan
+       transform="matrix(0,1,-1,0,0,0)"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="74.177475"
-         y="-823.00977"
-         id="tspan3189">view.render_side_boxes()</tspan></text>
+         id="tspan2408">render_side_boxes()</tspan></text>
     <rect
-       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:2.50000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:3.0652349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
        id="rect3191"
-       width="629.62366"
-       height="45.386246"
-       x="54.112095"
-       y="524.98816" />
+       width="771.97766"
+       height="55.647793"
+       x="-127.80586"
+       y="642.0293" />
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="456.07504"
-       y="561.66559"
-       id="text3181"><tspan
+       style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="-121.22153"
+       y="674.1748"
+       id="text3181"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="456.07504"
-         y="561.66559"
+         x="-121.22153"
+         y="674.1748"
          id="tspan3183">navcontentbottom</tspan></text>
     <rect
-       style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.50000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect3240"
-       width="1031.1713"
-       height="55.714287"
-       x="-161.0468"
-       y="-89.447922" />
+       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.68198514;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3881"
+       width="986.90503"
+       height="45.800392"
+       x="-128.34428"
+       y="-31.574066" />
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="757.85767"
-       y="-51.771908"
-       id="text3264"><tspan
+       style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="355.60541"
+       y="-2.7424495"
+       id="text3883"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="757.85767"
-         y="-51.771908"
-         id="tspan3266">header</tspan></text>
+         x="355.60541"
+         y="-2.7424495"
+         id="tspan3885">render_entity_toolbox(), render_entity_title()</tspan></text>
     <rect
-       style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.76090598;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect3270"
-       width="167.89117"
-       height="696.74976"
-       x="-160.03128"
-       y="-13.70227" />
-    <rect
-       style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect3279"
-       width="842.59979"
-       height="55.714287"
-       x="28.328695"
-       y="-13.41731" />
+       style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.68198514;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3890"
+       width="986.90503"
+       height="45.800392"
+       x="-128.87863"
+       y="19.723684" />
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="668.23749"
-       y="25.321617"
-       id="text3281"><tspan
+       style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="565.71027"
+       y="50.135612"
+       id="text3892"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="668.23749"
-         y="25.321617"
-         id="tspan3283">contentheader</tspan></text>
-    <rect
-       style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect3285"
-       width="1032.5997"
-       height="55.714287"
-       x="-159.50443"
-       y="697.41589" />
+         x="565.71027"
+         y="50.135612"
+         id="tspan3894">render_entity_summary()</tspan></text>
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="770.28204"
-       y="736.52045"
-       id="text3287"><tspan
+       style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="87.154541"
+       y="114.2578"
+       id="text3899"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="770.28204"
-         y="736.52045"
-         id="tspan3289">footer</tspan></text>
-    <rect
-       style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
-       id="rect3291"
-       width="844.62012"
-       height="55.714287"
-       x="27.850754"
-       y="627.44647" />
+         id="tspan3903"
+         x="87.154541"
+         y="114.2578">content_navigation_components('navcontenttop')</tspan></text>
     <text
        xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="680.66193"
-       y="669.04254"
-       id="text3293"><tspan
+       style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
+       x="88.46772"
+       y="675.71582"
+       id="text2410"
+       sodipodi:linespacing="125%"><tspan
          sodipodi:role="line"
-         x="680.66193"
-         y="669.04254"
-         id="tspan3295">contentfooter</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="-130.25735"
-       y="24.239677"
-       id="text3297"><tspan
-         sodipodi:role="line"
-         x="-130.25735"
-         y="24.239677"
-         id="tspan3299">leftcolumn</tspan></text>
-    <text
-       xml:space="preserve"
-       style="font-size:23.38711166px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="373.18518"
-       y="610.24188"
-       id="text3351"><tspan
-         sodipodi:role="line"
-         x="373.18518"
-         y="610.24188"
-         id="tspan3353">view.render()</tspan></text>
+         id="tspan2412"
+         x="88.46772"
+         y="675.71582">content_navigation_components('navcontenttop')</tspan></text>
   </g>
 </svg>
--- a/doc/book/en/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -44,18 +44,25 @@
 =================
 
 .. toctree::
+   :maxdepth: 2
+
+   intro/index
+   tutorials/index
+
+.. toctree::
    :maxdepth: 3
 
-   intro/index
    development/index
+
+.. toctree::
+   :maxdepth: 2
+
    admin/index
    annexes/index
 
 See also:
 
-* the complete :ref:`TOC`,
 * the :ref:`genindex`,
 * the :ref:`modindex`,
-* and the :ref:`search`.
 
 .. |cubicweb| replace:: *CubicWeb*
--- a/doc/book/en/intro/book-map.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Book map
-========
-
-[XXX WRITE ME]
-
-* explain how to use this book and what chapters to read in what order depending on the
-  objectives of the reader
-
--- a/doc/book/en/intro/concepts.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/intro/concepts.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -59,7 +59,7 @@
 repository. For applications that support high traffic, several web (front-end)
 and data (back-end) instances can be set-up to share the load.
 
-.. image:: ../../images/archi_globale.en.png
+.. image:: ../images/archi_globale.en.png
 
 The command :command:`cubicweb-ctl list` also displays the list of instances
 installed on your system.
--- a/doc/book/en/intro/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ b/doc/book/en/intro/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -2,9 +2,9 @@
 
 .. _Part1:
 
------------------------------------
-Part I - Introduction to *CubicWeb*
------------------------------------
+--------------------------
+Introduction to *CubicWeb*
+--------------------------
 
 This first part of the book offers different reading path to
 discover the *CubicWeb* framework, provides a tutorial to get a quick
@@ -15,7 +15,5 @@
    :maxdepth: 2
    :numbered:
 
-   book-map
    history
    concepts.rst
-   tutorial/index
--- a/doc/book/en/intro/tutorial/blog-in-five-minutes.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _BlogFiveMinutes:
-
-Get a blog running in five minutes!
------------------------------------
-
-For Debian or Ubuntu users, first install the following packages (:ref:`DebianInstallation`)::
-
-    cubicweb, cubicweb-dev, cubicweb-blog
-
-For Windows or Mac OS X users, you must install cubicweb from source (see :ref:`SourceInstallation` and  :ref:`WindowsInstallation`).
-
-Then create and initialize your instance::
-
-    cubicweb-ctl create blog myblog
-
-And start it::
-
-    cubicweb-ctl start -D myblog
-
-The -D option is the debugging mode of cubicweb, removing it will lauch the instance in the background.
-
-Permission
-~~~~~~~~~~
-
-This command assumes that you have root access to the /etc/ path. In order to initialize your instance as a `user` (from scratch), please check your current PYTHONPATH then create the ~/etc/cubicweb.d directory.
-
-Instance parameters
-~~~~~~~~~~~~~~~~~~~
-
-If the database installation failed, you'd like to change some instance parameters, for example, the database host or the user name. These informations can be edited in the `source` file located in the /etc/cubicweb.d/myblog directory.
-
-Then relaunch the database creation:
-
-     cubicweb-ctl db-create myblog
-
-Other paramaters, like web server or emails parameters, can be modified in the `all-in-one.conf` file.
-
-This is it. Your blog is running. Visit http://localhost:8080 and enjoy it! This blog is fully functionnal. The next section section will present the way to develop new cubes and customizing the look of your instance.
-
-
--- a/doc/book/en/intro/tutorial/components.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _cubes:
-
-Cubes
------
-
-Standard library
-~~~~~~~~~~~~~~~~
-
-A library of standard cubes are available from `CubicWeb Forge`_
-Cubes provide entities and views.
-
-The available application entities in standard cubes are:
-
-* addressbook: PhoneNumber and PostalAddress
-
-* basket: Basket (like a shopping cart)
-
-* blog: Blog (a *very* basic blog)
-
-* classfolder: Folder (to organize things but grouping them in folders)
-
-* classtags: Tag (to tag anything)
-
-* comment: Comment (to attach comment threads to entities)
-
-* file: File (to allow users to upload and store binary or text files)
-
-* link: Link (to collect links to web resources)
-
-* mailinglist: MailingList (to reference a mailing-list and the URLs
-  for its archives and its admin interface)
-
-* person: Person (easily mixed with addressbook)
-
-* task: Task (something to be done between start and stop date)
-
-* zone: Zone (to define places within larger places, for example a
-  city in a state in a country)
-
-.. _`CubicWeb Forge`: http://www.cubicweb.org/project/
-
-Adding comments to BlogDemo
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To import a cube in your instance just change the line in the
-``__pkginfo__.py`` file and verify that the cube you are planning
-to use is listed by the command ``cubicweb-ctl list``.
-For example::
-
-    __use__ = ('comment',)
-
-will make the ``Comment`` entity available in your ``BlogDemo``
-cube.
-
-Change the schema to add a relationship between ``BlogEntry`` and
-``Comment`` and you are done. Since the comment cube defines the
-``comments`` relationship, adding the line::
-
-    comments = ObjectRelation('Comment', cardinality='1*', composite='object')
-
-to the definition of a ``BlogEntry`` will be enough.
-
-Synchronize the data model
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Once you modified your data model, you need to synchronize the
-database with your model. For this purpose, *CubicWeb* provides
-a very useful command ``cubicweb-ctl shell blogdemo`` which
-launches an interactive shell where you can enter migration
-commands (see :ref:`cubicweb-ctl` for more details)).
-As you added the cube named `comment`, you need to run:
-
-::
-
-  add_cube('comment')
-
-You can now start your instance and comment your blog entries.
--- a/doc/book/en/intro/tutorial/conclusion.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-What's next?
-------------
-
-We demonstrated how from a straight out of the box *CubicWeb* installation, you
-can build your web application based on a data model. It's all already there:
-views, templates, permissions, etc. The step forward is now for you to customize
-according to your needs.
-
-Many features are available to extend your application, for example: RSS channel
-integration (:ref:`XmlAndRss`), hooks (:ref:`hooks`), support of sources such as
-Google App Engine (:ref:`GoogleAppEngineSource`) and lots of others to discover
-through our book.
-
--- a/doc/book/en/intro/tutorial/create-cube.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,430 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-.. _Steps:
-
-Steps for creating your cube
-----------------------------
-
-The following steps will help you to create and customize a new cube.
-
-1. :ref:`CreateYourCube`
-
-Create the directory to hold the code of your cube. The most important files that will be useful to customize your newly created cube are:
-  * schema.py: contains the data model
-  * views.py: contains your custom views
-  * entities.py: contains XXX 
-
-The detailed structure of the code directory is described in :ref:`cubelayout`.
-
-2. :ref:`DefineDataModel`
-
-Define the data model of your application.
-
-3. :ref:`ExploreYourInstance`
-
-Create, run, and explore an instance of your cube.
-
-4. :ref:`DefineViews`
-
-Customize the views of your data: how and which part of your data are showed. 
-
-Note: views don't concern the look'n'feel or design of the site. For that, you should use CSS instead, and default CSS or your new cube are located in 'blog/data/'.
-
-
-5. :ref:`DefineEntities`
-
-Define your own entities to add useful functions when you manipulate your data, especially when you write view.
-
-
-.. _CreateYourCube:
-
-Create your cube
-----------------
-
-The packages ``cubicweb`` and ``cubicweb-dev`` install a command line
-tool for *CubicWeb* called ``cubicweb-ctl``. This tool provides a wide
-range of commands described in details in :ref:`cubicweb-ctl`.
-
-Once your *CubicWeb* development environment is set up, you can create
-a new cube::
-
-  cubicweb-ctl newcube blog
-
-This will create in the cubes directory (``/path/to/forest/cubes`` for Mercurial
-installation, ``/usr/share/cubicweb/cubes`` for debian packages installation)
-a directory named ``blog`` reflecting the structure described in :ref:`Concepts`.
-
-
-For packages installation, you can still create new cubes in your home directory using the following configuration. Let's say you want to develop your new cubes in `~src/cubes`, then set the following environment variables:
-::
-
-  CW_CUBES_PATH=~/src/cubes
-  CW_MODE=user
-
-and then create your new cube using:
-::
-
-  cubicweb-ctl newcube --directory=~/src/cubes blog
-
-
-
-
-
-
-.. _DefineDataModel:
-
-Define your data model
-----------------------
-
-The data model or schema is the core of your *CubicWeb* application.
-It defines the type of content your application will handle.
-
-The data model of your cube ``blog`` is defined in the file ``schema.py``:
-
-.. sourcecode:: python
-
-  from yams.buildobjs import EntityType, String, SubjectRelation, Date
-
-  class Blog(EntityType):
-    title = String(maxsize=50, required=True)
-    description = String()
-
-  class BlogEntry(EntityType):
-    title = String(required=True, fulltextindexed=True, maxsize=256)
-    publish_date = Date(default='TODAY')
-    content = String(required=True, fulltextindexed=True)
-    entry_of = SubjectRelation('Blog', cardinality='?*')
-
-The first step is the import of the EntityType (generic class for entity and 
-attributes that will be used in both Blog and BlogEntry entities. 
-
-A Blog has a title and a description. The title is a string that is
-required and must be less than 50 characters.  The
-description is a string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a content. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The content is a string that will be indexed in
-the database full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that links it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-
-.. _ExploreYourInstance:
-
-Create and explore your instance
---------------------------------
-.. _CreateYourInstance:
-
-Create your instance
-~~~~~~~~~~~~~~~~~~~~
-
-To use this cube as an instance and create a new instance named ``blogdemo``, do::
-
-  cubicweb-ctl create blog blogdemo
-
-This command will create the corresponding database and initialize it.
-
-
-.. _WelcomeToYourWebInstance:
-
-Welcome to your web instance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Start your instance in debug mode with the following command: ::
-
-  cubicweb-ctl start -D blogdemo
-
-
-You can now access your web instance to create blogs and post messages
-by visiting the URL http://localhost:8080/.
-
-A login form will appear. By default, the instance will not allow anonymous
-users to enter the instance. To login, you need then use the admin account
-you created at the time you initialized the database with ``cubicweb-ctl
-create``.
-
-.. image:: ../../images/login-form.png
-
-
-Once authenticated, you can start playing with your instance
-and create entities.
-
-.. image:: ../../images/blog-demo-first-page.png
-
-Please notice that so far, the *CubicWeb* framework managed all aspects of
-the web application based on the schema provided at the beginning.
-
-.. _AddEntities:
-
-Add entities
-~~~~~~~~~~~~
-
-We will now add entities in our web application.
-
-Add a Blog
-**********
-
-Let us create a few of these entities. Click on the `[+]` at the left of the
-link Blog on the home page. Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the form by
-clicking on ``Validate``.
-
-.. image:: ../../images/cbw-create-blog.en.png
-   :alt: from to create blog
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link that will list for you all the existing Blog.
-You should be seeing a list with a single item ``Tech-blog`` you
-just created.
-
-.. image:: ../../images/cbw-list-one-blog.en.png
-   :alt: displaying a list of a single blog
-
-Clicking on this item will get you to its detailed description except
-that in this case, there is not much to display besides the name and
-the phrase ``everything about technology``.
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-.. image:: ../../images/cbw-list-two-blog.en.png
-   :alt: displaying a list of two blogs
-
-Add a BlogEntry
-***************
-
-Get back to the home page and click on [+] at the left of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``Validate``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``.
-
-You could also have, at the time you started to fill the form for a
-new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
-combobox titled ``add relation`` would have showed up.
-
-
-.. image:: ../../images/cbw-add-relation-entryof.en.png
-   :alt: editing a blog entry to add a relation to a blog
-
-Validate the changes by clicking ``Validate``. The entity BlogEntry
-that is displayed now includes a link to the entity Blog named
-``MyLife``.
-
-.. image:: ../../images/cbw-detail-one-blogentry.en.png
-   :alt: displaying the detailed view of a blogentry
-
-Note that all of this was handled by the framework and that the only input
-that was provided so far is the schema. To get a graphical view of the schema,
-point your browser to the URL http://localhost:8080/schema
-
-.. image:: ../../images/cbw-schema.en.png
-   :alt: graphical view of the schema (aka data-model)
-
-
-.. _DefineViews:
-
-Define your entity views
-------------------------
-
-Each entity defined in a model is associated with default views
-allowing different rendering of the data. You can redefine each of
-them according to your needs and preferences. So let's see how the
-views are defined.
-
-
-The view selection principle
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A view is defined by a Python class which includes:
-
-  - an identifier (all objects in *CubicWeb* are recorded in a
-    registry and this identifier will be used as a key)
-
-  - a filter to select the result sets it can be applied to
-
-A view has a set of methods complying with the `View` class interface
-(`cubicweb.common.view`).
-
-*CubicWeb* provides a lot of standard views for the type `EntityView`;
-for a complete list, read the code in directory ``cubicweb/web/views/``.
-
-A view is applied on a `result set` which contains a set of entities
-we are trying to display. *CubicWeb* uses a selector mechanism which
-computes for each available view a score: the view with the highest
-score is then used to display the given `result set`.  The standard
-library of selectors is in ``cubicweb.selector``.
-
-It is possible to define multiple views for the same identifier
-and to associate selectors and filters to allow the application
-to find the most appropriate way to render the data.
-
-For example, the view named ``primary`` is the one used to display a
-single entity. We will now show you how to create a primary view for
-BlogEntry.
-
-
-Primary view customization
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you wish to modify the way a `BlogEntry` is rendered, you will have
-to subclass the `primary` view, for instance in the module ``views``
-of the cube ``cubes/blog/views.py``.
-
-The standard primary view is the most sophisticated view of all. It
-has more than a call() method. It is a template. Actually the entry
-point calls the following sequence of (redefinable) methods:
-
- * render_entity_title
-
- * render_entity_metadata
-
- * render_entity_attributes
-
- * render_entity_relations
-
- * render_side_boxes
-
-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`.
-
-We can for example add in front of the publication date a prefix
-specifying that the date we see is the publication date.
-
-To do so, please apply the following changes:
-
-.. sourcecode:: python
-
-  from cubicweb.selectors import implements
-  from cubicweb.web.views import primary
-
-  class BlogEntryPrimaryView(primary.PrimaryView):
-      __select__ = implements('BlogEntry')
-
-      def render_entity_attributes(self, entity):
-          self.w(u'<p>published on %s</p>' %
-                 entity.publish_date.strftime('%Y-%m-%d'))
-          super(BlogEntryPrimaryView, self).render_entity_attributes(entity)
-
-.. note::
-  When a view is modified, it is not required to restart the instance
-  server. Save the Python file and reload the page in your web browser
-  to view the changes.
-
-You can now see that the publication date has a prefix.
-
-.. image:: ../../images/cbw-update-primary-view.en.png
-   :alt: modified primary view
-
-
-The above source code defines a new primary view for ``BlogEntry``.
-
-Since views are applied to result sets and result sets can be tables of
-data, we have to recover the entity from its (row,col)-coordinates.
-The view has a ``self.w()`` method that is used to output data, in our
-example HTML output.
-
-.. note::
-   You can find more details about views and selectors in :ref:`Views`.
-
-
-.. _DefineEntities:
-
-Write entities to add logic in your data
-----------------------------------------
-
-By default, CubicWeb provides a default entity for each data type defined in the schema. 
-A default entity mainly contains the attributes defined in the data model. 
-
-You can redefine each entity to provide additional functions to help you write your views. 
-
-.. sourcecode:: python
-
-    from cubicweb.entities import AnyEntity
-
-    class BlogEntry(AnyEntity):
-        """customized class for BlogEntry entities"""
-    	__regid__ = 'BlogEntry'
-    	__implements__ = AnyEntity.__implements__ 
-
-        def display_cw_logo(self):
-            if 'CW' in self.title:
-                return True
-            else:	
-                return False
-
-Customizing an entity requires that your entity:
- - inherits from ``cubicweb.entities`` or any subclass
- - defines a ``__regid__`` linked to the corresponding data type of your schema
- - implements the base class by explicitly using ``__implements__``.
-
-We implemented here a function ``display_cw_logo`` which tests if the blog entry title contains 'CW'.
-This function can then be used when you customize your views. For instance, you can modify your previous ``views.py`` as follows:
-
-.. sourcecode:: python
-
- class BlogEntryPrimaryView(primary.PrimaryView):
-     __select__ = implements('BlogEntry')
-
-     ...
-
-     def render_entity_title(self, entity):
-	 if entity.display_cw_logo():
-	     self.w(u'<image src="http://www.cubicweb.org/doc/en/_static/cubicweb.png"/>')
-	 super(BlogEntryPrimaryView, self).render_entity_title(entity)
-
-Then each blog entry whose title contains 'CW' is shown with the CubicWeb logo in front of it.
-
-.. _UpdatingSchemaAndSynchronisingInstance:
-
-Updating the schema and synchronising the instance
---------------------------------------------------
-
-While developping your cube, you may want to update your data model. Let's say you
-want to add a ``category`` attribute in the ``Blog`` data type. This is called a migration.
-
-The required steps are:
-1. modify the file ``schema.py``. The ``Blog`` class looks now like this:
-
-.. sourcecode:: python
-
- class Blog(EntityType):
-   title = String(maxsize=50, required=True)
-   description = String()
-   category = String(required=True, vocabulary=(_('Professional'), _('Personal')), default='Personal')
-
-2. stop your ``blogdemo`` instance
-
-3. start the cubicweb shell for your instance by running the following command:
-
-.. sourcecode:: bash
-
-  cubicweb-ctl shell blogdemo
-
-4. in the shell, execute:
-
-.. sourcecode:: python
-
- add_attribute('Blog', 'category')
-
-5. you can restart your instance, modify a blog entity and check that the new attribute 
-``category`` has been added.
-
-Of course, you may also want to add relations, entity types, ... See :ref:`migration`
-for a list of all available migration commands.
-
--- a/doc/book/en/intro/tutorial/index.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Tutorial:
-
-Tutorial
-========
-
-*CubicWeb* is a semantic web application framework that favors reuse and
-object-oriented design.
-
-A `cube` is a component that includes a model defining the data types and a set of
-views to display the data. A cube can be built by assembling other cubes.
-
-An `instance` is a specific installation of a cube and includes configuration
-files.
-
-
-This tutorial will show how to create a `cube` and how to use it as an
-application to run an `instance`.
-
-.. toctree::
-   :maxdepth: 2
-
-   blog-in-five-minutes
-   create-cube
-   components
-   maintemplate
-   conclusion
--- a/doc/book/en/intro/tutorial/maintemplate.rst	Thu Apr 15 12:47:02 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Templates
----------
-
-Look at ``cubicweb/web/views/basetemplates.py`` and you will
-find the base templates used to generate HTML for your application.
-
-A page is composed as indicated on the schema below:
-
-.. image:: ../../images/lax-book.06-main-template-layout.en.png
-
-In this section we will demonstrate a change in one of the main
-interesting template from the three you will look for,
-that is to say, the HTMLPageHeader, the HTMLPageFooter
-and the TheMainTemplate.
-
-
-Customize a template
-~~~~~~~~~~~~~~~~~~~~
-
-Based on the diagram below, each template can be overriden
-by your customized template. To do so, we recommand you create
-a Python module ``blog.views.templates`` to keep it organized.
-In this module you will have to import the parent class you are
-interested as follows: ::
-
-  from cubicweb.web.views.basetemplates import HTMLPageHeader, \
-                                    HTMLPageFooter, TheMainTemplate
-
-and then create your sub-class::
-
-  class MyBlogHTMLPageHeader(HTMLPageHeader):
-      ...
-
-Customize header
-`````````````````
-
-Let's now move the search box in the header and remove the login form from the
-header. We'll show how to move it to the left column of the user interface.
-
-Let's say we do not want anymore the login menu to be in the header
-
-First, to remove the login menu, we just need to comment out the display of the
-login graphic component such as follows:
-
-.. sourcecode:: python
-
-  class MyBlogHTMLPageHeader(HTMLPageHeader):
-
-      def main_header(self, view):
-          """build the top menu with authentification info and the rql box"""
-          self.w(u'<table id="header"><tr>\n')
-          self.w(u'<td id="firstcolumn">')
-          self._cw.vreg.select_component('logo', self._cw, self.cw_rset).dispatch(w=self.w)
-          self.w(u'</td>\n')
-          # appliname and breadcrumbs
-          self.w(u'<td id="headtext">')
-          comp = self._cw.vreg.select_component('appliname', self._cw, self.cw_rset)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w)
-          comp = self._cw.vreg.select_component('breadcrumbs', self._cw, self.cw_rset, view=view)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w, view=view)
-          self.w(u'</td>')
-          # logged user and help
-          #self.w(u'<td>\n')
-          #comp = self._cw.vreg.select_component('loggeduserlink', self._cw, self.cw_rset)
-          #comp.dispatch(w=self.w)
-          #self.w(u'</td><td>')
-
-          self.w(u'<td>')
-          helpcomp = self._cw.vreg.select_component('help', self._cw, self.cw_rset)
-          if helpcomp: # may not be available if Card is not defined in the schema
-              helpcomp.dispatch(w=self.w)
-          self.w(u'</td>')
-          # lastcolumn
-          self.w(u'<td id="lastcolumn">')
-          self.w(u'</td>\n')
-          self.w(u'</tr></table>\n')
-          self.template('logform', rset=self.cw_rset, id='popupLoginBox', klass='hidden',
-                        title=False, message=False)
-
-
-
-.. image:: ../../images/lax-book.06-header-no-login.en.png
-
-Customize footer
-````````````````
-
-If you want to change the footer for example, look
-for HTMLPageFooter and override it in your views file as in:
-
-.. sourcecode:: python
-
-  from cubicweb.web.views.basetemplates import HTMLPageFooter
-
-  class MyHTMLPageFooter(HTMLPageFooter):
-
-      def call(self, **kwargs):
-          self.w(u'<div class="footer">')
-          self.w(u'This website has been created with <a href="http://cubicweb.org">CubicWeb</a>.')
-          self.w(u'</div>')
-
-Updating a view does not require any restart of the server. By reloading
-the page you can see your new page footer.
-
-
-TheMainTemplate
-```````````````
-
-.. _TheMainTemplate:
-
-The MainTemplate is a bit complex as it tries to accomodate many
-different cases. We are now about to go through it and cutomize entirely
-our application.
-
-TheMainTemplate is responsible for the general layout of the entire application.
-It defines the template of ``__regid__ = main`` that is used by the application. Is
-also defined in ``cubicweb/web/views/basetemplates.py`` another template that can
-be used based on TheMainTemplate called SimpleMainTemplate which does not have
-a top section.
-
-.. image:: ../../images/lax-book.06-simple-main-template.en.png
-
-XXX
-[WRITE ME]
-
-* customize MainTemplate and show that everything in the user
-  interface can be changed
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/standard_theme/layout.html	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,13 @@
+{% extends "basic/layout.html" %}
+
+{% block header %}
+<div class="header">
+ <a href="http://www.cubicweb.org">
+  <img alt="cubicweb logo" src="{{ pathto('_static/cubicweb.png', 1) }}"/>
+ </a>
+</div>
+{% endblock %}
+
+{# puts the sidebar into "sidebar1" block i.e. before the document body #}
+{% block sidebar1 %}{{ sidebar() }}{% endblock %}
+{% block sidebar2 %}{% endblock %}
Binary file doc/book/en/standard_theme/static/contents.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/standard_theme/static/lglb-sphinx-doc.css	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,376 @@
+/**
+ * Sphinx stylesheet -- Logilab theme
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Inspired from sphinxdoc original theme.
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
+                 'Verdana', sans-serif;
+    font-size: 14px;
+    letter-spacing: -0.01em;
+    line-height: 150%;
+    text-align: center;
+    background-color: #D0D0D0;
+    color: #000000;
+    padding: 0;
+    border: 1px solid #CCBCA7;
+    min-width: 640px;
+    margin: 0px 30px 0px 30px;
+}
+
+div.document {
+    background-color: #FFFFFF;
+    text-align: left;
+    background-image: url(contents.png);
+    background-repeat: repeat-x;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+    border-left: 1px solid #CCBCA7;
+}
+
+div.body {
+    margin: 0;
+    padding: 0.5em 20px 20px 20px;
+}
+
+div.header {
+    margin: 0;
+    padding: 5px 5px 25px 5px;
+    background-color: #FFFFFF;
+    text-align: left;
+    line-height: 80%;
+ }
+
+div.related {
+    font-size: 1em;
+}
+
+div.related ul {
+    background-image: url(navigation.png);
+    height: 2em;
+    border-top: 1px solid #CCBCA7;
+    border-bottom: 1px solid #CCBCA7;
+}
+
+div.related ul li {
+    margin: 0;
+    padding: 0;
+    height: 2em;
+    float: left;
+}
+
+div.related ul li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+div.related ul li a {
+    margin: 0;
+    padding: 0 5px 0 5px;
+    line-height: 1.75em;
+}
+
+div.sphinxsidebarwrapper {
+    padding: 0;
+}
+
+div.sphinxsidebar {
+    margin: 0;
+    padding: 5px 10px 5px 10px;
+    width: 210px;
+    float: left;
+    font-size: 1em;
+    text-align: left;
+}
+
+div.sphinxsidebar h3, div.sphinxsidebar h4 {
+    margin: 1em 0 0.5em 0;
+    font-size: 1em;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: white;
+    border: 1px solid #CCBCA7;
+    background-color: #909090;
+}
+
+div.sphinxsidebar h3 a {
+    color: white;
+}
+
+div.sphinxsidebar ul {
+    padding-left: 1.5em;
+    margin-top: 7px;
+    padding: 0;
+    line-height: 130%;
+    font-weight: bold;
+}
+
+div.sphinxsidebar ul ul {
+    margin-left: 20px;
+    font-weight: normal;
+}
+
+div.sphinxsidebar li {
+    margin: 0;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #CCBCA7;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+div.footer {
+    background-color: #FFFFFF;
+    color: #707070;
+    padding: 3px 8px 3px 0;
+    clear: both;
+    font-size: 0.8em;
+    text-align: right;
+}
+
+div.footer a {
+    color: #707070;
+    text-decoration: underline;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+p {
+    margin: 0.8em 0 0 0;
+}
+
+ul, ol {
+    margin: 0;
+}
+
+li {
+    margin: 0.2em 0 0 0;
+}
+
+a {
+    color: #B45300;
+    text-decoration: none;
+}
+
+a:hover {
+    color: #4BACFF;
+}
+
+div.body a {
+    text-decoration: underline;
+}
+
+h1 {
+    margin: 0;
+    padding: 0.7em 0 0.3em 0;
+    font-size: 1.5em;
+    border-bottom: 3px solid #CC8B00;
+    color: #404040;
+}
+
+h2 {
+    margin: 1.3em 0 0.2em 0;
+    font-size: 1.35em;
+    padding: 0;
+    color: #303030;
+}
+
+h3 {
+    margin: 1em 0 -0.3em 0;
+    font-size: 1.2em;
+    color: #202020;
+}
+
+div.body h1 a {
+    color: #404040!important;
+}
+
+div.body h2 a {
+    color: #303030!important;
+}
+
+div.body h3 a {
+    color: #202020!important;
+}
+
+div.body h4 a, div.body h5 a, div.body h6 a {
+    color: #000000!important;
+}
+
+h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
+    display: none;
+    margin: 0 0 0 0.3em;
+    padding: 0 0.2em 0 0.2em;
+    color: #AAA!important;
+}
+
+h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
+h5:hover a.anchor, h6:hover a.anchor {
+    display: inline;
+}
+
+h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
+h5 a.anchor:hover, h6 a.anchor:hover {
+    color: #777;
+    background-color: #EEE;
+}
+
+a.headerlink {
+    color: #C60F0F!important;
+    font-size: 1em;
+    margin-left: 6px;
+    padding: 0 4px 0 4px;
+    text-decoration: none!important;
+}
+
+a.headerlink:hover {
+    background-color: #C0C0C0;
+    color: #FFFFFF!important;
+}
+
+cite, code, tt {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.01em;
+}
+
+tt {
+    background-color: #F0F0F0;
+    border-bottom: 1px solid #D0D0D0;
+}
+
+tt.descname, tt.descclassname, tt.xref {
+    background-color: #F0F0F0;
+    font-weight: normal;
+    font-size: 1em;
+    border: 1px solid #D0D0D0;
+    border: 0;
+}
+
+hr {
+    border: 1px solid #CC8B00;
+    margin: 2em;
+}
+
+a tt {
+    border: 0;
+    color: #B45300;
+}
+
+a:hover tt {
+    color: #4BACFF;
+}
+
+pre {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.015em;
+    line-height: 120%;
+    padding: 0.5em;
+    border: 1px solid #CCBCA7;
+    background-color: #F0F0F0;
+}
+
+pre a {
+    color: inherit;
+    text-decoration: underline;
+}
+
+td.linenos pre {
+    padding: 0.5em 0;
+}
+
+div.quotebar {
+    background-color: #F8F8F8;
+    max-width: 250px;
+    float: right;
+    padding: 2px 7px;
+    border: 1px solid #C0C0C0;
+}
+
+div.topic {
+    background-color: #F8F8F8;
+}
+
+table {
+    border-collapse: collapse;
+    margin: 0.8em -0.5em 0em -0.5em;
+}
+
+table td, table th {
+    padding: 0.2em 0.5em 0.2em 0.5em;
+}
+
+div.admonition, div.warning {
+    font-size: 0.9em;
+    margin: 1em 0 1em 0;
+    padding: 0;
+}
+
+div.admonition {
+    border: 1px solid #86989B;
+    background-color: #EBEBFF;
+}
+
+div.warning {
+    border: 1px solid #940000;
+    background-color: #FFEBEB;
+}
+
+div.admonition p, div.warning p {
+    margin: 0.5em 1em 0.5em 1em;
+    padding: 0;
+}
+
+div.admonition pre, div.warning pre {
+    margin: 0.4em 1em 0.4em 1em;
+}
+
+div.admonition p.admonition-title,
+div.warning p.admonition-title {
+    margin: 0;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: #FFFFFF;
+    font-weight: bold;
+}
+
+div.admonition p.admonition-title {
+    border-bottom: 1px solid #86989B;
+    background-color: #8C88B5;
+}
+
+div.warning p.admonition-title {
+    background-color: #CF0000;
+    border-bottom: 1px solid #940000;
+}
+
+div.admonition ul, div.admonition ol,
+div.warning ul, div.warning ol {
+    margin: 0.1em 0.5em 0.5em 3em;
+    padding: 0;
+}
+
+div.versioninfo {
+    margin: 1em 0 0 0;
+    border: 1px solid #C0C0C0;
+    background-color: #DDEAF0;
+    padding: 8px;
+    line-height: 1.3em;
+    font-size: 0.9em;
+}
+
+/* TOC trees */
+
+li.toctree-l1 {
+    margin-top: 0.4em;
+ }
\ No newline at end of file
Binary file doc/book/en/standard_theme/static/logilab_logo.png has changed
Binary file doc/book/en/standard_theme/static/navigation.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/standard_theme/theme.conf	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,4 @@
+[theme]
+inherit = basic
+stylesheet = lglb-sphinx-doc.css
+pygments_style = friendly
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/advanced/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,586 @@
+.. _advanced_tutorial:
+
+Building a photo gallery with CubicWeb
+======================================
+
+Desired features
+----------------
+
+* basically a photo gallery
+
+* photo stored onto the fs and displayed dynamically through a web interface
+
+* navigation through folder (album), tags, geographical zone, people on the
+  picture... using facets
+
+* advanced security (eg not everyone can see everything). More on this later.
+
+
+Cube creation and schema definition
+-----------------------------------
+
+.. _adv_tuto_create_new_cube:
+
+Step 1: creating a new cube for my web site
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One note about my development environment: I wanted to use packaged
+version of CubicWeb and cubes while keeping my cube in my user
+directory, let's say `~src/cubes`.  I achieve this by setting the
+following environment variables::
+
+  CW_CUBES_PATH=~/src/cubes
+  CW_MODE=user
+
+I can now create the cube which will hold custom code for this web
+site using::
+
+  c-c newcube --directory=~/src/cubes sytweb
+
+
+.. _adv_tuto_assemble_cubes:
+
+Step 2: pick building blocks into existing cubes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Almost everything I want represent in my web-site is somewhat already modelized in
+some cube that I'll extend for my need. So I'll pick the following cubes:
+
+* `folder`, containing `Folder` entity type, which will be used as
+  both 'album' and a way to map file system folders. Entities are
+  added to a given folder using the `filed_under` relation.
+
+* `file`, containing `File` and `Image` entity types, gallery view,
+  and a file system import utility.
+
+* `zone`, containing the `Zone` entity type for hierarchical geographical
+  zones. Entities (including sub-zones) are added to a given zone using the
+  `situated_in` relation.
+
+* `person`, containing the `Person` entity type plus some basic views.
+
+* `comment`, providing a full commenting system allowing one to comment entity types
+  supporting the `comments` relation by adding a `Comment` entity.
+
+* `tag`, providing a full tagging system as a easy and powerful way to classify
+  entities supporting the `tags` relation by linking the to `Tag` entities. This
+  will allows navigation into a large number of picture.
+
+Ok, now I'll tell my cube requires all this by editing cubes/sytweb/__pkginfo__.py:
+
+  .. sourcecode:: python
+
+    __depends_cubes__ = {'file': '>= 1.2.0',
+			 'folder': '>= 1.1.0',
+			 'person': '>= 1.2.0',
+			 'comment': '>= 1.2.0',
+			 'tag': '>= 1.2.0',
+			 'zone': None,
+			 }
+    __depends__ = {'cubicweb': '>= 3.5.10',
+		   }
+    for key,value in __depends_cubes__.items():
+	__depends__['cubicweb-'+key] = value
+    __use__ = tuple(__depends_cubes__)
+
+Notice that you can express minimal version of the cube that should be used,
+`None` meaning whatever version available.
+
+Step 3: glue everything together in my cube's schema
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. sourcecode:: python
+
+    from yams.buildobjs import RelationDefinition
+
+    class comments(RelationDefinition):
+	subject = 'Comment'
+	object = ('File', 'Image')
+	cardinality = '1*'
+	composite = 'object'
+
+    class tags(RelationDefinition):
+	subject = 'Tag'
+	object = ('File', 'Image')
+
+    class filed_under(RelationDefinition):
+	subject = ('File', 'Image')
+	object = 'Folder'
+
+    class situated_in(RelationDefinition):
+	subject = 'Image'
+	object = 'Zone'
+
+    class displayed_on(RelationDefinition):
+	subject = 'Person'
+	object = 'Image'
+
+
+This schema:
+
+* allows to comment and tag on `File` and `Image` entity types by adding the
+  `comments` and `tags` relations. This should be all we've to do for this
+  feature since the related cubes provide 'pluggable section' which are
+  automatically displayed on the primary view of entity types supporting the
+  relation.
+
+* adds a `situated_in` relation definition so that image entities can be
+  geolocalized.
+
+* add a new relation `displayed_on` relation telling who can be seen on a
+  picture.
+
+This schema will probably have to evolve as time goes (for security handling at
+least), but since the possibility to make schema evolving is one of CubicWeb
+feature (and goal), we won't worry and see that later when needed.
+
+
+Step 4: creating the instance
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now that I've a schema, I want to create an instance so I can start To
+create an instance using this new 'sytweb' cube, I run::
+
+  c-c create sytweb sytweb_instance
+
+hint : if you get an error while the database is initialized, you can
+avoid having to reanswer to questions by runing ::
+
+   c-c db-create sytweb_instance
+
+This will use your already configured instance and start directly from the create
+database step, thus skipping questions asked by the 'create' command.
+
+Once the instance and database are fully initialized, run ::
+
+  c-c start sytweb_instance
+
+to start the instance, check you can connect on it, etc...
+
+
+Security, testing and migration
+-------------------------------
+
+This post will cover various topics:
+
+* configuring security
+* migrating existing instance
+* writing some unit tests
+
+Here is the ``read`` security model I want:
+
+* folders, files, images and comments should have one of the following visibility:
+  - ``public``, everyone can see it
+  - ``authenticated``, only authenticated users can see it
+  - ``restricted``, only a subset of authenticated users can see it
+* managers (e.g. me) can see everything
+* only authenticated user can see people
+* everyone can  see classifier entities, eg tag and zone
+
+Also, unless explicity specified, visibility of an image should be the same as
+its parent folder, as well as visibility of a comment should be the same as the
+commented entity. If there is no parent entity, the default visibility is
+``authenticated``.
+
+Regarding write security, that's much easier:
+* anonymous can't write anything
+* authenticated users can only add comment
+* managers will add the remaining stuff
+
+Now, let's implement that!
+
+Proper security in CubicWeb is done at the schema level, so you don't have to
+bother with it in views: users will only see what they can see automatically.
+
+.. _adv_tuto_security:
+
+Step 1: configuring security into the schema
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In schema, you can grant access according to groups, or to some RQL expressions:
+users get access it the expression return some results. To implements the read
+security defined earlier, groups are not enough, we'll need RQL expression. Here
+is the idea:
+
+* add a `visibility` attribute on folder, image and comment, which may be one of
+  the value explained above
+
+* add a `may_be_read_by` relation from folder, image and comment to users,
+  which will define who can see the entity
+
+* security propagation will be done in hook.
+
+So the first thing to do is to modify my cube'schema.py to define those
+relations:
+
+.. sourcecode:: python
+
+    from yams.constraints import StaticVocabularyConstraint
+
+    class visibility(RelationDefinition):
+	subject = ('Folder', 'File', 'Image', 'Comment')
+	object = 'String'
+	constraints = [StaticVocabularyConstraint(('public', 'authenticated',
+						   'restricted', 'parent'))]
+	default = 'parent'
+	cardinality = '11' # required
+
+    class may_be_read_by(RelationDefinition):
+	subject = ('Folder', 'File', 'Image', 'Comment',)
+	object = 'CWUser'
+
+We can note the following points:
+
+* we've added a new `visibility` attribute to folder, file, image and comment
+  using a `RelationDefinition`
+
+* `cardinality = '11'` means this attribute is required. This is usually hidden
+  under the `required` argument given to the `String` constructor, but we can
+  rely on this here (same thing for StaticVocabularyConstraint, which is usually
+  hidden by the `vocabulary` argument)
+
+* the `parent` possible value will be used for visibility propagation
+
+Now, we should be able to define security rules in the schema, based on these new
+attribute and relation. Here is the code to add to *schema.py*:
+
+.. sourcecode:: python
+
+    from cubicweb.schema import ERQLExpression
+
+    VISIBILITY_PERMISSIONS = {
+	'read':   ('managers',
+		   ERQLExpression('X visibility "public"'),
+		   ERQLExpression('X may_be_read_by U')),
+	'add':    ('managers',),
+	'update': ('managers', 'owners',),
+	'delete': ('managers', 'owners'),
+	}
+    AUTH_ONLY_PERMISSIONS = {
+	    'read':   ('managers', 'users'),
+	    'add':    ('managers',),
+	    'update': ('managers', 'owners',),
+	    'delete': ('managers', 'owners'),
+	    }
+    CLASSIFIERS_PERMISSIONS = {
+	    'read':   ('managers', 'users', 'guests'),
+	    'add':    ('managers',),
+	    'update': ('managers', 'owners',),
+	    'delete': ('managers', 'owners'),
+	    }
+
+    from cubes.folder.schema import Folder
+    from cubes.file.schema import File, Image
+    from cubes.comment.schema import Comment
+    from cubes.person.schema import Person
+    from cubes.zone.schema import Zone
+    from cubes.tag.schema import Tag
+
+    Folder.__permissions__ = VISIBILITY_PERMISSIONS
+    File.__permissions__ = VISIBILITY_PERMISSIONS
+    Image.__permissions__ = VISIBILITY_PERMISSIONS
+    Comment.__permissions__ = VISIBILITY_PERMISSIONS.copy()
+    Comment.__permissions__['add'] = ('managers', 'users',)
+    Person.__permissions__ = AUTH_ONLY_PERMISSIONS
+    Zone.__permissions__ = CLASSIFIERS_PERMISSIONS
+    Tag.__permissions__ = CLASSIFIERS_PERMISSIONS
+
+What's important in there:
+
+* `VISIBILITY_PERMISSIONS` provides read access to managers group, if
+  `visibility` attribute's value is 'public', or if user (designed by the 'U'
+  variable in the expression) is linked to the entity (the 'X' variable) through
+  the `may_read` permission
+
+* we modify permissions of the entity types we use by importing them and
+  modifying their `__permissions__` attribute
+
+* notice the `.copy()`: we only want to modify 'add' permission for `Comment`,
+  not for all entity types using `VISIBILITY_PERMISSIONS`!
+
+* the remaining part of the security model is done using regular groups:
+
+  - `users` is the group to which all authenticated users will belong
+  - `guests` is the group of anonymous users
+
+
+.. _adv_tuto_security_propagation:
+
+Step 2: security propagation in hooks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To fullfill the requirements, we have to implement::
+
+  Also, unless explicity specified, visibility of an image should be the same as
+  its parent folder, as well as visibility of a comment should be the same as the
+  commented entity.
+
+This kind of `active` rule will be done using CubicWeb's hook
+system. Hooks are triggered on database event such as addition of new
+entity or relation.
+
+The trick part of the requirement is in *unless explicitly specified*, notably
+because when the entity addition hook is added, we don't know yet its 'parent'
+entity (eg folder of an image, image commented by a comment). To handle such things,
+CubicWeb provides `Operation`, which allow to schedule things to do at commit time.
+
+In our case we will:
+
+* on entity creation, schedule an operation that will set default visibility
+
+* when a "parent" relation is added, propagate parent's visibility unless the
+  child already has a visibility set
+
+Here is the code in cube's *hooks.py*:
+
+.. sourcecode:: python
+
+    from cubicweb.selectors import implements
+    from cubicweb.server import hook
+
+    class SetVisibilityOp(hook.Operation):
+	def precommit_event(self):
+	    for eid in self.session.transaction_data.pop('pending_visibility'):
+		entity = self.session.entity_from_eid(eid)
+		if entity.visibility == 'parent':
+		    entity.set_attributes(visibility=u'authenticated')
+
+    class SetVisibilityHook(hook.Hook):
+	__regid__ = 'sytweb.setvisibility'
+	__select__ = hook.Hook.__select__ & implements('Folder', 'File', 'Image', 'Comment')
+	events = ('after_add_entity',)
+	def __call__(self):
+	    hook.set_operation(self._cw, 'pending_visibility', self.entity.eid,
+			       SetVisibilityOp)
+
+    class SetParentVisibilityHook(hook.Hook):
+	__regid__ = 'sytweb.setparentvisibility'
+	__select__ = hook.Hook.__select__ & hook.match_rtype('filed_under', 'comments')
+	events = ('after_add_relation',)
+
+	def __call__(self):
+	    parent = self._cw.entity_from_eid(self.eidto)
+	    child = self._cw.entity_from_eid(self.eidfrom)
+	    if child.visibility == 'parent':
+		child.set_attributes(visibility=parent.visibility)
+
+Notice:
+
+* hooks are application objects, hence have selectors that should match entity or
+  relation types to which the hook applies. To match a relation type, we use the
+  hook specific `match_rtype` selector.
+
+* usage of `set_operation`: instead of adding an operation for each added entity,
+  set_operation allows to create a single one and to store entity's eids to be
+  processed in session's transaction data. This is a good pratice to avoid heavy
+  operations manipulation cost when creating a lot of entities in the same
+  transaction.
+
+* the `precommit_event` method of the operation will be called at transaction's
+  commit time.
+
+* in a hook, `self._cw` is the repository session, not a web request as usually
+  in views
+
+* according to hook's event, you have access to different attributes on the hook
+  instance. Here:
+
+  - `self.entity` is the newly added entity on 'after_add_entity' events
+
+  - `self.eidfrom` / `self.eidto` are the eid of the subject / object entity on
+    'after_add_relatiohn' events (you may also get the relation type using
+    `self.rtype`)
+
+The `parent` visibility value is used to tell "propagate using parent security"
+because we want that attribute to be required, so we can't use None value else
+we'll get an error before we get any chance to propagate...
+
+Now, we also want to propagate the `may_be_read_by` relation. Fortunately,
+CubicWeb provides some base hook classes for such things, so we only have to add
+the following code to *hooks.py*:
+
+.. sourcecode:: python
+
+    # relations where the "parent" entity is the subject
+    S_RELS = set()
+    # relations where the "parent" entity is the object
+    O_RELS = set(('filed_under', 'comments',))
+
+    class AddEntitySecurityPropagationHook(hook.PropagateSubjectRelationHook):
+	"""propagate permissions when new entity are added"""
+	__regid__ = 'sytweb.addentity_security_propagation'
+	__select__ = (hook.PropagateSubjectRelationHook.__select__
+		      & hook.match_rtype_sets(S_RELS, O_RELS))
+	main_rtype = 'may_be_read_by'
+	subject_relations = S_RELS
+	object_relations = O_RELS
+
+    class AddPermissionSecurityPropagationHook(hook.PropagateSubjectRelationAddHook):
+	"""propagate permissions when new entity are added"""
+	__regid__ = 'sytweb.addperm_security_propagation'
+	__select__ = (hook.PropagateSubjectRelationAddHook.__select__
+		      & hook.match_rtype('may_be_read_by',))
+	subject_relations = S_RELS
+	object_relations = O_RELS
+
+    class DelPermissionSecurityPropagationHook(hook.PropagateSubjectRelationDelHook):
+	__regid__ = 'sytweb.delperm_security_propagation'
+	__select__ = (hook.PropagateSubjectRelationDelHook.__select__
+		      & hook.match_rtype('may_be_read_by',))
+	subject_relations = S_RELS
+	object_relations = O_RELS
+
+* the `AddEntitySecurityPropagationHook` will propagate the relation
+  when `filed_under` or `comments` relations are added
+
+  - the `S_RELS` and `O_RELS` set as well as the `match_rtype_sets` selector are
+    used here so that if my cube is used by another one, it'll be able to
+    configure security propagation by simply adding relation to one of the two
+    sets.
+
+* the two others will propagate permissions changes on parent entities to
+  children entities
+
+
+.. _adv_tuto_tesing_security:
+
+Step 3: testing our security
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Security is tricky. Writing some tests for it is a very good idea. You should
+even write them first, as Test Driven Development recommends!
+
+Here is a small test case that will check the basis of our security
+model, in *test/unittest_sytweb.py*:
+
+.. sourcecode:: python
+
+    from cubicweb.devtools.testlib import CubicWebTC
+    from cubicweb import Binary
+
+    class SecurityTC(CubicWebTC):
+
+	def test_visibility_propagation(self):
+	    # create a user for later security checks
+	    toto = self.create_user('toto')
+	    # init some data using the default manager connection
+	    req = self.request()
+	    folder = req.create_entity('Folder',
+				       name=u'restricted',
+				       visibility=u'restricted')
+	    photo1 = req.create_entity('Image',
+				       data_name=u'photo1.jpg',
+				       data=Binary('xxx'),
+				       filed_under=folder)
+	    self.commit()
+	    photo1.clear_all_caches() # good practice, avoid request cache effects
+	    # visibility propagation
+	    self.assertEquals(photo1.visibility, 'restricted')
+	    # unless explicitly specified
+	    photo2 = req.create_entity('Image',
+				       data_name=u'photo2.jpg',
+				       data=Binary('xxx'),
+				       visibility=u'public',
+				       filed_under=folder)
+	    self.commit()
+	    self.assertEquals(photo2.visibility, 'public')
+	    # test security
+	    self.login('toto')
+	    req = self.request()
+	    self.assertEquals(len(req.execute('Image X')), 1) # only the public one
+	    self.assertEquals(len(req.execute('Folder X')), 0) # restricted...
+	    # may_be_read_by propagation
+	    self.restore_connection()
+	    folder.set_relations(may_be_read_by=toto)
+	    self.commit()
+	    photo1.clear_all_caches()
+	    self.failUnless(photo1.may_be_read_by)
+	    # test security with permissions
+	    self.login('toto')
+	    req = self.request()
+	    self.assertEquals(len(req.execute('Image X')), 2) # now toto has access to photo2
+	    self.assertEquals(len(req.execute('Folder X')), 1) # and to restricted folder
+
+    if __name__ == '__main__':
+	from logilab.common.testlib import unittest_main
+	unittest_main()
+
+It's not complete, but show most things you'll want to do in tests: adding some
+content, creating users and connecting as them in the test, etc...
+
+To run it type: ::
+
+    [syt@scorpius test]$ pytest unittest_sytweb.py
+    ========================  unittest_sytweb.py  ========================
+    -> creating tables [....................]
+    -> inserting default user and default groups.
+    -> storing the schema in the database [....................]
+    -> database for instance data initialized.
+    .
+    ----------------------------------------------------------------------
+    Ran 1 test in 22.547s
+
+    OK
+
+
+The first execution is taking time, since it creates a sqlite database for the
+test instance. The second one will be much quicker: ::
+
+    [syt@scorpius test]$ pytest unittest_sytweb.py
+    ========================  unittest_sytweb.py  ========================
+    .
+    ----------------------------------------------------------------------
+    Ran 1 test in 2.662s
+
+    OK
+
+If you do some changes in your schema, you'll have to force regeneration of that
+database. You do that by removing the tmpdb files before running the test: ::
+
+    [syt@scorpius test]$ rm tmpdb*
+
+
+.. Note::
+  pytest is a very convenient utilities to control test execution, from the `logilab-common`_
+  package
+
+.. _`logilab-common`: http://www.logilab.org/project/logilab-common
+
+.. _adv_tuto_migration_script:
+
+Step 4: writing the migration script and migrating the instance
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Prior to those changes, Iv'e created an instance, feeded it with some data, so I
+don't want to create a new one, but to migrate the existing one. Let's see how to
+do that.
+
+Migration commands should be put in the cube's *migration* directory, in a
+file named file:`<X.Y.Z>_Any.py` ('Any' being there mostly for historical reason).
+
+Here I'll create a *migration/0.2.0_Any.py* file containing the following
+instructions:
+
+.. sourcecode:: python
+
+  add_relation_type('may_be_read_by')
+  add_relation_type('visibility')
+  sync_schema_props_perms()
+
+Then I update the version number in cube's *__pkginfo__.py* to 0.2.0. And
+that's it! Those instructions will:
+
+* update the instance's schema by adding our two new relations and update the
+  underlying database tables accordingly (the two first instructions)
+
+* update schema's permissions definition (the later instruction)
+
+
+To migrate my instance I simply type::
+
+   [syt@scorpius ~]$ cubicweb-ctl upgrade sytweb
+
+I'll then be asked some questions to do the migration step by step. You should say
+YES when it asks if a backup of your database should be done, so you can get back
+to initial state if anything goes wrong...
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/blog-in-five-minutes.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,42 @@
+.. -*- coding: utf-8 -*-
+
+.. _BlogFiveMinutes:
+
+Get a blog running in five minutes!
+-----------------------------------
+
+For Debian or Ubuntu users, first install the following packages (:ref:`DebianInstallation`)::
+
+    cubicweb, cubicweb-dev, cubicweb-blog
+
+For Windows or Mac OS X users, you must install cubicweb from source (see :ref:`SourceInstallation` and  :ref:`WindowsInstallation`).
+
+Then create and initialize your instance::
+
+    cubicweb-ctl create blog myblog
+
+And start it::
+
+    cubicweb-ctl start -D myblog
+
+The -D option is the debugging mode of cubicweb, removing it will lauch the instance in the background.
+
+Permission
+~~~~~~~~~~
+
+This command assumes that you have root access to the /etc/ path. In order to initialize your instance as a `user` (from scratch), please check your current PYTHONPATH then create the ~/etc/cubicweb.d directory.
+
+Instance parameters
+~~~~~~~~~~~~~~~~~~~
+
+If the database installation failed, you'd like to change some instance parameters, for example, the database host or the user name. These informations can be edited in the `source` file located in the /etc/cubicweb.d/myblog directory.
+
+Then relaunch the database creation:
+
+     cubicweb-ctl db-create myblog
+
+Other paramaters, like web server or emails parameters, can be modified in the `all-in-one.conf` file.
+
+This is it. Your blog is running. Visit http://localhost:8080 and enjoy it! This blog is fully functionnal. The next section section will present the way to develop new cubes and customizing the look of your instance.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/components.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,79 @@
+.. -*- coding: utf-8 -*-
+
+.. _cubes:
+
+Cubes
+-----
+
+Standard library
+~~~~~~~~~~~~~~~~
+
+A library of standard cubes are available from `CubicWeb Forge`_
+Cubes provide entities and views.
+
+The available application entities in standard cubes are:
+
+* addressbook: PhoneNumber and PostalAddress
+
+* basket: Basket (like a shopping cart)
+
+* blog: Blog (a *very* basic blog)
+
+* classfolder: Folder (to organize things but grouping them in folders)
+
+* classtags: Tag (to tag anything)
+
+* comment: Comment (to attach comment threads to entities)
+
+* file: File (to allow users to upload and store binary or text files)
+
+* link: Link (to collect links to web resources)
+
+* mailinglist: MailingList (to reference a mailing-list and the URLs
+  for its archives and its admin interface)
+
+* person: Person (easily mixed with addressbook)
+
+* task: Task (something to be done between start and stop date)
+
+* zone: Zone (to define places within larger places, for example a
+  city in a state in a country)
+
+.. _`CubicWeb Forge`: http://www.cubicweb.org/project/
+
+Adding comments to BlogDemo
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To import a cube in your instance just change the line in the
+``__pkginfo__.py`` file and verify that the cube you are planning
+to use is listed by the command ``cubicweb-ctl list``.
+For example::
+
+    __use__ = ('comment',)
+
+will make the ``Comment`` entity available in your ``BlogDemo``
+cube.
+
+Change the schema to add a relationship between ``BlogEntry`` and
+``Comment`` and you are done. Since the comment cube defines the
+``comments`` relationship, adding the line::
+
+    comments = ObjectRelation('Comment', cardinality='1*', composite='object')
+
+to the definition of a ``BlogEntry`` will be enough.
+
+Synchronize the data model
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once you modified your data model, you need to synchronize the
+database with your model. For this purpose, *CubicWeb* provides
+a very useful command ``cubicweb-ctl shell blogdemo`` which
+launches an interactive shell where you can enter migration
+commands (see :ref:`cubicweb-ctl` for more details)).
+As you added the cube named `comment`, you need to run:
+
+::
+
+  add_cube('comment')
+
+You can now start your instance and comment your blog entries.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/conclusion.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,15 @@
+.. -*- coding: utf-8 -*-
+
+What's next?
+------------
+
+We demonstrated how from a straight out of the box *CubicWeb* installation, you
+can build your web application based on a data model. It's all already there:
+views, templates, permissions, etc. The step forward is now for you to customize
+according to your needs.
+
+Many features are available to extend your application, for example: RSS channel
+integration (:ref:`XmlAndRss`), hooks (:ref:`hooks`), support of sources such as
+Google App Engine (:ref:`GoogleAppEngineSource`) and lots of others to discover
+through our book.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/create-cube.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,431 @@
+.. -*- coding: utf-8 -*-
+
+.. _Steps:
+
+Steps for creating your cube
+----------------------------
+
+The following steps will help you to create and customize a new cube.
+
+1. :ref:`CreateYourCube`
+
+Create the directory to hold the code of your cube. The most important
+files that will be useful to customize your newly created cube are:
+
+  * schema.py: contains the data model
+  * views.py: contains your custom views
+  * entities.py: contains XXX
+
+The detailed structure of the code directory is described in :ref:`cubelayout`.
+
+2. :ref:`DefineDataModel`
+
+Define the data model of your application.
+
+3. :ref:`ExploreYourInstance`
+
+Create, run, and explore an instance of your cube.
+
+4. :ref:`DefineViews`
+
+Customize the views of your data: how and which part of your data are showed.
+
+Note: views don't concern the look'n'feel or design of the site. For that, you should use CSS instead, and default CSS or your new cube are located in 'blog/data/'.
+
+
+5. :ref:`DefineEntities`
+
+Define your own entities to add useful functions when you manipulate your data, especially when you write view.
+
+
+.. _CreateYourCube:
+
+Create your cube
+----------------
+
+The packages ``cubicweb`` and ``cubicweb-dev`` install a command line
+tool for *CubicWeb* called ``cubicweb-ctl``. This tool provides a wide
+range of commands described in details in :ref:`cubicweb-ctl`.
+
+Once your *CubicWeb* development environment is set up, you can create
+a new cube::
+
+  cubicweb-ctl newcube blog
+
+This will create in the cubes directory (``/path/to/forest/cubes`` for Mercurial
+installation, ``/usr/share/cubicweb/cubes`` for debian packages installation)
+a directory named ``blog`` reflecting the structure described in :ref:`Concepts`.
+
+
+For packages installation, you can still create new cubes in your home directory using the following configuration. Let's say you want to develop your new cubes in `~src/cubes`, then set the following environment variables:
+::
+
+  CW_CUBES_PATH=~/src/cubes
+  CW_MODE=user
+
+and then create your new cube using:
+::
+
+  cubicweb-ctl newcube --directory=~/src/cubes blog
+
+
+
+
+
+
+.. _DefineDataModel:
+
+Define your data model
+----------------------
+
+The data model or schema is the core of your *CubicWeb* application.
+It defines the type of content your application will handle.
+
+The data model of your cube ``blog`` is defined in the file ``schema.py``:
+
+.. sourcecode:: python
+
+  from yams.buildobjs import EntityType, String, SubjectRelation, Date
+
+  class Blog(EntityType):
+    title = String(maxsize=50, required=True)
+    description = String()
+
+  class BlogEntry(EntityType):
+    title = String(required=True, fulltextindexed=True, maxsize=256)
+    publish_date = Date(default='TODAY')
+    content = String(required=True, fulltextindexed=True)
+    entry_of = SubjectRelation('Blog', cardinality='?*')
+
+The first step is the import of the EntityType (generic class for entity and
+attributes that will be used in both Blog and BlogEntry entities.
+
+A Blog has a title and a description. The title is a string that is
+required and must be less than 50 characters.  The
+description is a string that is not constrained.
+
+A BlogEntry has a title, a publish_date and a content. The title is a
+string that is required and must be less than 100 characters. The
+publish_date is a Date with a default value of TODAY, meaning that
+when a BlogEntry is created, its publish_date will be the current day
+unless it is modified. The content is a string that will be indexed in
+the database full-text index and has no constraint.
+
+A BlogEntry also has a relationship ``entry_of`` that links it to a
+Blog. The cardinality ``?*`` means that a BlogEntry can be part of
+zero or one Blog (``?`` means `zero or one`) and that a Blog can
+have any number of BlogEntry (``*`` means `any number including
+zero`). For completeness, remember that ``+`` means `one or more`.
+
+
+.. _ExploreYourInstance:
+
+Create and explore your instance
+--------------------------------
+.. _CreateYourInstance:
+
+Create your instance
+~~~~~~~~~~~~~~~~~~~~
+
+To use this cube as an instance and create a new instance named ``blogdemo``, do::
+
+  cubicweb-ctl create blog blogdemo
+
+This command will create the corresponding database and initialize it.
+
+
+.. _WelcomeToYourWebInstance:
+
+Welcome to your web instance
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Start your instance in debug mode with the following command: ::
+
+  cubicweb-ctl start -D blogdemo
+
+
+You can now access your web instance to create blogs and post messages
+by visiting the URL http://localhost:8080/.
+
+A login form will appear. By default, the instance will not allow anonymous
+users to enter the instance. To login, you need then use the admin account
+you created at the time you initialized the database with ``cubicweb-ctl
+create``.
+
+.. image:: ../../images/login-form.png
+
+
+Once authenticated, you can start playing with your instance
+and create entities.
+
+.. image:: ../../images/blog-demo-first-page.png
+
+Please notice that so far, the *CubicWeb* framework managed all aspects of
+the web application based on the schema provided at the beginning.
+
+.. _AddEntities:
+
+Add entities
+~~~~~~~~~~~~
+
+We will now add entities in our web application.
+
+Add a Blog
+**********
+
+Let us create a few of these entities. Click on the `[+]` at the left of the
+link Blog on the home page. Call this new Blog ``Tech-blog`` and type in
+``everything about technology`` as the description, then validate the form by
+clicking on ``Validate``.
+
+.. image:: ../../images/cbw-create-blog.en.png
+   :alt: from to create blog
+
+Click on the logo at top left to get back to the home page, then
+follow the Blog link that will list for you all the existing Blog.
+You should be seeing a list with a single item ``Tech-blog`` you
+just created.
+
+.. image:: ../../images/cbw-list-one-blog.en.png
+   :alt: displaying a list of a single blog
+
+Clicking on this item will get you to its detailed description except
+that in this case, there is not much to display besides the name and
+the phrase ``everything about technology``.
+
+Now get back to the home page by clicking on the top-left logo, then
+create a new Blog called ``MyLife`` and get back to the home page
+again to follow the Blog link for the second time. The list now
+has two items.
+
+.. image:: ../../images/cbw-list-two-blog.en.png
+   :alt: displaying a list of two blogs
+
+Add a BlogEntry
+***************
+
+Get back to the home page and click on [+] at the left of the link
+BlogEntry. Call this new entry ``Hello World`` and type in some text
+before clicking on ``Validate``. You added a new blog entry without
+saying to what blog it belongs. There is a box on the left entitled
+``actions``, click on the menu item ``modify``. You are back to the form
+to edit the blog entry you just created, except that the form now has
+another section with a combobox titled ``add relation``. Chose
+``entry_of`` in this menu and a second combobox appears where you pick
+``MyLife``.
+
+You could also have, at the time you started to fill the form for a
+new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
+combobox titled ``add relation`` would have showed up.
+
+
+.. image:: ../../images/cbw-add-relation-entryof.en.png
+   :alt: editing a blog entry to add a relation to a blog
+
+Validate the changes by clicking ``Validate``. The entity BlogEntry
+that is displayed now includes a link to the entity Blog named
+``MyLife``.
+
+.. image:: ../../images/cbw-detail-one-blogentry.en.png
+   :alt: displaying the detailed view of a blogentry
+
+Note that all of this was handled by the framework and that the only input
+that was provided so far is the schema. To get a graphical view of the schema,
+point your browser to the URL http://localhost:8080/schema
+
+.. image:: ../../images/cbw-schema.en.png
+   :alt: graphical view of the schema (aka data-model)
+
+
+.. _DefineViews:
+
+Define your entity views
+------------------------
+
+Each entity defined in a model is associated with default views
+allowing different renderings of the data. You can redefine each of
+them according to your needs and preferences. So let's see how the
+views are defined.
+
+
+The view selection principle
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A view is defined by a Python class which includes:
+
+  - an identifier (all objects in *CubicWeb* are recorded in a
+    registry and this identifier will be used as a key)
+
+  - a filter to select the result sets it can be applied to
+
+A view has a set of methods complying with the `View` class interface
+(`cubicweb.common.view`).
+
+*CubicWeb* provides a lot of standard views for the type `EntityView`;
+for a complete list, read the code in directory ``cubicweb/web/views/``.
+
+A view is applied on a `result set` which contains a set of entities
+we are trying to display. *CubicWeb* uses a selector mechanism which
+computes for each available view a score: the view with the highest
+score is then used to display the given `result set`.  The standard
+library of selectors is in ``cubicweb.selector``.
+
+It is possible to define multiple views for the same identifier
+and to associate selectors and filters to allow the application
+to find the most appropriate way to render the data.
+
+For example, the view named ``primary`` is the one used to display a
+single entity. We will now show you how to create a primary view for
+BlogEntry.
+
+
+Primary view customization
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you wish to modify the way a `BlogEntry` is rendered, you will have
+to subclass the `primary` view, for instance in the module ``views``
+of the cube ``cubes/blog/views.py``.
+
+The standard primary view is the most sophisticated view of all. It
+has more than a call() method. It is a template. Actually the entry
+point calls the following sequence of (redefinable) methods:
+
+ * render_entity_title
+
+ * render_entity_metadata
+
+ * render_entity_attributes
+
+ * render_entity_relations
+
+ * render_side_boxes
+
+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`.
+
+We can for example add in front of the publication date a prefix
+specifying that the date we see is the publication date.
+
+To do so, please apply the following changes:
+
+.. sourcecode:: python
+
+  from cubicweb.selectors import implements
+  from cubicweb.web.views import primary
+
+  class BlogEntryPrimaryView(primary.PrimaryView):
+      __select__ = implements('BlogEntry')
+
+      def render_entity_attributes(self, entity):
+          self.w(u'<p>published on %s</p>' %
+                 entity.publish_date.strftime('%Y-%m-%d'))
+          super(BlogEntryPrimaryView, self).render_entity_attributes(entity)
+
+.. note::
+  When a view is modified, it is not required to restart the instance
+  server. Save the Python file and reload the page in your web browser
+  to view the changes.
+
+You can now see that the publication date has a prefix.
+
+.. image:: ../../images/cbw-update-primary-view.en.png
+   :alt: modified primary view
+
+
+The above source code defines a new primary view for ``BlogEntry``.
+
+Since views are applied to result sets and result sets can be tables of
+data, we have to recover the entity from its (row,col)-coordinates.
+The view has a ``self.w()`` method that is used to output data, in our
+example HTML output.
+
+.. note::
+   You can find more details about views and selectors in :ref:`Views`.
+
+
+.. _DefineEntities:
+
+Write entities to add logic in your data
+----------------------------------------
+
+By default, CubicWeb provides a default entity for each data type defined in the schema.
+A default entity mainly contains the attributes defined in the data model.
+
+You can redefine each entity to provide additional functions to help you write your views.
+
+.. sourcecode:: python
+
+    from cubicweb.entities import AnyEntity
+
+    class BlogEntry(AnyEntity):
+        """customized class for BlogEntry entities"""
+    	__regid__ = 'BlogEntry'
+    	__implements__ = AnyEntity.__implements__
+
+        def display_cw_logo(self):
+            if 'CW' in self.title:
+                return True
+            else:
+                return False
+
+Customizing an entity requires that your entity:
+ - inherits from ``cubicweb.entities`` or any subclass
+ - defines a ``__regid__`` linked to the corresponding data type of your schema
+ - implements the base class by explicitly using ``__implements__``.
+
+We implemented here a function ``display_cw_logo`` which tests if the blog entry title contains 'CW'.
+This function can then be used when you customize your views. For instance, you can modify your previous ``views.py`` as follows:
+
+.. sourcecode:: python
+
+ class BlogEntryPrimaryView(primary.PrimaryView):
+     __select__ = implements('BlogEntry')
+
+     ...
+
+     def render_entity_title(self, entity):
+	 if entity.display_cw_logo():
+	     self.w(u'<image src="http://www.cubicweb.org/doc/en/_static/cubicweb.png"/>')
+	 super(BlogEntryPrimaryView, self).render_entity_title(entity)
+
+Then each blog entry whose title contains 'CW' is shown with the CubicWeb logo in front of it.
+
+.. _UpdatingSchemaAndSynchronisingInstance:
+
+Updating the schema and synchronising the instance
+--------------------------------------------------
+
+While developping your cube, you may want to update your data model. Let's say you
+want to add a ``category`` attribute in the ``Blog`` data type. This is called a migration.
+
+The required steps are:
+1. modify the file ``schema.py``. The ``Blog`` class looks now like this:
+
+.. sourcecode:: python
+
+ class Blog(EntityType):
+   title = String(maxsize=50, required=True)
+   description = String()
+   category = String(required=True, vocabulary=(_('Professional'), _('Personal')), default='Personal')
+
+2. stop your ``blogdemo`` instance
+
+3. start the cubicweb shell for your instance by running the following command:
+
+.. sourcecode:: bash
+
+  cubicweb-ctl shell blogdemo
+
+4. in the shell, execute:
+
+.. sourcecode:: python
+
+ add_attribute('Blog', 'category')
+
+5. you can restart your instance, modify a blog entity and check that the new attribute
+``category`` has been added.
+
+Of course, you may also want to add relations, entity types, ... See :ref:`migration`
+for a list of all available migration commands.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,30 @@
+.. -*- coding: utf-8 -*-
+
+.. _Tutorial:
+
+.. _tuto_blog:
+
+Building a simple blog
+======================
+
+*CubicWeb* is a semantic web application framework that favors reuse and
+object-oriented design.
+
+A `cube` is a component that includes a model defining the data types and a set of
+views to display the data. A cube can be built by assembling other cubes.
+
+An `instance` is a specific installation of a cube and includes configuration
+files.
+
+
+This tutorial will show how to create a `cube` and how to use it as an
+application to run an `instance`.
+
+.. toctree::
+   :maxdepth: 2
+
+   blog-in-five-minutes
+   create-cube
+   components
+   maintemplate
+   conclusion
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/maintemplate.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,131 @@
+.. -*- coding: utf-8 -*-
+
+Templates
+---------
+
+Look at ``cubicweb/web/views/basetemplates.py`` and you will
+find the base templates used to generate HTML for your application.
+
+A page is composed as indicated on the schema below:
+
+.. image:: ../../images/lax-book.06-main-template-layout.en.png
+
+In this section we will demonstrate a change in one of the main
+interesting template from the three you will look for,
+that is to say, the HTMLPageHeader, the HTMLPageFooter
+and the TheMainTemplate.
+
+
+Customize a template
+~~~~~~~~~~~~~~~~~~~~
+
+Based on the diagram below, each template can be overriden
+by your customized template. To do so, we recommand you create
+a Python module ``blog.views.templates`` to keep it organized.
+In this module you will have to import the parent class you are
+interested as follows: ::
+
+  from cubicweb.web.views.basetemplates import HTMLPageHeader, \
+                                    HTMLPageFooter, TheMainTemplate
+
+and then create your sub-class::
+
+  class MyBlogHTMLPageHeader(HTMLPageHeader):
+      ...
+
+Customize header
+`````````````````
+
+Let's now move the search box in the header and remove the login form from the
+header. We'll show how to move it to the left column of the user interface.
+
+Let's say we do not want anymore the login menu to be in the header
+
+First, to remove the login menu, we just need to comment out the display of the
+login graphic component such as follows:
+
+.. sourcecode:: python
+
+  class MyBlogHTMLPageHeader(HTMLPageHeader):
+
+      def main_header(self, view):
+          """build the top menu with authentification info and the rql box"""
+          self.w(u'<table id="header"><tr>\n')
+          self.w(u'<td id="firstcolumn">')
+          self._cw.vreg.select_component('logo', self._cw, self.cw_rset).dispatch(w=self.w)
+          self.w(u'</td>\n')
+          # appliname and breadcrumbs
+          self.w(u'<td id="headtext">')
+          comp = self._cw.vreg.select_component('appliname', self._cw, self.cw_rset)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w)
+          comp = self._cw.vreg.select_component('breadcrumbs', self._cw, self.cw_rset, view=view)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w, view=view)
+          self.w(u'</td>')
+          # logged user and help
+          #self.w(u'<td>\n')
+          #comp = self._cw.vreg.select_component('loggeduserlink', self._cw, self.cw_rset)
+          #comp.dispatch(w=self.w)
+          #self.w(u'</td><td>')
+
+          self.w(u'<td>')
+          helpcomp = self._cw.vreg.select_component('help', self._cw, self.cw_rset)
+          if helpcomp: # may not be available if Card is not defined in the schema
+              helpcomp.dispatch(w=self.w)
+          self.w(u'</td>')
+          # lastcolumn
+          self.w(u'<td id="lastcolumn">')
+          self.w(u'</td>\n')
+          self.w(u'</tr></table>\n')
+          self.template('logform', rset=self.cw_rset, id='popupLoginBox', klass='hidden',
+                        title=False, message=False)
+
+
+
+.. image:: ../../images/lax-book.06-header-no-login.en.png
+
+Customize footer
+````````````````
+
+If you want to change the footer for example, look
+for HTMLPageFooter and override it in your views file as in:
+
+.. sourcecode:: python
+
+  from cubicweb.web.views.basetemplates import HTMLPageFooter
+
+  class MyHTMLPageFooter(HTMLPageFooter):
+
+      def call(self, **kwargs):
+          self.w(u'<div class="footer">')
+          self.w(u'This website has been created with <a href="http://cubicweb.org">CubicWeb</a>.')
+          self.w(u'</div>')
+
+Updating a view does not require any restart of the server. By reloading
+the page you can see your new page footer.
+
+
+TheMainTemplate
+```````````````
+
+.. _TheMainTemplate:
+
+The MainTemplate is a bit complex as it tries to accomodate many
+different cases. We are now about to go through it and cutomize entirely
+our application.
+
+TheMainTemplate is responsible for the general layout of the entire application.
+It defines the template of ``__regid__ = main`` that is used by the application. Is
+also defined in ``cubicweb/web/views/basetemplates.py`` another template that can
+be used based on TheMainTemplate called SimpleMainTemplate which does not have
+a top section.
+
+.. image:: ../../images/lax-book.06-simple-main-template.en.png
+
+XXX
+[WRITE ME]
+
+* customize MainTemplate and show that everything in the user
+  interface can be changed
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/index.rst	Thu Apr 15 12:48:40 2010 +0200
@@ -0,0 +1,19 @@
+.. _Tutorials:
+
+---------
+Tutorials
+---------
+
+We present two tutorials of different levels. The blog building
+tutorial introduces one smoothly to the basic concepts.
+
+Then there is a photo gallery construction tutorial which highlights
+more advanced concepts such as unit tests, security settings,
+migration scripts.
+
+.. toctree::
+   :maxdepth: 1
+   :numbered:
+
+   base/index
+   advanced/index
--- a/etwist/server.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/etwist/server.py	Thu Apr 15 12:48:40 2010 +0200
@@ -194,7 +194,7 @@
         """Render a page from the root resource"""
         # reload modified files in debug mode
         if self.debugmode:
-            self.appli.vreg.register_objects(self.config.vregistry_path())
+            self.appli.vreg.reload_if_needed()
         if self.config['profile']: # default profiler don't trace threads
             return self.render_request(request)
         else:
--- a/vregistry.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/vregistry.py	Thu Apr 15 12:48:40 2010 +0200
@@ -31,8 +31,7 @@
 from logilab.common.logging_ext import set_log_methods
 
 from cubicweb import CW_SOFTWARE_ROOT
-from cubicweb import (RegistryNotFound, ObjectNotFound, NoSelectableObject,
-                      RegistryOutOfDate)
+from cubicweb import RegistryNotFound, ObjectNotFound, NoSelectableObject
 from cubicweb.appobject import AppObject
 
 def _toload_info(path, extrapath, _toload=None):
@@ -246,8 +245,18 @@
     def __init__(self, config):
         super(VRegistry, self).__init__()
         self.config = config
+        # need to clean sys.path this to avoid import confusion pb (i.e.  having
+        # the same module loaded as 'cubicweb.web.views' subpackage and as
+        # views' or 'web.views' subpackage. This is mainly for testing purpose,
+        # we should'nt need this in production environment
+        for webdir in (join(dirname(realpath(__file__)), 'web'),
+                       join(dirname(__file__), 'web')):
+            if webdir in sys.path:
+                sys.path.remove(webdir)
+        if CW_SOFTWARE_ROOT in sys.path:
+            sys.path.remove(CW_SOFTWARE_ROOT)
 
-    def reset(self, path=None, force_reload=None):
+    def reset(self):
         # don't use self.clear, we want to keep existing subdictionaries
         for subdict in self.itervalues():
             subdict.clear()
@@ -392,60 +401,61 @@
         self._loadedmods = {}
         return filemods
 
-    def register_objects(self, path, force_reload, extrapath=None):
-        # need to clean sys.path this to avoid import confusion pb (i.e.
-        # having the same module loaded as 'cubicweb.web.views' subpackage and
-        # as views'  or 'web.views' subpackage
-        # this is mainly for testing purpose, we should'nt need this in
-        # production environment
-        for webdir in (join(dirname(realpath(__file__)), 'web'),
-                       join(dirname(__file__), 'web')):
-            if webdir in sys.path:
-                sys.path.remove(webdir)
-        if CW_SOFTWARE_ROOT in sys.path:
-            sys.path.remove(CW_SOFTWARE_ROOT)
+    def register_objects(self, path, force_reload=False, extrapath=None):
         # load views from each directory in the instance's path
         filemods = self.init_registration(path, extrapath)
-        change = False
         for filepath, modname in filemods:
-            if self.load_file(filepath, modname, force_reload):
-                change = True
-        if change:
-            self.initialization_completed()
-        return change
+            self.load_file(filepath, modname, force_reload)
+        self.initialization_completed()
 
     def initialization_completed(self):
         for regname, reg in self.iteritems():
             reg.initialization_completed()
 
+    def _mdate(self, filepath):
+        try:
+            return stat(filepath)[-2]
+        except OSError:
+            # this typically happens on emacs backup files (.#foo.py)
+            self.warning('Unable to load %s. It is likely to be a backup file',
+                         filepath)
+            return None
+
+    def is_reload_needed(self, path):
+        """return True if something module changed and the registry should be
+        reloaded
+        """
+        lastmodifs = self._lastmodifs
+        for fileordir in path:
+            if isdir(fileordir) and exists(join(fileordir, '__init__.py')):
+                if self.is_reload_needed([join(fileordir, fname)
+                                          for fname in listdir(fileordir)]):
+                    return True
+            elif fileordir[-3:] == '.py':
+                mdate = self._mdate(fileordir)
+                if mdate is None:
+                    continue # backup file, see _mdate implementation
+                if fileordir not in lastmodifs or lastmodifs[fileordir] < mdate:
+                    self.info('File %s changed since last visit', fileordir)
+                    return True
+        return False
+
     def load_file(self, filepath, modname, force_reload=False):
         """load app objects from a python file"""
         from logilab.common.modutils import load_module_from_name
         if modname in self._loadedmods:
             return
         self._loadedmods[modname] = {}
-        try:
-            modified_on = stat(filepath)[-2]
-        except OSError:
-            # this typically happens on emacs backup files (.#foo.py)
-            self.warning('Unable to load %s. It is likely to be a backup file',
-                         filepath)
-            return False
-        if filepath in self._lastmodifs:
-            # only load file if it was modified
-            if modified_on <= self._lastmodifs[filepath]:
-                return
-            # if it was modified, raise RegistryOutOfDate to reload everything
-            self.info('File %s changed since last visit', filepath)
-            raise RegistryOutOfDate()
+        mdate = self._mdate(filepath)
+        if mdate is None:
+            return # backup file, see _mdate implementation
         # set update time before module loading, else we get some reloading
         # weirdness in case of syntax error or other error while importing the
         # module
-        self._lastmodifs[filepath] = modified_on
+        self._lastmodifs[filepath] = mdate
         # load the module
         module = load_module_from_name(modname, use_sys=not force_reload)
         self.load_module(module)
-        return True
 
     def load_module(self, module):
         self.info('loading %s', module)
--- a/web/uicfg.py	Thu Apr 15 12:47:02 2010 +0200
+++ b/web/uicfg.py	Thu Apr 15 12:48:40 2010 +0200
@@ -8,107 +8,6 @@
 
 To configure the interface generation, we use ``RelationTag`` objects.
 
-Primary view configuration
-``````````````````````````
-
-XXX section moved to the doc, is maintained there
-
-If you want to customize the primary view of an entity, overriding the primary
-view class may not be necessary. For simple adjustments (attributes or relations
-display locations and styles), a much simpler way is to use uicfg.
-
-Attributes/relations display location
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In the primary view, there are 3 sections where attributes and relations can be
-displayed (represented in pink in the image below):
-
-* attributes
-* relations
-* sideboxes
-
-.. image:: ../../images/primaryview_template.png
-
-
-**Attributes** can only be displayed in the attributes section (default
-  behavior). They can also be hidden.
-
-For instance, to hide the ``title`` attribute of the ``Blog`` entity:
-
-.. sourcecode:: python
-
-   from cubicweb.web import uicfg
-   uicfg.primaryview_section.tag_attribute(('Blog', 'title'), 'hidden')
-
-
-**Relations** can be either displayed in one of the three sections or hidden.
-
-For relations, there are two methods:
-
-* ``tag_object_of`` for modifying the primary view of the object
-* ``tag_subject_of`` for modifying the primary view of the subject
-
-These two methods take two arguments:
-
-* a triplet ``(subject, relation_name, object)``, where subject or object can be replaced with ``'*'``
-* the section name or ``hidden``
-
-.. sourcecode:: python
-
-   # hide every relation ``entry_of`` in the ``Blog`` primary view
-   uicfg.primaryview_section.tag_object_of(('*', 'entry_of', 'Blog'), 'hidden')
-
-   # display ``entry_of`` relations in the ``relations`` section in the ``BlogEntry`` primary view
-   uicfg.primaryview_section.tag_subject_of(('BlogEntry', 'entry_of', '*'),
-                                             'relations')
-
-
-Display content
-^^^^^^^^^^^^^^^
-
-You can use ``primaryview_display_ctrl`` to customize the display of attributes
-or relations. Values of ``primaryview_display_ctrl`` are dictionaries.
-
-
-Common keys for attributes and relations are:
-* ``vid``: specifies the regid of the view for displaying the attribute or the relation.
-
-  If ``vid`` is not specified, the default value depends on the section:
-  * ``attributes`` section: 'reledit' view
-  * ``relations`` section: 'autolimited' view
-  * ``sideboxes`` section: 'sidebox' view
-
-* ``order``: int used to control order within a section. When not specified,
-  automatically set according to order in which tags are added.
-
-
-Keys for relations only:
-
-* ``label``: label for the relations section or side box
-
-* ``showlabel``: boolean telling whether the label is displayed
-
-* ``limit``: boolean telling if the results should be limited. If so, a link to all results is displayed
-
-* ``filter``: callback taking the related result set as argument and returning it filtered
-
-.. sourcecode:: python
-
-   # in ``CWUser`` primary view, display ``created_by`` relations in relations section
-   uicfg.primaryview_section.tag_object_of(('*', 'created_by', 'CWUser'), 'relations')
-
-   # displays this relation as a list, sets the label, limits the number of results and filters on comments
-   uicfg.primaryview_display_ctrl.tag_object_of(
-       ('*', 'created_by', 'CWUser'),
-       {'vid': 'list', 'label': _('latest comment(s):'), 'limit': True,
-        'filter': lambda rset: rset.filtered_rset(lambda x: x.e_schema == 'Comment')})
-
-.. Warning:: with the ``primaryview_display_ctrl`` rtag, the subject or the
-   object of the relation is ignored for respectively ``tag_object_of`` or
-   ``tag_subject_of``. To avoid warnings during execution, they should be set to
-   ``'*'``.
-
-
 Index view configuration
 ````````````````````````
 :indexview_etype_section: