merge stable
authorKatia Saurfelt <katia.saurfelt@logilab.fr>
Wed, 01 Jul 2009 11:33:40 +0200
branchstable
changeset 2213 713e220e7425
parent 2212 201ce0d389f3 (current diff)
parent 2208 1c73148ed912 (diff)
child 2214 a6b42cf05407
merge
doc/book/en/intro/foundations/index.rst
doc/book/en/intro/tutorial/blog-less-ten-minutes.rst
web/views/facets.py
--- a/.hgtags	Wed Jul 01 11:33:18 2009 +0200
+++ b/.hgtags	Wed Jul 01 11:33:40 2009 +0200
@@ -41,3 +41,5 @@
 2d7d3062ca03d4b4144100013dc4ab7f9d9cb25e cubicweb-version-3_3_0
 07214e923e75c8f0490e609e9bee0f4964b87114 cubicweb-debian-version-3_3_0-1
 a356da3e725bfcb59d8b48a89d04be05ea261fd3 3.3.1
+e3aeb6e6c3bb5c18e8dcf61bae9d654beda6c036 cubicweb-version-3_3_2
+bef5e74e53f9de8220451dca4b5863a24a0216fb cubicweb-debian-version-3_3_2-1
--- a/__pkginfo__.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/__pkginfo__.py	Wed Jul 01 11:33:40 2009 +0200
@@ -7,7 +7,7 @@
 distname = "cubicweb"
 modname = "cubicweb"
 
-numversion = (3, 3, 1)
+numversion = (3, 3, 2)
 version = '.'.join(str(num) for num in numversion)
 
 license = 'LGPL v2'
--- a/common/__init__.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/common/__init__.py	Wed Jul 01 11:33:40 2009 +0200
@@ -18,9 +18,9 @@
     rtype = 'String'
 
     @classmethod
-    def st_description(cls, funcnode):
-        return ', '.join(term.get_description()
-                         for term in iter_funcnode_variables(funcnode))
+    def st_description(cls, funcnode, mainindex, tr):
+        return ', '.join(sorted(term.get_description(mainindex, tr)
+                                for term in iter_funcnode_variables(funcnode)))
 
 register_function(COMMA_JOIN)  # XXX do not expose?
 
@@ -41,8 +41,8 @@
     rtype = 'String'
 
     @classmethod
-    def st_description(cls, funcnode):
-        return funcnode.children[0].get_description()
+    def st_description(cls, funcnode, mainindex, tr):
+        return funcnode.children[0].get_description(mainindex, tr)
 
 register_function(LIMIT_SIZE)
 
--- a/common/mail.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/common/mail.py	Wed Jul 01 11:33:40 2009 +0200
@@ -19,7 +19,7 @@
 def addrheader(uaddr, uname=None):
     # even if an email address should be ascii, encode it using utf8 since
     # application tests may generate non ascii email address
-    addr = uaddr.encode('UTF-8') 
+    addr = uaddr.encode('UTF-8')
     if uname:
         return '%s <%s>' % (header(uname).encode(), addr)
     return addr
--- a/common/uilib.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/common/uilib.py	Wed Jul 01 11:33:40 2009 +0200
@@ -92,7 +92,9 @@
 
 # fallback implementation, nicer one defined below if lxml is available
 def soup2xhtml(data, encoding):
-    return data
+    # normalize line break
+    # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
+    return u'\n'.join(data.splitlines())
 
 # fallback implementation, nicer one defined below if lxml> 2.0 is available
 def safe_cut(text, length):
@@ -123,6 +125,10 @@
         Note: the function considers a string with no surrounding tag as valid
               if <div>`data`</div> can be parsed by an XML parser
         """
+        # normalize line break
+        # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
+        data = u'\n'.join(data.splitlines())
+        # XXX lxml 1.1 support still needed ?
         xmltree = etree.HTML('<div>%s</div>' % data)
         # NOTE: lxml 1.1 (etch platforms) doesn't recognize
         #       the encoding=unicode parameter (lxml 2.0 does), this is
--- a/cwctl.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/cwctl.py	Wed Jul 01 11:33:40 2009 +0200
@@ -141,7 +141,7 @@
             if forkcmd:
                 status = system('%s %s' % (forkcmd, appid))
                 if status:
-                    sys.exit(status)
+                    print '%s exited with status %s' % (forkcmd, status)
             else:
                 self.run_arg(appid)
 
--- a/debian/changelog	Wed Jul 01 11:33:18 2009 +0200
+++ b/debian/changelog	Wed Jul 01 11:33:40 2009 +0200
@@ -1,3 +1,9 @@
+cubicweb (3.3.2-1) unstable; urgency=low
+
+  * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Thu, 25 Jun 2009 07:58:14 +0200
+
 cubicweb (3.3.1-1) unstable; urgency=low
 
   * new upstream release
--- a/debian/control	Wed Jul 01 11:33:18 2009 +0200
+++ b/debian/control	Wed Jul 01 11:33:40 2009 +0200
@@ -76,7 +76,7 @@
 Package: cubicweb-common
 Architecture: all
 XB-Python-Version: ${python:Versions}
-Depends: ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.6.0), python-logilab-common (>= 0.41.0), python-yams (>= 0.23.0), python-rql (>= 0.22.0)
+Depends: ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.6.0), python-logilab-common (>= 0.41.0), python-yams (>= 0.23.0), python-rql (>= 0.22.1)
 Recommends: python-simpletal (>= 4.0), python-lxml
 Conflicts: cubicweb-core
 Replaces: cubicweb-core
--- a/devtools/fake.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/devtools/fake.py	Wed Jul 01 11:33:40 2009 +0200
@@ -173,6 +173,8 @@
 
     def execute(self, *args):
         pass
+    unsafe_execute = execute
+    
     def commit(self, *args):
         self.transaction_data.clear()
     def close(self, *args):
--- a/devtools/repotest.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/devtools/repotest.py	Wed Jul 01 11:33:40 2009 +0200
@@ -117,7 +117,7 @@
     def tearDown(self):
         ExecutionPlan._check_permissions = _orig_check_permissions
         rqlannotation._select_principal = _orig_select_principal
-        
+
     def set_debug(self, debug):
         set_debug(debug)
 
@@ -208,6 +208,7 @@
 
 
 class BasePlannerTC(BaseQuerierTC):
+    newsources = 0
     def setup(self):
         clear_cache(self.repo, 'rel_type_sources')
         clear_cache(self.repo, 'rel_type_sources')
@@ -220,7 +221,6 @@
         self.schema = self.o.schema
         self.sources = self.o._repo.sources
         self.system = self.sources[-1]
-        self.newsources = 0
         do_monkey_patch()
 
     def add_source(self, sourcecls, uri):
--- a/doc/book/en/B000-development.en.txt	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/B000-development.en.txt	Wed Jul 01 11:33:40 2009 +0200
@@ -6,7 +6,7 @@
 Part II - Development
 =====================
 
-This part is about developing web applications with the `CubicWeb` framework.
+This part is about developing web applications with the *CubicWeb* framework.
 
 .. toctree::
    :maxdepth: 1
--- a/doc/book/en/B0015-define-permissions.en.txt	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/B0015-define-permissions.en.txt	Wed Jul 01 11:33:40 2009 +0200
@@ -11,7 +11,7 @@
 * permissions (read, update, create, delete)
 * permissions are assigned to groups (and not to users)
 
-For `CubicWeb` in particular:
+For *CubicWeb* in particular:
 
 * we associate rights at the enttities/relations schema level
 * for each entity, we distinguish four kind of permissions: read,
--- a/doc/book/en/MERGE_ME-tut-create-gae-app.en.txt	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/MERGE_ME-tut-create-gae-app.en.txt	Wed Jul 01 11:33:40 2009 +0200
@@ -7,7 +7,7 @@
 
 Ce tutoriel va vous guider pas à pas a construire une apllication web 
 de gestion de Blog afin de vous faire découvrir les fonctionnalités de
-`CubicWeb`.
+*CubicWeb*.
 
 Nous supposons que vous avec déjà suivi le guide :ref:`installationGAE`.
 
@@ -23,7 +23,7 @@
   
   cubicweb-ctl newgapp blogdemo
 
-`newgapp` est la commande permettant de créer une instance `CubicWeb` pour
+`newgapp` est la commande permettant de créer une instance *CubicWeb* pour
 le datastore.
 
 Assurez-vous que votre variable d'environnement ``PYTHONPATH`` est correctement
@@ -32,7 +32,7 @@
 Définissez un schéma
 --------------------
 
-Le modèle de données ou schéma est au coeur d'une application `CubicWeb`.
+Le modèle de données ou schéma est au coeur d'une application *CubicWeb*.
 C'est là où vous allez devoir définir le type de contenu que votre application
 devra gérer.
 
@@ -180,7 +180,7 @@
    :alt: displaying the detailed view of a blogentry
 
 Rappelez-vous que pour le moment, tout a été géré par la plate-forme
-`CubicWeb` et que la seule chose qui a été fournie est le schéma de
+*CubicWeb* et que la seule chose qui a été fournie est le schéma de
 données. D'ailleurs pour obtenir une vue graphique du schéma, exécutez
 la commande ``laxctl genschema blogdemo`` et vous pourrez visualiser
 votre schéma a l'URL suivante : http://localhost:8080/schema
--- a/doc/book/en/Z010-beginners.en.txt	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/Z010-beginners.en.txt	Wed Jul 01 11:33:40 2009 +0200
@@ -2,7 +2,7 @@
 
 .. _QuickInstall:
 
-Quick Installation of a `CubicWeb` instance
+Quick Installation of a *CubicWeb* instance
 ===========================================
 
 .. include:: C010-setup.en.txt
--- a/doc/book/en/Z012-create-instance.en.txt	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/Z012-create-instance.en.txt	Wed Jul 01 11:33:40 2009 +0200
@@ -7,7 +7,7 @@
 What is an instance?
 --------------------
 
-A `CubicWeb` instance is a container that
+A *CubicWeb* instance is a container that
 refers to cubes and configuration parameters for your web application.
 Each instance is stored as a directory in ``~/etc/cubicweb.d`` which enables 
 us to run your application.
@@ -26,12 +26,12 @@
 a debian package installation. For example, the 'blog' cube defines the entities 
 blogs and blogentries.
 
-When an `CubicWeb` instance is created, you list the cubes that you want to use. 
+When an *CubicWeb* instance is created, you list the cubes that you want to use. 
 Using a cube means having the entities defined in your cube's schema
 available in your instance as well as their views and workflows.
 
 
-Creating a basic `CubicWeb` Instance 
+Creating a basic *CubicWeb* Instance 
 ------------------------------------
 
 We can create an instance to view our
@@ -55,10 +55,10 @@
 (:ref:`ConfigurationPostgres`).
 
 It is important to distinguish here the user used to access the database and
-the user used to login to the cubicweb application. When a `CubicWeb` application
+the user used to login to the cubicweb application. When a *CubicWeb* application
 starts, it uses the login/psswd for the database to get the schema and handle
 low level transaction. But, when ``cubicweb-ctl create`` asks for
-a manager login/psswd of `CubicWeb`, it refers to an application user
+a manager login/psswd of *CubicWeb*, it refers to an application user
 to administrate your web application. 
 The configuration files are stored in *~/etc/cubicweb.d/myblog/*. 
 
--- a/doc/book/en/admin/create-instance.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/admin/create-instance.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -7,7 +7,7 @@
 -----------------
 
 Now that we created our cube, we can create an instance to view our
-application in a web browser. To do so we will use a `all-in-one` 
+application in a web browser. To do so we will use a `all-in-one`
 configuration to simplify things ::
 
   cubicweb-ctl create -c all-in-one mycube myinstance
@@ -27,7 +27,7 @@
 user used to login to the cubicweb application. When an instance starts, it uses
 the login/psswd for the database to get the schema and handle low level
 transaction. But, when :command:`cubicweb-ctl create` asks for a manager
-login/psswd of `CubicWeb`, it refers to the user you will use during the
+login/psswd of *CubicWeb*, it refers to the user you will use during the
 development to administrate your web application. It will be possible, later on,
 to use this user to create others users for your final web application.
 
@@ -45,8 +45,8 @@
 The option `-D` specify the *debug mode* : the instance is not running in
 server mode and does not disconnect from the termnial, which simplifies debugging
 in case the instance is not properly launched. You can see how it looks by
-visiting the URL `http://localhost:8080` (the port number depends of your 
-configuration). To login, please use the cubicweb administrator login/psswd you 
+visiting the URL `http://localhost:8080` (the port number depends of your
+configuration). To login, please use the cubicweb administrator login/psswd you
 defined when you created the instance.
 
 To shutdown the instance, Crtl-C in the terminal window is enough.
@@ -59,5 +59,6 @@
 
 upgrade
 ~~~~~~~
-XXX feed me
 
+XXX write me
+
--- a/doc/book/en/admin/gae.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/admin/gae.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -9,9 +9,9 @@
 `Google AppEngine`_ is provided with a partial port of the `Django`
 framework, but Google stated at Google IO 2008 that it would not
 support a specific Python web framework and that all
-community-supported frameworks would be more than welcome [1]_. 
+community-supported frameworks would be more than welcome [1]_.
 
-Therefore `Logilab`_ ported `CubicWeb` to run on top of `Google AppEngine`'s
+Therefore `Logilab`_ ported *CubicWeb* to run on top of `Google AppEngine`'s
 datastore.
 
 .. _`Google AppEngine`: http://code.google.com/appengine/docs/whatisgoogleappengine.html
@@ -25,8 +25,8 @@
   http://code.google.com/appengine/downloads.html
 
 
-Please follow instructions on how to install `CubicWeb` framework
-(:ref:`CubicWebInstallation`). 
+Please follow instructions on how to install *CubicWeb* framework
+(:ref:`CubicWebInstallation`).
 
 Installation
 ------------
@@ -37,7 +37,7 @@
    cubicweb-ctl newgapp <myapp>
 
 This will create a directory containing ::
- 
+
    `-- myapp/
        |-- app.conf
        |-- app.yaml
@@ -73,17 +73,17 @@
        |-- yams/
        `-- yapps/
 
-  
+
 This skeleton directory is a working `AppEngine` application. You will
 recognize the files ``app.yaml`` and ``main.py``. All the rest is the
-`CubicWeb` framework and its third-party libraries. You will notice that 
+*CubicWeb* framework and its third-party libraries. You will notice that
 the directory ``cubes`` is a library of reusable cubes.
 
 The main directories that you should know about are:
 
-  - ``cubes`` : this is a library of reusable yams cubes. To use 
-    those cubes you will list them in the variable 
-    `included-yams-cubes` of ``app.conf``. See also :ref:`cubes`. 
+  - ``cubes`` : this is a library of reusable yams cubes. To use
+    those cubes you will list them in the variable
+    `included-yams-cubes` of ``app.conf``. See also :ref:`cubes`.
   - [WHICH OTHER ONES SHOULD BE LISTED HERE?]
 
 Dependencies
@@ -91,7 +91,7 @@
 
 Before starting anything, please make sure the following packages are installed:
   - yaml : by default google appengine is providing yaml; make sure you can
-    import it. We recommend you create a symbolic link yaml instead of installing 
+    import it. We recommend you create a symbolic link yaml instead of installing
     and using python-yaml:
     yaml -> full/path/to/google_appengine/lib/yaml/lib/yaml/
   - gettext
@@ -99,13 +99,13 @@
 Setup
 ~~~~~
 
-Once you executed ``cubicweb-ctl newgapp <myapp>``, you can use that ``myapp/`` 
+Once you executed ``cubicweb-ctl newgapp <myapp>``, you can use that ``myapp/``
 as an application directory and do as follows.
 
-This installation directory provides a configuration for an instance of `CubicWeb`
-ported for Google App Engine. It is installed with its own command ``laxctl`` 
-which is a port of the command tool ``cubicweb-ctl`` originally developped for 
-`CubicWeb`.
+This installation directory provides a configuration for an instance of *CubicWeb*
+ported for Google App Engine. It is installed with its own command ``laxctl``
+which is a port of the command tool ``cubicweb-ctl`` originally developped for
+*CubicWeb*.
 
 You can have the details of available commands by running ::
 
@@ -115,11 +115,11 @@
 Generating translation files
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-`CubicWeb` is fully internationalized. Translation catalogs are found in
+*CubicWeb* is fully internationalized. Translation catalogs are found in
 ``myapp/i18n``. To compile the translation files, use the `gettext` tools
 or the ``laxctl`` command ::
 
-  $ python myapp/bin/laxctl i18ncube 
+  $ python myapp/bin/laxctl i18ncube
   $ python myapp/bin/laxctl i18ninstance
 
 Ignore the errors that print "No translation file found for domain
@@ -132,7 +132,7 @@
 You will never need to add new entries in the translation catalog. Instead we would
 recommand you to use ``self.req._("msgId")`` in your application code
 to flag new message id to add to the catalog, where ``_`` refers to
-xgettext that is used to collect new strings to translate. 
+xgettext that is used to collect new strings to translate.
 While running ``laxctl i18ncube``, new string will be added to the catalogs.
 
 Generating the data directory
@@ -165,7 +165,7 @@
  
   # does this application rely on google authentication service or not.
   use-google-auth=no
- 
+
 In ``app.yaml`` comment the `login: required` set by default in the handler::
 
   - url: .*
@@ -187,8 +187,8 @@
 
   $ python /path/to/google_appengine/dev_appserver.py /path/to/myapp/
 
-Once the local server is started, visit `http://MYAPP_URL/_load <http://localhost:8080/_load>`_ and sign in as administrator. 
-This will initialize the repository and enable you to log in into 
+Once the local server is started, visit `http://MYAPP_URL/_load <http://localhost:8080/_load>`_ and sign in as administrator.
+This will initialize the repository and enable you to log in into
 the application and continue the installation.
 
 You should be redirected to a page displaying a message `content initialized`.
@@ -197,7 +197,7 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
 You, then, want to visit  `http://MYAPP_URL/?vid=authinfo <http://localhost:8080/?vid=authinfo>`_ .
-If you selected not  to use google authentication, you will be prompted to a 
+If you selected not  to use google authentication, you will be prompted to a
 login form where you should initialize the administrator login (recommended
 to use admin/admin at first). You will then be redirected to a page providing
 you the value to provide to ``./bin/laxctl --cookie``.
@@ -212,21 +212,21 @@
    :alt: displaying the detailed view of the cookie values returned
 
 
-.. note:: In case you are not redirected to a page providing the 
-   option --cookie value, please visit one more time  
+.. note:: In case you are not redirected to a page providing the
+   option --cookie value, please visit one more time
    `http://MYAPP_URL/?vid=authinfo <http://localhost:8080/?vid=authinfo>`_ .
 
 Once, you have this value, then return to the shell and execute ::
- 
+
   $ python myapp/bin/laxctl db-init --cookie='dev_appserver_login=test@example.com:True; __session=7bbe973a6705bc5773a640f8cf4326cc' localhost:8080
 
 .. note:: In the case you are not using google authentication, the value returned
-   by `http://MYAPP_URL/?vid=authinfo <http://localhost:8080/?vid=authinfo>`_ 
+   by `http://MYAPP_URL/?vid=authinfo <http://localhost:8080/?vid=authinfo>`_
    will look like :
    --cookie='__session=2b45d1a9c36c03d2a30cedb04bc37b6d'
 
 Log out by clicking in the menu at the top right corner
-and restart browsing from `http://MYAPP_URL/ <http://localhost:8080>`_ 
+and restart browsing from `http://MYAPP_URL/ <http://localhost:8080>`_
 as a normal user.
 
 Unless you did something to change it, http://MYAPP_URL should be
--- a/doc/book/en/admin/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/admin/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -6,7 +6,7 @@
 Part III - Administration
 -------------------------
 
-This part is for installation and administration of the `CubicWeb` framework and
+This part is for installation and administration of the *CubicWeb* framework and
 applications based on that framework.
 
 .. toctree::
@@ -25,7 +25,7 @@
 RQL logs
 --------
 
-You can configure the `CubicWeb` application to keep a log
+You can configure the *CubicWeb* application to keep a log
 of the queries executed against your database. To do so,
 edit the configuration file of your application
 ``.../etc/cubicweb.d/myapp/all-in-one.conf`` and uncomment the
--- a/doc/book/en/admin/instance-config.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/admin/instance-config.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -51,7 +51,7 @@
      RewriteCond %(REQUEST_URI) ^/demo
      RewriteRule ^/demo$ /demo/
      RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
-  
+
    and for the https:::
 
      RewriteCond %(REQUEST_URI) ^/ demo
--- a/doc/book/en/admin/setup.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/admin/setup.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,13 +3,13 @@
 .. _SetUpEnv:
 
 ===================================================
-Installation and set-up of a `CubicWeb` environment
+Installation and set-up of a *CubicWeb* environment
 ===================================================
 
 Installation of `Cubicweb` and its dependencies
 -----------------------------------------------
 
-`CubicWeb` is packaged for Debian and Ubuntu, but can be installed from source
+*CubicWeb* is packaged for Debian and Ubuntu, but can be installed from source
 using a tarball or the Mercurial version control system.
 
 .. _DebianInstallation:
@@ -35,7 +35,7 @@
 
 You can now install the required packages with the following command::
 
-  apt-get update 
+  apt-get update
   apt-get install cubicweb cubicweb-dev
 
 `cubicweb` installs the framework itself, allowing you to create
@@ -88,13 +88,13 @@
 Environment configuration
 -------------------------
 
-If you installed `CubicWeb` by cloning the Mercurial forest, then you
-will need to update the environment variable PYTHONPATH by adding  
+If you installed *CubicWeb* by cloning the Mercurial forest, then you
+will need to update the environment variable PYTHONPATH by adding
 the path to the forest ``cubicweb``:
 
 Add the following lines to either `.bashrc` or `.bash_profile` to configure
 your development environment ::
-  
+
   export PYTHONPATH=/full/path/to/cubicweb-forest
 
 If you installed the debian packages, no configuration is required.
@@ -134,34 +134,34 @@
 
     $ initdb -D /path/to/pgsql
 
-  Once initialized, start the database server Postgres 
+  Once initialized, start the database server Postgres
   with the command::
-  
+
     $ postgres -D /path/to/psql
 
   If you cannot execute this command due to permission issues, please
   make sure that your username has write access on the database.
   ::
- 
+
     $ chown username /path/to/pgsql
 
 * The database authentication can be either set to `ident sameuser`
-  or `md5`. 
+  or `md5`.
   If set to `md5`, make sure to use an existing user
   of your database.
   If set to `ident sameuser`, make sure that your
   client's operating system user name has a matching user in
   the database. If not, please do as follow to create a user::
-    
+
     $ su
     $ su - postgres
     $ createuser -s -P username
 
   The option `-P` (for password prompt), will encrypt the password with
-  the method set in the configuration file ``pg_hba.conf``. 
+  the method set in the configuration file ``pg_hba.conf``.
   If you do not use this option `-P`, then the default value will be null
   and you will need to set it with::
-    
+
     $ su postgres -c "echo ALTER USER username WITH PASSWORD 'userpasswd' | psql"
 
   This login/password will be requested when you will create an
--- a/doc/book/en/admin/site-config.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/admin/site-config.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -14,12 +14,12 @@
 This menu provides you a way to adjust some navigation options depending on
 your needs, such as the number of entities to display by page of results.
 Follows the detailled list of available options :
-  
+
 * navigation.combobox-limit : maximum number of entities to display in related
   combo box (sample format: 23)
-* navigation.page-size : maximum number of objects displayed by page of results 
+* navigation.page-size : maximum number of objects displayed by page of results
   (sample format: 23)
-* navigation.related-limit : maximum number of related entities to display in 
+* navigation.related-limit : maximum number of related entities to display in
   the primary view (sample format: 23)
 * navigation.short-line-size : maximum number of characters in short description
   (sample format: 23)
@@ -47,17 +47,17 @@
 Actions
 ~~~~~~~
 This menu provides a way to configure the context in which you expect the actions
-to be displayed to the user and if you want the action to be visible or not. 
-You must have notice that when you view a list of entities, an action box is 
-available on the left column which display some actions as well as a drop-down 
-menu for more actions. 
+to be displayed to the user and if you want the action to be visible or not.
+You must have notice that when you view a list of entities, an action box is
+available on the left column which display some actions as well as a drop-down
+menu for more actions.
 
 The context available are :
 
 * mainactions : actions listed in the left box
 * moreactions : actions listed in the `more` menu of the left box
 * addrelated : add actions listed in the left box
-* useractions : actions listed in the first section of drop-down menu 
+* useractions : actions listed in the first section of drop-down menu
   accessible from the right corner user login link
 * siteactions : actions listed in the second section of drop-down menu
   accessible from the right corner user login link
@@ -65,15 +65,15 @@
 
 Boxes
 ~~~~~
-The application has already a pre-defined set of boxes you can use right away. 
+The application has already a pre-defined set of boxes you can use right away.
 This configuration section allows you to place those boxes where you want in the
-application interface to customize it. 
+application interface to customize it.
 
 The available boxes are :
 
 * actions box : box listing the applicable actions on the displayed data
 
-* boxes_blog_archives_box : box listing the blog archives 
+* boxes_blog_archives_box : box listing the blog archives
 
 * possible views box : box listing the possible views for the displayed data
 
@@ -81,7 +81,7 @@
 
 * search box : search box
 
-* startup views box : box listing the configuration options available for 
+* startup views box : box listing the configuration options available for
   the application site, such as `Preferences` and `Site Configuration`
 
 Components
--- a/doc/book/en/annexes/cookbook.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/cookbook.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -7,10 +7,10 @@
 life easier.
 
 
-* How to import LDAP users in `CubicWeb`?
+* How to import LDAP users in *CubicWeb*?
 
   Here is a very useful script which enables you to import LDAP users
-  into your `CubicWeb` application by running the following: ::
+  into your *CubicWeb* application by running the following: ::
 
 
     import os
@@ -70,11 +70,11 @@
   you would not be able to use dbapi. ::
 
     from cubicweb import dbapi
-        
+
     cnx = dbapi.connection(database='instance-id', user='admin', password='admin')
     cur = cnx.cursor()
     for name in ('Personal', 'Professional', 'Computers'):
         cur.execute('INSERT Blog B: B name %s', name)
     cnx.commit()
 
-    
+
--- a/doc/book/en/annexes/cubicweb-ctl.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/cubicweb-ctl.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -5,7 +5,7 @@
 ``cubicweb-ctl`` tool
 =====================
 
-`cubicweb-ctl` is the swiss knife to manage `CubicWeb` instances.
+`cubicweb-ctl` is the swiss knife to manage *CubicWeb* instances.
 The general syntax is ::
 
   cubicweb-ctl <command> [options command] <arguments commands>
@@ -15,7 +15,7 @@
   cubicweb-ctl
   cubicweb-ctl --help
 
-Please note that the commands available depends on the `CubicWeb` packages
+Please note that the commands available depends on the *CubicWeb* packages
 and cubes that have been installed.
 
 To view the help menu on specific command ::
@@ -28,7 +28,7 @@
 * ``newcube``, create a new cube on the file system based on the name
   given in the parameters. This command create a cube from an application
   skeleton that includes default files required for debian packaging.
-  
+
 
 Command to create an instance
 -----------------------------
@@ -62,7 +62,7 @@
 Commands to maintain instances
 ------------------------------
 * ``upgrade``, launches the existing instances migration when a new version
-  of `CubicWeb` or the cubes installed is available
+  of *CubicWeb* or the cubes installed is available
 * ``shell``, opens a migration shell for manual maintenance of the instance
 * ``db-dump``, creates a dump of the system database
 * ``db-restore``, restores a dump of the system database
@@ -73,9 +73,9 @@
 
 Commands to maintain i18n catalogs
 ----------------------------------
-* ``i18ncubicweb``, regenerates messages catalogs of the `CubicWeb` library
+* ``i18ncubicweb``, regenerates messages catalogs of the *CubicWeb* library
 * ``i18ncube``, regenerates the messages catalogs of a cube
-* ``i18ninstance``, recompiles the messages catalogs of an instance. 
+* ``i18ninstance``, recompiles the messages catalogs of an instance.
   This is automatically done while upgrading.
 
 See also chapter :ref:`internationalisation`.
@@ -116,7 +116,7 @@
 
 This will create a new cube in ``/path/to/forest/cubicweb/cubes/<mycube>``
 for a Mercurial forest installation, or in ``/usr/share/cubicweb/cubes``
-for a debian packages installation, and then create an instance as 
+for a debian packages installation, and then create an instance as
 explained just above.
 
 
--- a/doc/book/en/annexes/faq.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/faq.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -18,12 +18,12 @@
   preferred template language if you want. [explain how to use a
   template language]
 
-  `CubicWeb` does not define its own templating language as this was
+  *CubicWeb* does not define its own templating language as this was
   not our goal. Based on our experience, we realized that
   we could gain productivity by letting designers use design tools
   and developpers develop without the use of the templating language
   as an intermediary that could not be anyway efficient for both parties.
-  Python is the templating language that we use in `CubicWeb`, but again,
+  Python is the templating language that we use in *CubicWeb*, but again,
   it does not prevent you from using a templating language.
 
   The reason template languages are not used in this book is that
@@ -46,14 +46,14 @@
   robust application.
 
 Why do you use the LGPL license to prevent me from doing X ?
------------------------------------------------------------
+------------------------------------------------------------
 
   LGPL means that *if* you redistribute your application, you need to
   redistribute the changes you made to CubicWeb under the LGPL licence.
 
   Publishing a web site has nothing to do with redistributing
   source code. A fair amount of companies use modified LGPL code
-  for internal use. And someone could publish a `CubicWeb` component
+  for internal use. And someone could publish a *CubicWeb* component
   under a BSD licence for others to plug into a LGPL framework without
   any problem. The only thing we are trying to prevent here is someone
   taking the framework and packaging it as closed source to his own
@@ -92,26 +92,28 @@
 [copy answer from forum, explain why similar to sparql and why better
   than django and SQL]
 
-which ajax library
-------------------
-[we use jquery and things on top of that]
+which ajax library is CubicWeb using ?
+--------------------------------------
+
+[CubicWeb uses jQuery and adds a thin layer on top of that]
 
 
-How to implement security?
---------------------------
+How is security implemented ?
+------------------------------
 
   This is an example of how it works in our framework::
 
     class Version(EntityType):
-    """a version is defining the content of a particular project's
-    release"""
-    # definition of attributes is voluntarily missing
-    permissions = {'read': ('managers', 'users', 'guests',),
-                   'update': ('managers', 'logilab', 'owners',),
-                   'delete': ('managers', ),
-                   'add': ('managers', 'logilab',
-                        ERQLExpression('X version_of PROJ, U in_group G, PROJ
-                        require_permission P, P name "add_version", P require_group G'),)}
+        """a version is defining the content of a particular project's
+        release"""
+        # definition of attributes is voluntarily missing
+        permissions = {'read': ('managers', 'users', 'guests',),
+                       'update': ('managers', 'logilab', 'owners',),
+                       'delete': ('managers', ),
+                       'add': ('managers', 'logilab',
+                           ERQLExpression('X version_of PROJ, U in_group G, '
+                                          'PROJ require_permission P, '
+                                          'P name "add_version", P require_group G'),)}
 
   The above means that permission to read a Version is granted to any
   user that is part of one of the groups 'managers', 'users', 'guests'.
@@ -124,7 +126,7 @@
         """link a version to its project. A version is necessarily linked
         to one and only one project. """
         # some lines voluntarily missing
-        permissions = {'read': ('managers', 'users', 'guests',), 
+        permissions = {'read': ('managers', 'users', 'guests',),
                        'delete': ('managers', ),
                        'add': ('managers', 'logilab',
                             RRQLExpression('O require_permission P, P name "add_version",
@@ -135,8 +137,9 @@
   [XXX what does the second example means in addition to the first one?]
 
 
-`Error while publishing rest text ...`
---------------------------------------
+What is `Error while publishing rest text ...` ?
+------------------------------------------------
+
   While modifying the description of an entity, you get an error message in
   the application `Error while publishing ...` for Rest text and plain text.
   The server returns a traceback like as follows ::
@@ -152,8 +155,8 @@
   This can be fixed by applying the patch described in :
   http://code.google.com/p/googleappengine/issues/detail?id=48
 
-What are hooks used for?
-------------------------
+What are hooks used for ?
+-------------------------
 
   Hooks are executed around (actually before or after) events.  The
   most common events are data creation, update and deletion.  They
@@ -166,8 +169,8 @@
   Other kinds of hooks, called Operations, are available
   for execution just before commit.
 
-When should you define an HTML template rather than define a graphical component?
----------------------------------------------------------------------------------
+When should you define an HTML template rather than define a graphical component ?
+----------------------------------------------------------------------------------
 
   An HTML template cannot contain code, hence it is only about static
   content.  A component is made of code and operations that apply on a
@@ -180,15 +183,15 @@
   `AppRsetObject` instances are selected on a request and a result
   set. `AppObject` instances are directly selected by id.
 
-How to update a database after a schema modification?
------------------------------------------------------
+How to update a database after a schema modification ?
+------------------------------------------------------
 
   It depends on what has been modified in the schema.
 
-  * Update of an attribute permissions and properties: 
+  * Update of an attribute permissions and properties:
     ``synchronize_eschema('MyEntity')``.
 
-  * Update of a relation permissions and properties: 
+  * Update of a relation permissions and properties:
     ``synchronize_rschema('MyRelation')``.
 
   * Add an attribute: ``add_attribute('MyEntityType', 'myattr')``.
@@ -196,8 +199,8 @@
   * Add a relation: ``add_relation_definition('SubjRelation', 'MyRelation', 'ObjRelation')``.
 
 
-How to create an anonymous user?
---------------------------------
+How to create an anonymous user ?
+---------------------------------
 
   This allows to bypass authentication for your site. In the
   ``all-in-one.conf`` file of your instance, define the anonymous user
@@ -222,8 +225,8 @@
     decribed above.
 
 
-How to change the application logo?
------------------------------------
+How to change the application logo ?
+------------------------------------
 
   There are two ways of changing the logo.
 
@@ -239,11 +242,11 @@
 
        LOGO = DATADIR/path/to/mylogo.gif
 
-     where DATADIR is ``mycubes/data``.
+     where DATADIR is ``mycube/data``.
 
 
-How to configure LDAP source?
--------------------------------
+How to configure a LDAP source ?
+--------------------------------
 
   Your instance's sources are defined in ``/etc/cubicweb.d/myapp/sources``.
   Configuring an LDAP source is about declaring that source in your
@@ -269,7 +272,7 @@
   Any change applied to configuration file requires to restart your
   application.
 
-I get NoSelectableObject exceptions: how do I debug selectors ?
+I get NoSelectableObject exceptions, how do I debug selectors ?
 ---------------------------------------------------------------
 
   You just need to put the appropriate context manager around view/component
@@ -296,28 +299,28 @@
 
     2009-01-09 16:43:52 - (cubicweb.selectors) WARNING: selector one_line_rset returned 0 for <class 'cubicweb.web.views.basecomponents.WFHistoryVComponent'>
 
-How to format an entity date attribute?
----------------------------------------
+How to format an entity date attribute ?
+----------------------------------------
 
   If your schema has an attribute of type Date or Datetime, you might
   want to format it. First, you should define your preferred format using
   the site configuration panel ``http://appurl/view?vid=systempropertiesform``
   and then set ``ui.date`` and/or ``ui.datetime``.
   Then in the view code, use::
-    
+
     self.format_date(entity.date_attribute)
 
 Can PostgreSQL and CubicWeb authentication work with kerberos ?
 ----------------------------------------------------------------
 
-  If you have postgresql set up to accept kerberos authentication, you can set
+  If you have PostgreSQL set up to accept kerberos authentication, you can set
   the db-host, db-name and db-user parameters in the `sources` configuration
-  file while leaving the password blank. It should be enough for your instance
-  to connect to postgresql with a kerberos ticket.
+  file while leaving the password blank. It should be enough for your
+  application to connect to postgresql with a kerberos ticket.
 
-  
-How to load data from a script?
--------------------------------
+
+How to load data from a script ?
+--------------------------------
 
   The following script aims at loading data within a script assuming pyro-nsd is
   running and your application is configured with ``pyro-server=yes``, otherwise
@@ -331,8 +334,8 @@
         cur.execute('INSERT Blog B: B name %s', name)
     cnx.commit()
 
-What is the CubicWeb datatype corresponding to GAE datastore's UserProperty?
-----------------------------------------------------------------------------
+What is the CubicWeb datatype corresponding to GAE datastore's UserProperty ?
+-----------------------------------------------------------------------------
 
   If you take a look at your application schema and
   click on "display detailed view of metadata" you will see that there
@@ -348,8 +351,8 @@
   mapping Google Accounts to local Euser entities automatically]
 
 
-How to reset the password for user joe?
----------------------------------------
+How to reset the password for user joe ?
+----------------------------------------
 
   You need to generate a new encrypted password::
 
@@ -357,7 +360,7 @@
     >>> from cubicweb.server.utils import crypt_password
     >>> crypt_password('joepass')
     'qHO8282QN5Utg'
-    >>> 
+    >>>
 
   and paste it in the database::
 
--- a/doc/book/en/annexes/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -7,7 +7,7 @@
 --------------------
 
 The following chapters are reference material.
- 
+
 .. toctree::
    :maxdepth: 1
 
--- a/doc/book/en/annexes/mercurial.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/mercurial.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -12,7 +12,7 @@
 next, and so on). Locally, we have a repository containing revisions
 tree, and a working directory. It is possible
 to put in its working directory, one of the versions of its local repository,
-modify and then push it in its repository. 
+modify and then push it in its repository.
 It is also possible to get revisions from another repository or to export
 its own revisions from the local repository to another repository.
 
@@ -83,7 +83,7 @@
 
      hg incoming ssh://myhost//home/src/repo
 
-* See what is the revision of the local repository which has been taken out 
+* See what is the revision of the local repository which has been taken out
   from the working directory and amended::
 
      hg parent
@@ -114,8 +114,8 @@
 Installation of the forest extension
 ````````````````````````````````````
 
-Set up the forest extension by getting a copy of the sources 
-from http://hg.akoha.org/hgforest/ and adding the following 
+Set up the forest extension by getting a copy of the sources
+from http://hg.akoha.org/hgforest/ and adding the following
 lines to your ``~/.hgrc``: ::
 
    [extensions]
--- a/doc/book/en/annexes/rql/implementation.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/rql/implementation.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -53,7 +53,7 @@
 
      relation    ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
                    | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
-                   
+
      expression  ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
                    | '(' expression ')'
 
@@ -83,7 +83,7 @@
 Internal representation (syntactic tree)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The tree research does not contain the selected variables 
+The tree research does not contain the selected variables
 (e.g. there is only what follows "WHERE").
 
 The insertion tree does not contain the variables inserted or relations
@@ -156,7 +156,7 @@
 
      Document class Type <-> Document occurence_of Fiche class Type
      Sheet class Type    <-> Form collection Collection class Type
-    
+
 Therefore 1. becomes::
 
      Document X where
--- a/doc/book/en/annexes/rql/intro.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/rql/intro.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -11,8 +11,8 @@
 user should see virtually no difference between an attribute and a
 relation).
 
-RQL is inspired by SQL but is the highest level. A knowledge of the 
-`CubicWeb` schema defining the application is necessary.
+RQL is inspired by SQL but is the highest level. A knowledge of the
+*CubicWeb* schema defining the application is necessary.
 
 Comparison with existing languages
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -21,8 +21,8 @@
 ```
 RQL builds on the features of SQL but is at a higher level
 (the current implementation of RQL generates SQL). For that it is limited
-to the way of browsing relations and introduces variables. 
-The user does not need to know the model underlying SQL, but the `CubicWeb` 
+to the way of browsing relations and introduces variables.
+The user does not need to know the model underlying SQL, but the *CubicWeb*
 schema defining the application.
 
 Versa
@@ -30,16 +30,16 @@
 We should look in more detail, but here are already some ideas for
 the moment ... Versa_ is the language most similar to what we wanted
 to do, but the model underlying data being RDF, there is some
-number of things such as namespaces or handling of the RDF types which 
+number of things such as namespaces or handling of the RDF types which
 does not interest us. On the functionality level, Versa_ is very comprehensive
 including through many functions of conversion and basic types manipulation,
-which may need to be guided at one time or another. 
+which may need to be guided at one time or another.
 Finally, the syntax is a little esoteric.
 
 Sparql
 ``````
 The query language most similar to RQL is SPARQL_, defined by the W3C to serve
-for the semantic web. 
+for the semantic web.
 
 
 The different types of queries
@@ -59,7 +59,7 @@
 Delete entities or relationship (`DELETE`)
    Remove entities or relations existing in the database.
 
-   
+
 
 
 .. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
--- a/doc/book/en/annexes/rql/language.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/annexes/rql/language.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -67,7 +67,7 @@
   of logical operators (see :ref:`PriorityOperators`).
 
 Mathematical Operators
-````````````````````
+```````````````````````
 ::
 
      +, -, *, /
@@ -81,7 +81,7 @@
 * The operator `=` is the default operator.
 
 * The operator `LIKE` equivalent to `~=` can be used with the
-  special character `%` in a string to indicate that the chain 
+  special character `%` in a string to indicate that the chain
   must start or finish by a prefix/suffix:
   ::
 
@@ -90,11 +90,11 @@
 
 * The operator `IN` provides a list of possible values:
   ::
-  
+
     Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
 
 
-XXX nico: "A trick <> 'bar'" wouldn't it be more convenient than 
+XXX nico: "A trick <> 'bar'" wouldn't it be more convenient than
 "NOT A trick 'bar'" ?
 
 .. _PriorityOperators:
@@ -130,7 +130,7 @@
    Type of selected variables.
    The special type `Any` is equivalent to not specify a type.
 :restriction:
-   list of conditions to test successively 
+   list of conditions to test successively
      `V1 relation V2 | <static value>`
 :orderterms:
    Definition of the selection order: variable or column number followed by
@@ -167,7 +167,7 @@
 Identity
 ````````
 
-You can use the special relation `identity` in a query to 
+You can use the special relation `identity` in a query to
 add an identity constraint between two variables. This is equivalent
 to ``is`` in python::
 
@@ -181,23 +181,23 @@
 Limit / offset
 ``````````````
 ::
-    
+
     Any P ORDERBY N LIMIT 5 OFFSET 10 WHERE P is Person, P firstname N
 
 Function calls
 ``````````````
 ::
-    
+
     Any UPPER(N) WHERE P firstname N
 
 Functions on string: UPPER, LOWER
-    
+
 Exists
 ``````
 ::
-    
+
     Any X ORDERBY PN,N
-    WHERE X num N, X version_of P, P name PN, 
+    WHERE X num N, X version_of P, P name PN,
           EXISTS(X in_state S, S name IN ("dev", "ready"))
           OR EXISTS(T tags X, T name "priority")
 
@@ -219,12 +219,12 @@
        Any C, P WHERE C is Card, P? documented_by C
 
     Any T,P,V WHERE T is Ticket, T concerns P, T done_in V?
-    
-    
+
+
 Having
 ``````
 ::
-    
+
     Any X GROUPBY X WHERE X knows Y HAVING COUNT(Y) > 10
 
 Subqueries
@@ -232,14 +232,14 @@
 ::
 
     (Any X WHERE X is Person) UNION (Any X WHERE X is Company)
-    
+
 
      DISTINCT Any W, REF
-        WITH W, REF BEING 
+        WITH W, REF BEING
             (
-	      (Any W, REF WHERE W is Workcase, W ref REF, 
+	      (Any W, REF WHERE W is Workcase, W ref REF,
                                  W concerned_by D, D name "Logilab")
-               UNION 
+               UNION
               (Any W, REF WHERE W is Workcase, W ref REF, '
                                 W split_into WP, WP name "WP1")
             )
@@ -317,7 +317,7 @@
 
 The restriction can define variables used in assignments.
 
-Caution, if a restriction is specified, the insertion is done for 
+Caution, if a restriction is specified, the insertion is done for
 *each line result returned by the restriction*.
 
 - *Insert a new person named 'foo'*
@@ -331,7 +331,7 @@
 
         INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
 
-- *Insert a new person named 'foo' and a 'friend' relation with an existing 
+- *Insert a new person named 'foo' and a 'friend' relation with an existing
   person called 'nice'*
   ::
 
@@ -350,7 +350,7 @@
 
         SET X name 'bar', X first_name 'original' WHERE X is Person, X name 'foo'
 
-- *Insert a relation of type 'know' between objects linked by 
+- *Insert a relation of type 'know' between objects linked by
   the relation of type 'friend'*
   ::
 
--- a/doc/book/en/development/cubes/cc-newcube.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/cubes/cc-newcube.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -7,7 +7,7 @@
 
   cubicweb-ctl newcube mycube
 
-  # answer questions 
+  # answer questions
   hg init moncube
   cd mycube
   hg add .
@@ -31,12 +31,12 @@
     the source code of your cube:
     ``cubicweb-ctl newcube --directory=/path/to/cubes/library cube_name``
 
-    
+
 Usage of :command:`cubicweb-ctl liveserver`
 -------------------------------------------
 
 To quickly test a new cube, you can also use the `liveserver` command for cubicweb-ctl
-which allows to create an instance in memory (using an SQLite database by 
+which allows to create an instance in memory (using an SQLite database by
 default) and make it accessible through a web server ::
 
   cubicweb-ctl live-server mycube
--- a/doc/book/en/development/datamodel/baseschema.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/datamodel/baseschema.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,7 +3,7 @@
 ----------------------------------
 
 The library defines a set of entity schemas that are required by the system
-or commonly used in `CubicWeb` applications.
+or commonly used in *CubicWeb* applications.
 
 
 Entity types used to store the schema
@@ -24,7 +24,7 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * `State`, workflow state
 * `Transition`, workflow transition
-* `TrInfo`, record of a transition trafic for an entity 
+* `TrInfo`, record of a transition trafic for an entity
 
 Other entity types
 ~~~~~~~~~~~~~~~~~~
--- a/doc/book/en/development/datamodel/define-workflows.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/datamodel/define-workflows.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -8,30 +8,30 @@
 General
 -------
 
-A workflow describes how certain entities have to evolve between 
-different states. Hence we have a set of states, and a "transition graph", 
+A workflow describes how certain entities have to evolve between
+different states. Hence we have a set of states, and a "transition graph",
 i.e. a list of possible transitions from one state to another state.
 
-We will define a simple workflow for a blog, with only the following 
-two states: `submitted` and `published`. So first, we create a simple 
-`CubicWeb` in ten minutes (see :ref:`BlogTenMinutes`).
+We will define a simple workflow for a blog, with only the following
+two states: `submitted` and `published`. So first, we create a simple
+*CubicWeb* in ten minutes (see :ref:`BlogFiveMinutes`).
 
 Set-up a workflow
 -----------------
 
-We want to create a workflow to control the quality of the BlogEntry 
+We want to create a workflow to control the quality of the BlogEntry
 submitted on your application. When a BlogEntry is created by a user
 its state should be `submitted`. To be visible to all, it has to
 be in the state `published`. To move it from `submitted` to `published`,
 we need a transition that we can call `approve_blogentry`.
 
 A BlogEntry state should not be modifiable by every user.
-So we have to define a group of users, `moderators`, and 
+So we have to define a group of users, `moderators`, and
 this group will have appropriate permissions to publish a BlogEntry.
 
 There are two ways to create a workflow: from the user interface,
-or by defining it in ``migration/postcreate.py``. 
-This script is executed each time a new ``cubicweb-ctl db-init`` is done. 
+or by defining it in ``migration/postcreate.py``.
+This script is executed each time a new ``cubicweb-ctl db-init`` is done.
 We strongly recommand to create the workflow in ``migration/postcreate.py``
 and we will now show you how. Read `Under the hood`_ to understand why.
 
@@ -60,13 +60,13 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The ``postcreate.py`` script is executed in a special environment, adding
-several `CubicWeb` primitives that can be used.
+several *CubicWeb* primitives that can be used.
 They are all defined in the ``class ServerMigrationHelper``.
 We will only discuss the methods we use to create a workflow in this example.
 
 To define our workflow for BlogDemo, please add the following lines
 to ``migration/postcreate.py``::
-  
+
   _ = unicode
 
   moderators = add_entity('CWGroup', name=u"moderators")
@@ -88,12 +88,12 @@
   add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
 
 
-``add_transition`` expects 
+``add_transition`` expects
 
   * as the first argument the name of the
     transition, then the entity type on which the transition can be applied,
   * then the list of states on which the transition can be trigged,
-  * the target state of the transition, 
+  * the target state of the transition,
   * and the permissions
     (e.g. a list of user groups who can apply the transition; the user
     has to belong to at least one of the listed group to perform the action).
@@ -106,11 +106,11 @@
   Do not forget to add the `_()` in front of all states and transitions names while creating
   a workflow so that they will be identified by the i18n catalog scripts.
 
-In addition to the user group condition, we could have added a RQL condition. 
-In this case, the user can only perform the action if 
-the two conditions are satisfied. 
+In addition to the user group condition, we could have added a RQL condition.
+In this case, the user can only perform the action if
+the two conditions are satisfied.
 
-If we use a RQL condition on a transition, we can use the following 
+If we use a RQL condition on a transition, we can use the following
 variables:
 
 * `%(eid)s`, object's eid
@@ -123,7 +123,7 @@
 You can notice that in the action box of a BlogEntry, the state
 is now listed as well as the possible transitions defined by the workflow.
 The transitions will only be displayed for users having the right permissions.
-In our example, the transition `approve_blogentry` will only be displayed 
+In our example, the transition `approve_blogentry` will only be displayed
 for the users belonging to the group `moderators` or `managers`.
 
 
@@ -131,7 +131,7 @@
 ~~~~~~~~~~~~~~
 
 A workflow is a collection of entities of type ``State`` and of type ``Transition``
-which are standard `CubicWeb` entity types.
+which are standard *CubicWeb* entity types.
 For instance, the following lines::
 
   submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
@@ -141,7 +141,7 @@
 with name 'published'. Whereas::
 
   add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
- 
+
 will create an entity of type ``Transition`` with name 'approve_blogentry' which will
 be linked to the ``State`` entities created before.
 As a consequence, we could use the administration interface to do these operations.
@@ -151,8 +151,8 @@
 
 Indeed, if you create the states and transitions through the user interface,
 next time you initialize the database
-you will have to re-create all the entities. 
-The user interface should only be a reference for you to view the states 
+you will have to re-create all the entities.
+The user interface should only be a reference for you to view the states
 and transitions, but is not the appropriate interface to define your
 application workflow.
 
--- a/doc/book/en/development/datamodel/definition.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/datamodel/definition.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,23 +3,23 @@
 Yams *schema*
 -------------
 
-The **schema** is the core piece of a `CubicWeb` application as it defines
+The **schema** is the core piece of a *CubicWeb* application as it defines
 the handled data model. It is based on entity types that are either already
-defined in the `CubicWeb` standard library; or more specific types, that
-`CubicWeb` expects to find in one or more Python files under the directory
+defined in the *CubicWeb* standard library; or more specific types, that
+*CubicWeb* expects to find in one or more Python files under the directory
 `schema`.
 
 At this point, it is important to make clear the difference between
 *relation type* and *relation definition*: a *relation type* is only a relation
-name with potentially other additionnal properties (see XXXX), whereas a 
-*relation definition* is a complete triplet 
-"<subject entity type> <relation type> <object entity type>". 
-A relation type could have been implied if none is related to a 
+name with potentially other additionnal properties (see XXXX), whereas a
+*relation definition* is a complete triplet
+"<subject entity type> <relation type> <object entity type>".
+A relation type could have been implied if none is related to a
 relation definition of the schema.
 
 
-All `CubicWeb` built-in types are available : `String`, `Int`, `Float`,
-`Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` 
+All *CubicWeb* built-in types are available : `String`, `Int`, `Float`,
+`Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte`
 and `Password`.
 They are implicitely imported (as well as the special the function "_"
 for translation :ref:`internationalization`).
@@ -67,7 +67,7 @@
   RelationSchema.rproperties()
   RelationSchema.rproperty(subjtype, objtype, property name)
 
-* Optional properties for attributes and relations : 
+* Optional properties for attributes and relations :
 
   - `description` : a string describing an attribute or a relation. By default
     this string will be used in the editing form of the entity, which means
@@ -79,7 +79,7 @@
 
   - `cardinality` : a two character string which specify the cardinality of the
     relation. The first character defines the cardinality of the relation on
-    the subject, and the second on the object. When a relation can have 
+    the subject, and the second on the object. When a relation can have
     multiple subjects or objects, the cardinality applies to all,
     not on a one-to-one basis (so it must be consistent...). The possible
     values are inspired from regular expression syntax :
@@ -92,24 +92,24 @@
   - `meta` : boolean indicating that the relation is a meta-relation (false by
     default)
 
-* optional properties for attributes : 
+* optional properties for attributes :
 
   - `required` : boolean indicating if the attribute is required (false by default)
 
   - `unique` : boolean indicating if the value of the attribute has to be unique
     or not within all entities of the same type (false by default)
 
-  - `indexed` : boolean indicating if an index needs to be created for this 
+  - `indexed` : boolean indicating if an index needs to be created for this
     attribute in the database (false by default). This is useful only if
     you know that you will have to run numerous searches on the value of this
     attribute.
 
   - `default` : default value of the attribute. In case of date types, the values
     which could be used correspond to the RQL keywords `TODAY` and `NOW`.
-  
+
   - `vocabulary` : specify static possible values of an attribute
 
-* optional properties of type `String` : 
+* optional properties of type `String` :
 
   - `fulltextindexed` : boolean indicating if the attribute is part of
     the full text index (false by default) (*applicable on the type `Byte`
@@ -120,11 +120,11 @@
 
   - `maxsize` : integer providing the maximum size of the string (no limit by default)
 
-* optional properties for relations : 
+* optional properties for relations :
 
   - `composite` : string indicating that the subject (composite == 'subject')
     is composed of the objects of the relations. For the opposite case (when
-    the object is composed of the subjects of the relation), we just set 
+    the object is composed of the subjects of the relation), we just set
     'object' as value. The composition implies that when the relation
     is deleted (so when the composite is deleted), the composed are also deleted.
 
@@ -137,7 +137,7 @@
 * `SizeConstraint` : allows to specify a minimum and/or maximum size on
   string (generic case of `maxsize`)
 
-* `BoundConstraint` : allows to specify a minimum and/or maximum value on 
+* `BoundConstraint` : allows to specify a minimum and/or maximum value on
   numeric types
 
 * `UniqueConstraint` : identical to "unique=True"
@@ -146,7 +146,7 @@
 
 * `RQLConstraint` : allows to specify a RQL query that has to be satisfied
   by the subject and/or the object of the relation. In this query the variables
-  `S` and `O` are reserved for the entities subject and object of the 
+  `S` and `O` are reserved for the entities subject and object of the
   relation.
 
 * `RQLVocabularyConstraint` : similar to the previous type of constraint except
@@ -160,7 +160,7 @@
 The security model
 ~~~~~~~~~~~~~~~~~~
 
-The security model of `cubicWeb` is based on `Access Control List`. 
+The security model of `cubicWeb` is based on `Access Control List`.
 The main principles are:
 
 * users and groups of users
@@ -168,7 +168,7 @@
 * permissions (read, update, create, delete)
 * permissions are assigned to groups (and not to users)
 
-For `CubicWeb` in particular:
+For *CubicWeb* in particular:
 
 * we associate rights at the enttities/relations schema level
 * for each entity, we distinguish four kind of permissions: read,
@@ -213,13 +213,13 @@
   This can only be used for the actions `update` and `delete` of an entity
   type.
 
-It is also possible to use specific groups if they are defined in the precreate 
+It is also possible to use specific groups if they are defined in the precreate
 of the cube (``migration/precreate.py``).
 
 
 Use of RQL expression for writing rights
 `````````````````````````````````````````
-It is possible to define RQL expression to provide update permission 
+It is possible to define RQL expression to provide update permission
 (`add`, `delete` and `update`) on relation and entity types.
 
 RQL expression for entity type permission :
@@ -232,13 +232,13 @@
   respectively on the current entity (on which the action is verified) and
   on the user who send the request
 
-* it is possible to use, in this expression, a special relation 
-  "has_<ACTION>_permission" where the subject is the user and the 
+* it is possible to use, in this expression, a special relation
+  "has_<ACTION>_permission" where the subject is the user and the
   object is a any variable, meaning that the user needs to have
   permission to execute the action <ACTION> on the entities related
-  to this variable 
+  to this variable
 
-For RQL expressions on a relation type, the principles are the same except 
+For RQL expressions on a relation type, the principles are the same except
 for the following :
 
 * you have to use the class `RQLExpression` in the case of a non-final relation
@@ -248,7 +248,7 @@
   which the action is being verified) and the user who executed the query
 
 * we can also defined rights on attributes of an entity (non-final relation),
-  knowing that : 
+  knowing that :
 
   - to defines RQL expression, we have to use the class `RQLExpression`
     in which X represents the entity the attribute belongs to
@@ -260,17 +260,17 @@
 
   Potentially, the use of an RQL expression to add an entity or a relation
   can cause problems for the user interface, because if the expression uses
-  the entity or the relation to create, then we are not able to verify the 
+  the entity or the relation to create, then we are not able to verify the
   permissions before we actually add the entity (please note that this is
   not a problem for the RQL server at all, because the permissions checks are
-  done after the creation). In such case, the permission check methods 
-  (check_perm, has_perm) can indicate that the user is not allowed to create 
-  this entity but can obtain the permission. 
+  done after the creation). In such case, the permission check methods
+  (check_perm, has_perm) can indicate that the user is not allowed to create
+  this entity but can obtain the permission.
   To compensate this problem, it is usually necessary, for such case,
   to use an action that reflects the schema permissions but which enables
   to check properly the permissions so that it would show up if necessary.
 
-  
+
 Use of RQL expression for reading rights
 ````````````````````````````````````````
 
@@ -315,20 +315,20 @@
 `Company` through the semantic `works_for`.
 
 The name of the Python attribute corresponds to the name of the attribute
-or the relation in `CubicWeb` application.
+or the relation in *CubicWeb* application.
 
 An attribute is defined in the schema as follows::
-    
+
     attr_name = attr_type(properties*)
 
 where `attr_type` is one of the type listed above and `properties` is
 a list of  the attribute needs to statisfy (see :ref:`properties`
-for more details). 
+for more details).
 
 
 * relations can be defined by using `ObjectRelation` or `SubjectRelation`.
   The first argument of `SubjectRelation` or `ObjectRelation` gives respectively
-  the object/subject entity type of the relation. This could be :  
+  the object/subject entity type of the relation. This could be :
 
   * a string corresponding to an entity type
 
@@ -337,7 +337,7 @@
   * special string such as follows :
 
     - "**" : all types of entities
-    - "*" : all types of non-meta entities 
+    - "*" : all types of non-meta entities
     - "@" : all types of meta entities but not system entities (e.g. used for
       the basic schema description)
 
@@ -356,9 +356,9 @@
 
 A relation is defined by a Python class heriting `RelationType`. The name
 of the class corresponds to the name of the type. The class then contains
-a description of the properties of this type of relation, and could as well 
+a description of the properties of this type of relation, and could as well
 contain a string for the subject and a string for the object. This allows to create
-new definition of associated relations, (so that the class can have the 
+new definition of associated relations, (so that the class can have the
 definition properties from the relation) for example ::
 
   class locked_by(RelationType):
--- a/doc/book/en/development/datamodel/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/datamodel/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -11,3 +11,4 @@
    baseschema
 
 ..    define-workflows
+..    inheritance
--- a/doc/book/en/development/devcore/appobject.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devcore/appobject.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -1,5 +1,5 @@
 
-  
+
 The `AppObject` class
 ~~~~~~~~~~~~~~~~~~~~~
 
--- a/doc/book/en/development/devcore/dbapi.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devcore/dbapi.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -20,7 +20,7 @@
 
 The `Connection` object owns the methods `commit` and `rollback`. You *should
 never need to use them* during the development of the web interface based on
-the `CubicWeb` framework as it determines the end of the transaction depending
+the *CubicWeb* framework as it determines the end of the transaction depending
 on the query execution success.
 
 .. note::
--- a/doc/book/en/development/devcore/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devcore/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -10,7 +10,7 @@
    selectors.rst
    dbapi.rst
 
-   
+
 :mod:`Configuration <cubicweb.cwconfig>`
 ----------------------------------------
 
--- a/doc/book/en/development/devcore/selectors.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devcore/selectors.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -7,7 +7,7 @@
 essential part of the construction of well behaved cubes.
 
 
-`CubicWeb` provides its own set of selectors that you can use and here is a
+*CubicWeb* provides its own set of selectors that you can use and here is a
 description of some of the most common used:
 
 Of course you will write your own set of selectors as you get familiar with the
--- a/doc/book/en/development/devcore/vreg.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devcore/vreg.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -1,3 +1,5 @@
+.. -*- coding: utf-8 -*-
+
 The VRegistry
 --------------
 
@@ -7,21 +9,23 @@
 Details of the recording process
 ````````````````````````````````
 
-* par défaut on enregistre automatiquement tout les objets
+XXX this part needs to be updated and checked
+
+* by default all objects are registered automatically
 
-* si certains objets doivent remplacer d'autres objets ou être inclus
-  conditionnellement,
-  - enregistrement explicite en définissant la fonction `registration_callback(vreg)`
-  - appel des méthodes d'enregistrement des objets sur le vreg
+* if some objects have to replace other objects or be included only if a
+  condition is true,
+  - explicitly register the object by defining `registration_callback(vreg)`
+  - call registration methods on objects listed in the vreg registry
+
 .. note::
     Once the function `registration_callback(vreg)` is implemented, all the objects
-    need to be explicitly registered as it disables the automatic object registering.
-    
-* suppression de l'ancien système quand il ne restera plus de réference au
-  module registerers dans le code des cubes existants.
+    have to be explicitly registered as it disables the automatic object registering.
 
+* the old registration mechanism will be removed when there will be no reference
+  left to the registerers module in cubicweb and the library of cubes.
 
-Examples
+Examples:
 
 .. code-block:: python
 
@@ -40,6 +44,7 @@
 
 API d'enregistrement des objets
 ```````````````````````````````
+
 .. code-block:: python
 
    register(obj, registryname=None, oid=None, clear=False)
@@ -58,7 +63,8 @@
 
 Defining selectors
 ``````````````````
-The object's selector is defined by itsd `__select__` class attribute.
+
+The object's selector is defined by its `__select__` class attribute.
 
 When two selectors are combined using the `&` operator (former `chainall`), it
 means that both should return a positive score. On success, the sum of scores is returned.
@@ -86,18 +92,20 @@
 Example
 ````````
 
-Le but final : quand on est sur un Blog, on veut que le lien rss de celui-ci pointe
-vers les entrées de ce blog, non vers l'entité blog elle-même.
+XXX this part needs to be translated
 
-L'idée générale pour résoudre ça : on définit une méthode sur les classes d'entité
+Le but final : quand on est sur un Blog, on veut que le lien rss de celui-ci pointe
+vers les entrées de ce blog, non vers l'entité blog elle-même.
+
+L'idée générale pour résoudre ça : on définit une méthode sur les classes d'entité
 qui renvoie l'url du flux rss pour l'entité en question. Avec une implémentation
-par défaut sur AnyEntity et une implémentation particulière sur Blog qui fera ce
+par défaut sur AnyEntity et une implémentation particulière sur Blog qui fera ce
 qu'on veut.
 
-La limitation : on est embêté dans le cas ou par ex. on a un result set qui contient
+La limitation : on est embêté dans le cas ou par ex. on a un result set qui contient
 plusieurs entités Blog (ou autre chose), car on ne sait pas sur quelle entité appeler
 la méthode sus-citée. Dans ce cas, on va conserver le comportement actuel (eg appel
-à limited_rql)
+à limited_rql)
 
 Donc : on veut deux cas ici, l'un pour un rset qui contient une et une seule entité,
 l'autre pour un rset qui contient plusieurs entité.
@@ -116,7 +124,7 @@
   pour voir le détail)
 * non_final_entity, qui filtre sur des rset contenant une liste d'entité non finale
 
-ça correspond donc à notre 2eme cas. Reste à fournir un composant plus spécifique
+ça correspond donc à notre 2eme cas. Reste à fournir un composant plus spécifique
 pour le 1er cas ::
 
   class EntityRSSIconBox(RSSIconBox):
@@ -130,11 +138,11 @@
 non sélectionnable). Donc ici, sur un rset avec plusieurs entités, onelinerset_selector
 rendra la classe EntityRSSIconBox non sélectionnable, et on obtiendra bien la
 classe RSSIconBox. Pour un rset avec une entité, la classe EntityRSSIconBox aura un
-score supérieur à RSSIconBox et c'est donc bien elle qui sera sélectionnée.
+score supérieur à RSSIconBox et c'est donc bien elle qui sera sélectionnée.
 
-Voili voilou, il reste donc pour finir tout ça :
+Voili voilou, il reste donc pour finir tout ça :
 
-* à définir le contenu de la méthode call de EntityRSSIconBox
+* à définir le contenu de la méthode call de EntityRSSIconBox
 * fournir l'implémentation par défaut de la méthode renvoyant l'url du flux rss sur
   AnyEntity
 * surcharger cette methode dans blog.Blog
@@ -144,8 +152,8 @@
 ```````````````````````
 
 Il faut utiliser les sélecteurs pour faire des choses différentes en
-fonction de ce qu'on a en entrée. Dès qu'on a un "if" qui teste la
-nature de `self.rset` dans un objet, il faut très sérieusement se
+fonction de ce qu'on a en entrée. Dès qu'on a un "if" qui teste la
+nature de `self.rset` dans un objet, il faut très sérieusement se
 poser la question s'il ne vaut pas mieux avoir deux objets différent
 avec des sélecteurs approprié.
 
--- a/doc/book/en/development/devrepo/hooks.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devrepo/hooks.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -10,8 +10,8 @@
 *Hooks* are executed before or after updating an entity or a relation in the
 repository.
 
-Their prototypes are as follows: 
-    
+Their prototypes are as follows:
+
     * after_add_entity     (session, entity)
     * after_update_entity  (session, entity)
     * after_delete_entity  (session, eid)
@@ -23,10 +23,10 @@
     * after_delete_relation  (session, fromeid, rtype, toeid)
     * before_add_relation    (session, fromeid, rtype, toeid)
     * before_delete_relation (session, fromeid, rtype, toeid)
-    
+
     * server_startup
     * server_shutdown
-    
+
     * session_open
     * session_close
 
--- a/doc/book/en/development/devweb/form.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devweb/form.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -9,9 +9,9 @@
   * `vocabulary(rtype, x='subject', limit=None)`, called by the
     editing views, it returns a list of couples (label, eid) of entities
     that could be related to the entity by the relation `rtype`
-  * `subject_relation_vocabulary(rtype, limit=None)`, called internally 
+  * `subject_relation_vocabulary(rtype, limit=None)`, called internally
     by  `vocabulary` in the case of a subject relation
-  * `object_relation_vocabulary(rtype, limit=None)`, called internally 
+  * `object_relation_vocabulary(rtype, limit=None)`, called internally
     by  `vocabulary` in the case of an object relation
   * `relation_vocabulary(rtype, targettype, x, limit=None)`, called
     internally by `subject_relation_vocabulary` and `object_relation_vocabulary`
--- a/doc/book/en/development/devweb/views.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/devweb/views.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,11 +3,11 @@
 
 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`.
+in *CubicWeb*.
 
 We'll start with a description of the interface providing you with a basic
 understanding of the classes and methods available, then detail the view
-selection principle which makes `CubicWeb` web interface very flexible.
+selection principle which makes *CubicWeb* web interface very flexible.
 
 A `View` is an object applied to another object such as an entity.
 
@@ -42,19 +42,19 @@
 
 * `dispatch(**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 (default 
+* `call(**kwargs)`, call the view for a complete result set or null (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
 * `url()`, returns the URL enabling us to get the view with the current
-  result set 
-* `view(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of identifier 
+  result set
+* `view(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of identifier
   `__vid` on the given result set. It is possible to give a view identifier
   of fallback that will be used if the view requested is not applicable to the
   result set
-  
+
 * `wview(__vid, rset, __fallback_vid=None, **kwargs)`, similar to `view` except
   the flow is automatically passed in the parameters
-  
+
 * `html_headers()`, returns a list of HTML headers to set by the main template
 
 * `page_title()`, returns the title to use in the HTML header `title`
@@ -67,17 +67,17 @@
 
 * `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 applied to any result set 
+* `AnyRsetView`, view applied to any result set
 * `EmptyRsetView`, view applied to an empty result set
 
 
-Examples of views class 
+Examples of views class
 -----------------------
 
 - Using `templatable`, `content_type` and HTTP cache configuration
 
 .. code-block:: python
-    
+
 
     class RSSView(XMLView):
         id = 'rss'
@@ -86,13 +86,13 @@
         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
 
 .. code-block:: python
-    
+
 
     class SearchForAssociationView(EntityView):
         """view called by the edition view when the user asks
@@ -111,18 +111,18 @@
 
 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 
+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`` ::
 
 .. code-block:: python
 
    from cubicweb.view import EntityView
    from cubicweb.selectors import implements
-  
+
    class BlogEntryPrimaryView(EntityView):
        id = 'primary'
        __select__ =implements('Blog')
-       
+
        def cell_call(self, row, col):
            entity = self.entity(row, col)
            self.w(u'<h1>%s</h1>' % entity.title)
@@ -131,7 +131,7 @@
            self.w(u'<p>%s</p>' % entity.text)
 
 The above source code defines a new primary view (`line 03`) for
-``BlogEntry`` (`line 05`). 
+``BlogEntry`` (`line 05`).
 
 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 08`).
@@ -170,9 +170,9 @@
 about the schema and infer that such entities have to be of the
 ``BlogEntry`` kind and retrieves them.
 
-The request returns a selection of data called a result set. At 
+The request returns a selection of data called a result set. At
 `line 10` the view 'primary' is applied to this result set to output
-HTML. 
+HTML.
 
 **This is to be compared to interfaces and protocols in object-oriented
 languages. Applying a given view called 'a_view' to all the entities
@@ -186,7 +186,7 @@
    :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
+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.**
@@ -202,7 +202,7 @@
 
 * create view "blogentry table" with title, publish_date, category
 
-We will show that by default the view that displays 
+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)
@@ -226,7 +226,7 @@
 * 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 
+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).
--- a/doc/book/en/development/entityclasses/data-as-objects.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/entityclasses/data-as-objects.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -19,18 +19,18 @@
 
   * `absolute_url(**kwargs)`, returns an absolute URL to access the primary view
     of an entity
-    
+
   * `rest_path()`, returns a relative REST URL to get the entity
 
   * `format(attr)`, returns the format (MIME type) of the field given un parameter
 
-  * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`, 
+  * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
     returns a string enabling the display of an attribute value in a given format
     (the value is automatically recovered if necessary)
 
 :Data handling:
 
-  * `as_rset()`, converts the entity into an equivalent result set simulating the 
+  * `as_rset()`, converts the entity into an equivalent result set simulating the
      request `Any X WHERE X eid _eid_`
 
   * `complete(skip_bytes=True)`, executes a request that recovers in one time
@@ -57,21 +57,21 @@
 
   * `delete()` allows to delete the entity
 
-  
+
 Tne :class:`AnyEntity` class
 ----------------------------
-  
+
 To provide a specific behavior for each entity, we have to define
 a class inheriting from `cubicweb.entities.AnyEntity`. In general, we
 define this class in a module of `mycube.entities` package of an application
 so that it will be available on both server and client side.
 
-The class `AnyEntity` is loaded dynamically from the class `Entity` 
+The class `AnyEntity` is loaded dynamically from the class `Entity`
 (`cubciweb.entity`). We define a sub-class to add methods or to
 specialize the handling of a given entity type
 
 The methods defined for `AnyEntity` or `Entity` are the following ones:
-  
+
 :Standard meta-data (Dublin Core):
 
   * `dc_title()`, returns a unicode string corresponding to the meta-data
@@ -81,15 +81,15 @@
   * `dc_long_title()`, same as dc_title but can return a more
     detailled title
 
-  * `dc_description(format='text/plain')`, returns a unicode string 
+  * `dc_description(format='text/plain')`, returns a unicode string
     corresponding to the meta-data `Description` (look for a description
     attribute by default)
 
-  * `dc_authors()`, returns a unicode string corresponding to the meta-data 
+  * `dc_authors()`, returns a unicode string corresponding to the meta-data
     `Authors` (owners by default)
 
-  * `dc_date(date_format=None)`, returns a unicode string corresponding to 
+  * `dc_date(date_format=None)`, returns a unicode string corresponding to
     the meta-data `Date` (update date by default)
 
-  * `dc_type(form='')`, returns a string to display the entity type by 
+  * `dc_type(form='')`, returns a string to display the entity type by
     specifying the preferred form (`plural` for a plural form)
--- a/doc/book/en/development/entityclasses/load-sort.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/entityclasses/load-sort.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -14,13 +14,13 @@
   `None` if we do not want to sort on the attribute given in the parameter.
   By default, the entities are sorted according to their creation date.
 
-* The class method `fetch_unrelated_order(attr, var)` is similar to the 
+* The class method `fetch_unrelated_order(attr, var)` is similar to the
   method `fetch_order` except that it is essentially used to control
-  the sorting of drop-down lists enabling relations creation in 
+  the sorting of drop-down lists enabling relations creation in
   the editing view of an entity.
 
 The function `fetch_config(fetchattrs, mainattr=None)` simplifies the
-definition of the attributes to load and the sorting by returning a 
+definition of the attributes to load and the sorting by returning a
 list of attributes to pre-load (considering automatically the attributes
 of `AnyEntity`) and a sorting function based on the main attribute
 (the second parameter if specified otherwisethe first attribute from
--- a/doc/book/en/development/entityclasses/more.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/entityclasses/more.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -1,12 +1,14 @@
 Navigation on deletion
 ----------------------
+
 XXX after_deletion_path, pre_web_edit
 
 Controlling output url
----------------------
-XXX
+-----------------------
+
+XXX write me
 
 Controling notification references
 ----------------------------------
-XXX
 
+XXX write me
--- a/doc/book/en/development/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -4,7 +4,7 @@
 Part II - Development
 ---------------------
 
-This part is about developing web applications with the `CubicWeb` framework.
+This part is about developing web applications with the *CubicWeb* framework.
 
 .. toctree::
    :maxdepth: 2
--- a/doc/book/en/development/migration/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/migration/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -5,7 +5,7 @@
 Migration
 =========
 
-One of the main concept in `CubicWeb` is to create incremental applications.
+One of the main concept in *CubicWeb* is to create incremental applications.
 For this purpose, multiple actions are provided to facilitate the improvement
 of an application, and in particular to handle the changes to be applied
 to the data model, without loosing existing data.
@@ -23,11 +23,11 @@
 
   <version n° X.Y.Z>[_<description>]_<mode>.py
 
-in which : 
+in which :
 
 * X.Y.Z is the model version number to which the script enables to migrate.
 
-* *mode* (between the last "_" and the extension ".py") is used for 
+* *mode* (between the last "_" and the extension ".py") is used for
   distributed installation. It indicates to which part
   of the application (RQL server, web server) the script applies.
   Its value could be :
@@ -44,10 +44,10 @@
     (schema and data migration for example).
 
 Again in the directory `migration`, the file `depends.map` allows to indicate
-that for the migration to a particular model version, you always have to first 
-migrate to a particular `CubicWeb` version. This file can contain comments (lines
+that for the migration to a particular model version, you always have to first
+migrate to a particular *CubicWeb* version. This file can contain comments (lines
 starting by `#`) and a dependancy is listed as follows: ::
-  
+
   <model version n° X.Y.Z> : <cubicweb version n° X.Y.Z>
 
 For example: ::
@@ -65,7 +65,7 @@
 * `config`, instance configuration
 
 * `interactive_mode`, boolean indicating that the script is executed in
-  an interactive mode or not 
+  an interactive mode or not
 
 * `appltemplversion`, application model version of the instance
 
@@ -87,7 +87,7 @@
 * `repo_schema`, instance persisting schema (e.g. instance schema of the
   current migration)
 
-* `newschema`, installed schema on the file system (e.g. schema of 
+* `newschema`, installed schema on the file system (e.g. schema of
   the updated model and cubicweb)
 
 * `sqlcursor`, SQL cursor for very rare cases where it is really
@@ -95,30 +95,30 @@
 
 * `repo`, repository object
 
-                        
+
 Schema migration
 ----------------
 The following functions for schema migration are available in `repository`
 scripts:
 
 * `add_attribute(etype, attrname, attrtype=None, commit=True)`, adds a new
-  attribute to an existing entity type. If the attribute type is not specified, 
+  attribute to an existing entity type. If the attribute type is not specified,
   then it is extracted from the updated schema.
-        
+
 * `drop_attribute(etype, attrname, commit=True)`, removes an attribute from an
   existing entity type.
 
 * `rename_attribute(etype, oldname, newname, commit=True)`, renames an attribute
-            
+
 * `add_entity_type(etype, auto=True, commit=True)`, adds a new entity type.
   If `auto` is True, all the relations using this entity type and having a known
   entity type on the other hand will automatically be added.
 
-* `drop_entity_type(etype, commit=True)`, removes an entity type and all the 
+* `drop_entity_type(etype, commit=True)`, removes an entity type and all the
   relations using it.
 
 * `rename_entity_type(oldname, newname, commit=True)`, renames an entity type
-            
+
 * `add_relation_type(rtype, addrdef=True, commit=True)`, adds a new relation
   type. If `addrdef` is True, all the relations definitions of this type will
   be added.
@@ -136,17 +136,17 @@
 
 * `synchronize_permissions(ertype, commit=True)`, synchronizes permissions on
   an entity type or relation type.
-        
+
 * `synchronize_rschema(rtype, commit=True)`, synchronizes properties and permissions
   on a relation type.
-                
+
 * `synchronize_eschema(etype, commit=True)`, synchronizes properties and persmissions
   on an entity type.
-    
+
 * `synchronize_schema(commit=True)`, synchronizes the persisting schema with the
-  updated schema (but without adding or removing new entity types, relations types 
+  updated schema (but without adding or removing new entity types, relations types
   or even relations definitions).
-        
+
 * `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, changes
   properties of a relation definition by using the named parameters of the properties
   to change.
@@ -162,7 +162,7 @@
 The following functions for data migration are available in `repository` scripts:
 
 * `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, executes an arbitrary RQL
-  query, either to interrogate or update. A result set object is returned.  
+  query, either to interrogate or update. A result set object is returned.
 
 * `add_entity(etype, *args, **kwargs)`, adds a nes entity type of the given
   type. The attribute and relation values are specified using the named and
@@ -176,8 +176,8 @@
 
 * `add_state(name, stateof, initial=False, commit=False, **kwargs)`, adds a new state
   in the workflow.
-    
-* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`, 
+
+* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
   adds a new transition in the workflow.
 
 You can find more details about workflows in the chapter :ref:`Workflow` .
@@ -185,7 +185,7 @@
 Configuration migration
 -----------------------
 
-The following functions for configuration migration are available in all 
+The following functions for configuration migration are available in all
 scripts:
 
 * `option_renamed(oldname, newname)`, indicates that an option has been renamed
@@ -200,8 +200,8 @@
 
 Others migration functions
 --------------------------
-Those functions are only used for low level operations that could not be 
-accomplished otherwise or to repair damaged databases during interactive 
+Those functions are only used for low level operations that could not be
+accomplished otherwise or to repair damaged databases during interactive
 session. They are available in `repository` scripts:
 
 * `sqlexec(sql, args=None, ask_confirm=True)`, executes an arbitrary SQL query
--- a/doc/book/en/development/testing/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/testing/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -10,7 +10,7 @@
 Unit tests
 ----------
 
-`CubicWeb` framework provides essentially two Python test classes in the
+*CubicWeb* framework provides essentially two Python test classes in the
 module `cubicweb.devtools.apptest`:
 
 * `EnvBasedTC`, to simulate a complete environment (web + repository)
@@ -28,11 +28,11 @@
 Email notifications tests
 -------------------------
 When running tests potentially generated e-mails are not really
-sent but is found in the list `MAILBOX` of module `cubicweb.devtools.apptest`. 
+sent but is found in the list `MAILBOX` of module `cubicweb.devtools.apptest`.
 This list is reset at each test *setUp* (by the setUp of classes `EnvBasedTC`
 and `RepositoryBasedTC`).
 
-	
+
 You can test your notifications by analyzing the contents of this list, which
 contains objects with two attributes:
 * `recipients`, the list of recipients
--- a/doc/book/en/development/webstdlib/autoform.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/webstdlib/autoform.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -2,7 +2,7 @@
 ---------------------------------------------------------------
 
 It is possible to manage attributes/relations in the simple or multiple
-editing form thanks to the following *rtags*: 
+editing form thanks to the following *rtags*:
 
 * `primary`, indicates that an attribute or a relation has to be
   inserted **in the simple or multiple editing forms**. In the case of
@@ -26,6 +26,6 @@
 * `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  
+If necessary, it is possible to overwrite the method
 `relation_category(rtype, x='subject')` to dynamically compute
 a relation editing category.
--- a/doc/book/en/development/webstdlib/basetemplates.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/webstdlib/basetemplates.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -32,15 +32,15 @@
 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 
+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_. 
+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')
@@ -101,13 +101,13 @@
         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.vreg.select_component('loggeduserlink', self.req, self.rset)
         #comp.dispatch(w=self.w)
         #self.w(u'</td><td>')
-        
+
         # search box
         self.w(u'<td>')
         self.get_searchbox(view, 'left')
@@ -133,14 +133,14 @@
                 if box.id == '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 : 
+for HTMLPageFooter and override it in your views file as in :
 ::
 
   form cubicweb.web.views.basetemplates import HTMLPageFooter
@@ -158,7 +158,7 @@
 ---------------
 .. _TheMainTemplate:
 
-TheMainTemplate is responsible for the general layout of the entire application. 
+TheMainTemplate is responsible for the general layout of the entire application.
 It defines the template of ``id = main`` that is used by the application.
 
 The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
@@ -168,7 +168,7 @@
 
 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 
+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.
 
@@ -177,9 +177,9 @@
 
 * `__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 
+* `__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 
+* `__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)
--- a/doc/book/en/development/webstdlib/baseviews.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/webstdlib/baseviews.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,7 +3,7 @@
 Base views (:mod:`cubicweb.web.views.baseviews`)
 ------------------------------------------------
 
-`CubicWeb` provides a lot of standard views. You can find them in
+*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
@@ -13,26 +13,26 @@
 HTML views
 ~~~~~~~~~~
 *oneline*
-    This is a hyper linked *text* view. Similar to the `secondary` view, 
-    but called when we want the view to stand on a single line, or just 
+    This is a hyper linked *text* view. Similar to the `secondary` view,
+    but called when we want the view to stand on a single line, or just
     get a brief view. By default this view uses the
     parameter `MAX_LINE_CHAR` to control the result size.
 
 *secondary*
     This is a combinaison of an icon and a *oneline* view.
-    By default it renders the two first attributes of the entity as a 
+    By default it renders the two first attributes of the entity as a
     clickable link redirecting to the primary view.
 
 *incontext, outofcontext*
     Similar to the `secondary` view, but called when an entity is considered
-    as in or out of context. By default it respectively returns the result of 
-    `textincontext` and `textoutofcontext` wrapped in a link leading to 
+    as in or out of context. By default it respectively returns the result of
+    `textincontext` and `textoutofcontext` wrapped 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>`) 
+    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*
@@ -57,10 +57,10 @@
 Text views
 ~~~~~~~~~~
 *text*
-    This is the simplest text view for an entity. It displays the 
+    This is the simplest text view for an entity. It displays the
     title of an entity. It should not contain HTML.
 
 *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 
+    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	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/webstdlib/boxes.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -2,7 +2,7 @@
 ---------------------------------------------------------------
 
 *sidebox*
-  This view displays usually a side box of some related entities 
+  This view displays usually a side box of some related entities
   in a primary view.
 
 The action box
@@ -23,9 +23,9 @@
   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  
+If necessary, it is possible to overwrite the method
 `relation_mode(rtype, targettype, x='subject')` to dynamically
 compute a relation creation category.
 
--- a/doc/book/en/development/webstdlib/primary.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/webstdlib/primary.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -2,23 +2,21 @@
 ---------------------------------------------------------------
 
 The primary view of an entity is the view called by default when a single
-entity is in the result set and needs to be displayed. 
+entity is in the result set and needs to be displayed.
 
 This view is supposed to render a maximum of informations about the entity.
 
-
-
 Rendering methods and attributes for ``PrimaryView``
 ----------------------------------------------------
 
-By default, `CubicWeb` provides a primary view for each new entity type
+By default, *CubicWeb* provides a primary view for each new entity type
 you create. The first view you might be interested in modifying.
 
 Let's have a quick look at the EntityView ``PrimaryView`` as well as
 its rendering method
 
 .. code-block:: python
-    
+
     class PrimaryView(EntityView):
         """the full view of an non final entity"""
         id = 'primary'
@@ -64,8 +62,8 @@
 
 The methods you want to modify while customizing a ``PrimaryView`` are:
 
-*render_entity_title(self, entity)* 
-    Renders the entity title based on the assumption that the method 
+*render_entity_title(self, entity)*
+    Renders the entity title based on the assumption that the method
     ``def content_title(self)`` is implemented for the given entity type.
 
 *render_entity_metadata(self, entity)*
@@ -77,7 +75,7 @@
     of type `Password` and `Bytes`.
 
 *content_navigation_components(self, context)*
-    This method is applicable only for entity type implementing the interface 
+    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 methods will render the navigation links between
     entities of this type, either at the top or at the bottom of the page
@@ -85,7 +83,7 @@
 
 *render_entity_relations(self, entity, siderelations)*
     Renders all the relations of the entity in the main section of the page.
-        
+
 *render_side_related(self, entity, siderelations)*
     Renders all the relations of the entity in a side box. This is equivalent
     to *render_entity_relations* in addition to render the relations
@@ -98,7 +96,7 @@
     Renders the attribute label next to the attribute value if set to True.
     Otherwise, does only display the attribute value.
 
-*show_rel_label* 
+*show_rel_label*
     Renders the relation label next to the relation value if set to True.
     Otherwise, does only display the relation value.
 
@@ -114,4 +112,4 @@
 overwrite ``render_entity`` as you might potentially loose the benefits of the side
 boxes handling.
 
-.. XXX talk about uicfg.rdisplay
\ No newline at end of file
+.. XXX talk about uicfg.rdisplay
--- a/doc/book/en/development/webstdlib/urlpublish.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/development/webstdlib/urlpublish.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,4 +3,4 @@
 ------------------------------------------------------------------------------------------------
 
 XXX feed me
-show how urls are mapped to selections and views and explain URLRewriting 
+show how urls are mapped to selections and views and explain URLRewriting
--- a/doc/book/en/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,25 +3,25 @@
 .. _contents:
 
 =====================================================
-`CubicWeb` - The Semantic Web is a construction game!
+*CubicWeb* - The Semantic Web is a construction game!
 =====================================================
 
-`CubicWeb` is a semantic web application framework, licensed under the LGPL,
+*CubicWeb* is a semantic web application framework, licensed under the LGPL,
 that empowers developers to efficiently build web applications by reusing
 components (called `cubes`) and following the well known object-oriented design
 principles.
 
 Its main features are:
 
-* an engine driven by the explicit :ref:`data model <DefineDataModel>` of the application, 
-* a query language name :ref:`RQL <RQL>` similar to W3C's SPARQL, 
-* a :ref:`selection+view <DefineViews>` mechanism for semi-automatic XHTML/XML/JSON/text generation, 
+* an engine driven by the explicit :ref:`data model <DefineDataModel>` of the application,
+* a query language named :ref:`RQL <RQL>` similar to W3C's SPARQL,
+* a :ref:`selection+view <DefineViews>` mechanism for semi-automatic XHTML/XML/JSON/text generation,
 * a library of reusable :ref:`components <cubes>` (data model and views) that fulfill common needs,
 * the power and flexibility of the Python_ programming language,
 * the reliability of SQL databases, LDAP directories, Subversion and Mercurial for storage backends.
 
 Built since 2000 from an R&D effort still continued, supporting 100,000s of
-daily visits at some production sites, `CubicWeb` is a proven end to end solution
+daily visits at some production sites, *CubicWeb* is a proven end to end solution
 for semantic web application development that promotes quality, reusability and
 efficiency.
 
@@ -29,14 +29,19 @@
 
 The hacker will join development at the forge_.
 
-The impatient developper will move right away to :ref:`SetUpEnv`.
+The impatient developer will move right away to :ref:`SetUpEnv`.
+
+The chatter lover will join the `jabber forum`_, the `mailing-list`_ and the blog_.
 
 .. _Logilab: http://www.logilab.fr/
 .. _forge: http://www.cubicweb.org/project/
 .. _Python: http://www.python.org/
+.. _`jabber forum`: http://www.logilab.org/blogentry/6718
+.. _`mailing-list`: http://lists.cubicweb.org/mailman/listinfo/cubicweb
+.. _blog: http://www.cubicweb.org/blog/1238
 
-The book
-========
+Table of Contents
+=================
 
 .. toctree::
    :maxdepth: 2
@@ -46,17 +51,10 @@
    admin/index
    annexes/index
 
-
-
-Table of Contents
------------------
-
-Complete :ref:`TOC`.
+See also:
 
-Indices and tables
-==================
+* the complete :ref:`TOC`,
+* the :ref:`genindex`,
+* the :ref:`modindex`,
+* and the :ref:`search`.
 
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
--- a/doc/book/en/intro/concepts/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/intro/concepts/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,75 +3,64 @@
 The Core Concepts of CubicWeb
 =============================
 
-.. toctree::
-   :maxdepth: 1
-
-------------------------------
-
-This section aims to provide you the keys of success with *CubicWeb*
-by clarifying the terms specific to our framework. If you want to do anything
-serious with CubicWeb, you should understand concepts in those lines.
-
-*CubicWeb* defines its own terminology. To make sure there is no confusion
-while reading this book, we strongly recommand you take time to go through
-the following definitions that are the basics to understand while
-developing with *CubicWeb*.
-
+This section defines some terms and core concepts of the *CubicWeb*
+framework. To avoid confusion while reading this book, take time to go through
+the following definitions and use this section as a reference during your
+reading.
 
 .. _Cube:
 
 Cubes
 -----
-** Construct your application by assembling cubes **
+
+A cube is a software component composed of three parts: its data model (schema),
+its logic (entities) and its user interface (views).
 
-A cube provides a specific functionality, or a complete *CubicWeb*
-application usually by assembling other cubes.
-
-It's usually composed of a data model, some logic to manipulate it and some parts
-of web interface.
+A cube can use other cubes as building blocks and assemble them to provide
+a whole with richer functionnalities than its parts. The cubes `cubicweb-blog`_
+and `cubicweb-comment`_ could be used to make a cube named *myblog* with
+commentable blog entries.
 
-You can decide to write your own set of cubes if you wish to re-use the
-entity types you develop or/and if you have specific needs not covered by
-cubes are available from the `CubicWeb Forge`_ under a free software license.
+The `CubicWeb Forge`_ offers a large number of cubes developed by the community
+and available under a free software license.
 
-Available cubes on your system are defined in the directory
-:file:`/usr/share/cubicweb/cubes` when using a system wide installation.  For people
-using the mercurial repository of cubicweb, the :file:`/path/to/forest/cubicweb/cubes`
-directory is used. You can specify additional location using the :envvar:`CW_CUBES_PATH`
-environment variable, using ':' as separator.
+Available cubes on your system are usually stored in the directory
+:file:`/usr/share/cubicweb/cubes` when using a unix system wide
+installation. During development, the cubes are found in the
+:file:`/path/to/cubicweb_forest/cubes` directory. You can specify additional
+locations using the :envvar:`CW_CUBES_PATH` environment variable, using ':' as a
+separator.
 
 .. _`CubicWeb Forge`: http://www.cubicweb.org/project/
-
+.. _`cubicweb-blog`: http://www.cubicweb.org/project/cubicweb-blog
+.. _`cubicweb-comment`: http://www.cubicweb.org/project/cubicweb-comment
 
 
 Instances
 ----------
-** *CubicWeb* framework is a server/client application framework**
 
-An instance is a specific installation of one or multiple cubes. All the required
-configuration files necessary for the well being of your web application are
-grouped in an instance. This will refer to the cube(s) your application is based
-on.  For example logilab.org and our intranet are two instances of a single cube
-`jpl`
+An instance is a runnable application installed on a computer and based on a
+cube.
 
-We recommand not to define schema, entities or views in the instance
-file system itself but in the cube, in order to maintain re-usability of
-entities and their views. We strongly recommand to develop cubes which
-could be used in other instances (modular approach).
+The instance directory includes the configuration files. Several instances can
+be created based on the same cube. For exemple, several software forges can be
+set up on one computer system based on the `cubicweb-forge`_ cube.
 
-An instance usually usually consists into a web interface which is talking to a
-rql repository, itself connected to a SQL database, all into a single
-process. You can have some more complicated configurations using several web
-front-ends talking to a rql repository using `Pyro`_, databases replication...
+.. _`cubicweb-forge`: http://www.cubicweb.org/project/cubicweb-forge
+
+Instances can be of different types: all-in-one, web engine or data 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
 
-The term application is sometimes used to talk about an instance and sometimes to
-talk of a cube depending on the context.  So we would like to avoid using this
-term and try to use *cube* and *instance* instead.
+The term application can refer to an instance or to a cube, depending on the
+context. This book will try to avoid using this term and use *cube* and
+*instance* as appropriate.
 
-Data Repository
-~~~~~~~~~~~~~~~
+(Data) Repository
+~~~~~~~~~~~~~~~~~~
+
 The repository (Be carefull not to get confused with a Mercurial repository or a
 debian repository!) manages all interactions with various data sources by
 providing access to them using uniformly using the Relation Query Language (RQL).  The
@@ -134,7 +123,7 @@
 see :ref:`yams.BASE_TYPES`
 
 Data level security is defined by setting permissions on entity and relation types.
-  
+
 A schema consist of parts detailed below.
 
 
@@ -215,7 +204,7 @@
 When no score is higher than the others, an exception is raised in development
 mode to let you know that the engine was not able to identify the view to
 apply. This error is silented in production mode and one of the objects with the
-higher score is picked. 
+higher score is picked.
 
 If no object has a positive score, ``NoSelectableObject`` exception is raised.
 
--- a/doc/book/en/intro/foundations/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-`CubicWeb` Foundations
-======================
-
-A little history...
--------------------
-
-`CubicWeb` is a web application framework developped by Logilab_ since 2001.
-
-Entirely written in Python, `CubicWeb` publishes data from all sorts
-of sources such as SQL database, LDAP directory and versioning system such
-as subversion.
-
-`CubicWeb` user interface was designed to let the final user a huge flexibility
-on how to select and how to display content. It allows to browse the knowledge
-database and to display the results with the best rendering according to
-the context.
-This interface flexibility gives back the user the control of the 
-rendering parameters that are usually reserved for developpers.
-
-
-We can list a couple of web applications developped with `CubicWeb`, an online
-public phone directory (see http://www.118000.fr/), a system for managing 
-digital studies and simulations for a research lab, a tool for shared children
-babysitting (see http://garde-partagee.atoukontact.fr/), a tool to manage
-software developpment (see http://www.logilab.org), an application for
-managing museums collections (see 
-http://collections.musees-haute-normandie.fr/collections/), etc.
-
-In 2008, `CubicWeb` was ported for a new type of source : the datastore 
-from `GoogleAppEngine`_.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/intro/history.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -0,0 +1,30 @@
+.. -*- coding: utf-8 -*-
+
+A little history...
+======================
+
+*CubicWeb* is a semantic web application framework that Logilab_ started
+developing in 2001 as an offspring of its Narval_ research project. *CubicWeb*
+is written in Python and includes a data server and a web engine.
+
+Its data server publishes data federated from different sources like SQL
+databases, LDAP directories and versioning systems (such as subversion or
+mercurial).
+
+Its web engine was designed to let the final user control what content to select
+and how to display it. It allows one to browse the federated data sources and
+display the results with the rendering that best fits the context. This
+flexibility of the user interface gives back to the user some capabilities
+usually only accessible to application developers.
+
+*CubicWeb* has been developed by Logilab_ and used in-house for many years
+before it was first installed for its clients in 2006 as version 2.
+
+In 2008, *CubicWeb* version 3 became downloadable for free under the terms of
+the LGPL license. Its community is now steadily growing as changes can occur
+rapidly thanks to the time and energy originally put in the design of the
+framework.
+
+
+.. _Narval: http://www.logilab.org/project/narval
+.. _Logilab: http://www.logilab.fr/
--- a/doc/book/en/intro/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/intro/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,18 +3,18 @@
 .. _Part1:
 
 -----------------------------------
-Part I - Introduction to `CubicWeb`
+Part I - Introduction to *CubicWeb*
 -----------------------------------
 
-This first part of the book will present different reading path to
-discover the `CubicWeb` framework, provide a tutorial to get a quick
-overview of its features and list its key concepts.
+This first part of the book offers different reading path to
+discover the *CubicWeb* framework, provides a tutorial to get a quick
+overview of its features and lists its key concepts.
 
- 
+
 .. toctree::
    :maxdepth: 2
 
    book-map
-   foundations/index
+   history
    concepts/index
    tutorial/index
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/intro/tutorial/blog-in-five-minutes.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -0,0 +1,25 @@
+.. -*- coding: utf-8 -*-
+
+.. _BlogFiveMinutes:
+
+Get a blog running in five minutes!
+-----------------------------------
+
+First install the following packages (:ref:`DebianInstallation`)::
+
+    cubicweb, cubicweb-dev, cubicweb-blog
+
+Then create and initialize your instance::
+
+    cubicweb-ctl create blog myblog
+
+And start it::
+
+    cubicweb-ctl start -D myblog
+
+This is it. Your blog is running. Visit http://localhost:8080 and enjoy it!
+
+As a developer, you'll want to know more about developing new cubes and
+customizing the look of your instance. This is what the next section is about.
+
+
--- a/doc/book/en/intro/tutorial/blog-less-ten-minutes.rst	Wed Jul 01 11:33:18 2009 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _BlogTenMinutes:
-
-Get a Blog running in less than ten minutes!
---------------------------------------------
-
-You need to install the following packages (:ref:`DebianInstallation`)::
-
-    cubicweb, cubicweb-dev, cubicweb-blog
-
-Creation and initialization of your application by running::
-    
-    cubicweb-ctl create blog myblog
-
-Your application is now ready to go::
-
-    cubicweb-ctl start -D myblog
-
-This is it. Your blog is ready to you. Go to http://localhost:8080 and enjoy!
-
-As a developper, you'll want to know more about how to develop new
-cubes and cutomize the look of your application and this is what we
-talk about now. 
-
-
--- a/doc/book/en/intro/tutorial/components.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/intro/tutorial/components.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -67,15 +67,15 @@
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Once you modified your data model, you need to synchronize the
-database with your model. For this purpose, `CubicWeb` provides
+database with your model. For this purpose, *CubicWeb* provides
 a very useful command ``cubicweb-ctl shell blogdemo`` which
-launches an interactive migration Python shell. (see 
+launches an interactive migration Python shell. (see
 :ref:`cubicweb-ctl` for more details))
 As you modified a relation from the `BlogEntry` schema,
 run the following command:
 ::
 
   synchronize_rschema('BlogEntry')
-  
-You can now start your application and add comments to each 
+
+You can now start your application and add comments to each
 `BlogEntry`.
--- a/doc/book/en/intro/tutorial/conclusion.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/intro/tutorial/conclusion.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -3,15 +3,15 @@
 What's next?
 ------------
 
-We demonstrated how from a straight out of the box `CubicWeb`
+We demonstrated how from a straight out of the box *CubicWeb*
 installation, you can build your web-application based on a
 schema. It's all already there: views, templates, permissions,
 etc. The step forward is now for you to customize according
 to your needs.
 
 More than a web application, many features are available to
-extend your application, for example: RSS channel integration 
-(:ref:`rss`), hooks (:ref:`hooks`), support of sources such as 
-Google App Engine (:ref:`gaecontents`) and lots of others to 
+extend your application, for example: RSS channel integration
+(:ref:`rss`), hooks (:ref:`hooks`), support of sources such as
+Google App Engine (:ref:`gaecontents`) and lots of others to
 discover through our book.
 
--- a/doc/book/en/intro/tutorial/create-cube.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/intro/tutorial/create-cube.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -4,16 +4,16 @@
 ----------------
 
 The packages ``cubicweb`` and ``cubicweb-dev`` installs a command line tool
-for `CubicWeb` called ``cubicweb-ctl``. This tool provides a wide range of
-commands described in details in :ref:`cubicweb-ctl`. 
+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
+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) 
+installation, ``/usr/share/cubicweb/cubes`` for debian packages installation)
 a directory named ``blog`` reflecting the structure described in :ref:`cubesConcepts`.
 
 .. _DefineDataModel:
@@ -21,7 +21,7 @@
 Define your data model
 ----------------------
 
-The data model or schema is the core of your `CubicWeb` application.
+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``:
@@ -36,11 +36,11 @@
     title = String(required=True, fulltextindexed=True, maxsize=256)
     publish_date = Date(default='TODAY')
     content = String(required=True, fulltextindexed=True)
-    entry_of = SubjectRelation('Blog', cardinality='?*') 
+    entry_of = SubjectRelation('Blog', cardinality='?*')
 
 
 A Blog has a title and a description. The title is a string that is
-required by the class EntityType and must be less than 50 characters. 
+required by the class EntityType 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
@@ -61,7 +61,7 @@
 --------------------
 
 To use this cube as an application and create a new instance named ``blogdemo``, do::
-  
+
   cubicweb-ctl create blog blogdemo
 
 
@@ -86,12 +86,12 @@
 .. image:: ../../images/login-form.png
 
 
-Once authenticated, you can start playing with your application 
+Once authenticated, you can start playing with your application
 and create entities.
 
 .. image:: ../../images/blog-demo-first-page.png
 
-Please notice that so far, the `CubicWeb` franework managed all aspects of 
+Please notice that so far, the *CubicWeb* franework managed all aspects of
 the web application based on the schema provided at first.
 
 
@@ -142,10 +142,10 @@
 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``. 
+``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 
+new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
 combobox titled ``add relation`` would have showed up.
 
 
@@ -181,30 +181,30 @@
 The view selection principle
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-A view is defined by a Python class which includes: 
-  
-  - an identifier (all objects in `CubicWeb` are entered in a registry
+A view is defined by a Python class which includes:
+
+  - an identifier (all objects in *CubicWeb* are entered 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`;
+*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: 
+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 
+The standard library of selectors is in
 ``cubicweb.common.selector`` and a library of methods used to
 compute scores is available in ``cubicweb.vregistry.vreq``.
 
 It is possible to define multiple views for the same identifier
 and to associate selectors and filters to allow the application
-to find the best way to render the data. 
+to find the best 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 customize this view.
@@ -213,7 +213,7 @@
 View customization
 ~~~~~~~~~~~~~~~~~~
 
-If you wish to modify the way a `BlogEntry` is rendered, you will have to 
+If you wish to modify the way a `BlogEntry` is rendered, you will have to
 overwrite the `primary` view defined in the module ``views`` of the cube
 ``cubes/blog/views.py``.
 
@@ -244,7 +244,7 @@
         self.w(u'<h1>%s</h1>' % entity.title)
         self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
         self.w(u'<p>%s</p>' % entity.content)
-        
+
         # display relations
         siderelations = []
         if self.main_related_section:
@@ -261,7 +261,7 @@
    :alt: modified primary view
 
 
-The above source code defines a new primary view for ``BlogEntry``. 
+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.
--- a/doc/book/en/intro/tutorial/index.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/intro/tutorial/index.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -5,17 +5,14 @@
 Tutorial
 ========
 
-`CubicWeb` is a semantic web application framework that favors reuse and
+*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. 
+views to display the data. A cube can be built by assembling other cubes.
 
-An application is a `cube`, but usually an application is built by assembling
-a few smaller cubes.
-
-An `instance` is a specific installation of an application and includes
-configuration files.
+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
@@ -24,7 +21,7 @@
 .. toctree::
    :maxdepth: 2
 
-   blog-less-ten-minutes
+   blog-in-five-minutes
    create-cube
    components
    maintemplate
--- a/doc/book/en/intro/tutorial/maintemplate.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/intro/tutorial/maintemplate.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -11,8 +11,8 @@
 .. 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 
+interesting template from the three you will look for,
+that is to say, the HTMLPageHeader, the HTMLPageFooter
 and the TheMainTemplate.
 
 
@@ -24,14 +24,14 @@
 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
 `````````````````
@@ -47,7 +47,7 @@
 .. code-block :: 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')
@@ -115,10 +115,10 @@
 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 ``id = main`` that is used by the application. Is 
+TheMainTemplate is responsible for the general layout of the entire application.
+It defines the template of ``id = 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 
+be used based on TheMainTemplate called SimpleMainTemplate which does not have
 a top section.
 
 .. image:: ../../images/lax-book.06-simple-main-template.en.png
--- a/doc/book/en/makefile	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/makefile	Wed Jul 01 11:33:40 2009 +0200
@@ -1,5 +1,5 @@
 MKHTML=mkdoc
-MKHTMLOPTS=--doctype article --target html --stylesheet standard 
+MKHTMLOPTS=--doctype article --target html --stylesheet standard
 SRC=.
 
 TXTFILES:= $(wildcard *.txt)
@@ -9,11 +9,13 @@
 SPHINXOPTS    =
 SPHINXBUILD   = sphinx-build
 PAPER         =
+#BUILDDIR      = build
+BUILDDIR      = /tmp/cwdoc
 
 # Internal variables for sphinx
 PAPEROPT_a4     = -D latex_paper_size=a4
 PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+ALLSPHINXOPTS   = -d ${BUILDDIR}/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
 
 
 .PHONY: help clean html web pickle htmlhelp latex changes linkcheck
@@ -23,7 +25,7 @@
 	@echo "  all       to make standalone HTML files, developer manual and API doc"
 	@echo "  apidoc    to make API doc"
 	@echo "  html      to make standalone HTML files"
-	@echo "---  "	
+	@echo "---  "
 	@echo "  pickle    to make pickle files (usable by e.g. sphinx-web)"
 	@echo "  htmlhelp  to make HTML files and a HTML help project"
 	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@@ -33,59 +35,59 @@
 clean:
 	rm -rf apidoc/
 	rm -f *.html
-	-rm -rf build/*
+	-rm -rf ${BUILDDIR}/*
 
 all: ${TARGET} apidoc html
 
 %.html: %.txt
 	${MKHTML} ${MKHTMLOPTS} $<
 
-#apydoc: 
+#apydoc:
 #	epydoc --html -o epydoc/ -n ../server/*.py ../core/*.py ../common/*.py ../server/*/*.py ../modpython/*/*.py ../common/*/*.py
 apidoc:
 	epydoc --html -o apidoc -n "cubicweb" --exclude=setup --exclude=__pkginfo__ ../../../
 
 # run sphinx ###
 html:
-	mkdir -p build/html build/doctrees
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
+	mkdir -p ${BUILDDIR}/html ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) ${BUILDDIR}/html
 	@echo
-	@echo "Build finished. The HTML pages are in build/html."
+	@echo "Build finished. The HTML pages are in ${BUILDDIR}/html."
 
 pickle:
-	mkdir -p build/pickle build/doctrees
-	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
+	mkdir -p ${BUILDDIR}/pickle ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) ${BUILDDIR}/pickle
 	@echo
 	@echo "Build finished; now you can process the pickle files or run"
-	@echo "  sphinx-web build/pickle"
+	@echo "  sphinx-web ${BUILDDIR}/pickle"
 	@echo "to start the sphinx-web server."
 
 web: pickle
 
 htmlhelp:
-	mkdir -p build/htmlhelp build/doctrees
-	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
+	mkdir -p ${BUILDDIR}/htmlhelp ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) ${BUILDDIR}/htmlhelp
 	@echo
 	@echo "Build finished; now you can run HTML Help Workshop with the" \
-	      ".hhp project file in build/htmlhelp."
+	      ".hhp project file in ${BUILDDIR}/htmlhelp."
 
 latex:
-	mkdir -p build/latex build/doctrees
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
+	mkdir -p ${BUILDDIR}/latex ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) ${BUILDDIR}/latex
 	@echo
-	@echo "Build finished; the LaTeX files are in build/latex."
+	@echo "Build finished; the LaTeX files are in ${BUILDDIR}/latex."
 	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
 	      "run these through (pdf)latex."
 
 changes:
-	mkdir -p build/changes build/doctrees
-	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
+	mkdir -p ${BUILDDIR}/changes ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) ${BUILDDIR}/changes
 	@echo
-	@echo "The overview file is in build/changes."
+	@echo "The overview file is in ${BUILDDIR}/changes."
 
 linkcheck:
-	mkdir -p build/linkcheck build/doctrees
-	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
+	mkdir -p ${BUILDDIR}/linkcheck ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) ${BUILDDIR}/linkcheck
 	@echo
 	@echo "Link check complete; look for any errors in the above output " \
-	      "or in build/linkcheck/output.txt."
+	      "or in ${BUILDDIR}/linkcheck/output.txt."
--- a/doc/book/en/toc.rst	Wed Jul 01 11:33:18 2009 +0200
+++ b/doc/book/en/toc.rst	Wed Jul 01 11:33:40 2009 +0200
@@ -9,17 +9,17 @@
 .. toctree::
    :numbered:
 
-   concepts/index
-   cubes/index
-   datamodel/index
-   entityclasses/index
-   devcore/index
-   devweb/index
-   devrepo/index
-   testing/index
-   migration/index
-   webstdlib/index
+   intro/concepts/index
+   development/cubes/index
+   development/datamodel/index
+   development/entityclasses/index
+   development/devcore/index
+   development/devweb/index
+   development/devrepo/index
+   development/testing/index
+   development/migration/index
+   development/webstdlib/index
    admin/index
-   rql/index
+   annexes/rql/index
    annexes/index
 
--- a/etwist/__init__.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/etwist/__init__.py	Wed Jul 01 11:33:40 2009 +0200
@@ -1,4 +1,4 @@
-""" CW - nevow/twisted client 
+""" CW - nevow/twisted client
 
 :organization: Logilab
 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
--- a/etwist/server.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/etwist/server.py	Wed Jul 01 11:33:40 2009 +0200
@@ -138,6 +138,9 @@
                     if segments[0] == 'static':
                         # instance static directory
                         datadir = self.config.static_directory
+                    elif segments[1] == 'fckeditor':
+                        fckeditordir = self.config.ext_resources['FCKEDITOR_PATH']
+                        return static.File(fckeditordir), segments[2:]
                     else:
                         # cube static data file
                         datadir = self.config.locate_resource(segments[1])
--- a/goa/overrides/toolsutils.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/goa/overrides/toolsutils.py	Wed Jul 01 11:33:40 2009 +0200
@@ -24,7 +24,7 @@
     :param config_file: path to the configuration file
 
     :rtype: dict
-    :return: a dictionary with specified values associated to option names 
+    :return: a dictionary with specified values associated to option names
     """
     config = current = {}
     try:
--- a/goa/skel/main.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/goa/skel/main.py	Wed Jul 01 11:33:40 2009 +0200
@@ -41,7 +41,7 @@
 from cubicweb.wsgi.handler import CubicWebWSGIApplication
 application = CubicWebWSGIApplication(config, vreg=vreg)
 
-# main function so this handler module is cached 
+# main function so this handler module is cached
 def main():
     from wsgiref.handlers import CGIHandler
     CGIHandler().run(application)
--- a/goa/test/pytestconf.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/goa/test/pytestconf.py	Wed Jul 01 11:33:40 2009 +0200
@@ -6,7 +6,7 @@
 
 import cubicweb
 # remove 'mx' modules imported by cubicweb
-for modname in sys.modules.keys(): 
+for modname in sys.modules.keys():
     if modname.startswith('mx'):
         sys.modules.pop(modname)
 
--- a/md5crypt.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/md5crypt.py	Wed Jul 01 11:33:40 2009 +0200
@@ -85,7 +85,7 @@
         i = i >> 1
     final = md5.md5(ctx).digest()
     # The following is supposed to make
-    # things run slower. 
+    # things run slower.
     # my question: WTF???
     for i in xrange(1000):
         ctx1 = ''
--- a/misc/cwzope/cwzope.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/misc/cwzope/cwzope.py	Wed Jul 01 11:33:40 2009 +0200
@@ -5,7 +5,7 @@
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
-from AccessControl import getSecurityManager 
+from AccessControl import getSecurityManager
 
 from cubicweb.dbapi import connect, Connection, Cursor
 from cubicweb.common.utils import ResultSet, ResultSetIterator, ResultSetRow, Entity
--- a/misc/migration/postcreate.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/misc/migration/postcreate.py	Wed Jul 01 11:33:40 2009 +0200
@@ -43,4 +43,4 @@
 eid = add_entity('CWPermission', name=PERM_USE_TEMPLATE_FORMAT,
                  label=_('use template languages'))
 rql('SET X require_group G WHERE G name "managers", X eid %(x)s',
-    {'x': eid}, 'x')    
+    {'x': eid}, 'x')
--- a/schema.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/schema.py	Wed Jul 01 11:33:40 2009 +0200
@@ -14,6 +14,7 @@
 from warnings import warn
 
 from logilab.common.decorators import cached, clear_cache, monkeypatch
+from logilab.common.deprecation import obsolete
 from logilab.common.compat import any
 
 from yams import BadSchemaDefinition, buildobjs as ybo
@@ -32,8 +33,6 @@
 schema.use_py_datetime()
 nodes.use_py_datetime()
 
-_ = unicode
-
 BASEGROUPS = ('managers', 'users', 'guests', 'owners')
 
 _LOGGER = getLogger('cubicweb.schemaloader')
@@ -122,7 +121,7 @@
     # ensure unicode
     # added .lower() in case no translation are available
     return unicode(req._(key)).lower()
-__builtins__['display_name'] = display_name
+__builtins__['display_name'] = obsolete('display_name should be imported from cubicweb.schema')(display_name)
 
 def ERSchema_display_name(self, req, form=''):
     """return a internationalized string for the entity/relation type name in
--- a/selectors.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/selectors.py	Wed Jul 01 11:33:40 2009 +0200
@@ -189,7 +189,7 @@
         self.once_is_enough = once_is_enough
 
     @lltrace
-    def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
+    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
         if not rset:
             return 0
         score = 0
@@ -238,7 +238,7 @@
     """
 
     @lltrace
-    def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
+    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
         if not rset and not kwargs.get('entity'):
             return 0
         score = 0
@@ -287,7 +287,7 @@
 
 @objectify_selector
 @lltrace
-def none_rset(cls, req, rset, *args, **kwargs):
+def none_rset(cls, req, rset=None, *args, **kwargs):
     """accept no result set (e.g. given rset is None)"""
     if rset is None:
         return 1
@@ -295,7 +295,7 @@
 
 @objectify_selector
 @lltrace
-def any_rset(cls, req, rset, *args, **kwargs):
+def any_rset(cls, req, rset=None, *args, **kwargs):
     """accept result set, whatever the number of result it contains"""
     if rset is not None:
         return 1
@@ -303,7 +303,7 @@
 
 @objectify_selector
 @lltrace
-def nonempty_rset(cls, req, rset, *args, **kwargs):
+def nonempty_rset(cls, req, rset=None, *args, **kwargs):
     """accept any non empty result set"""
     if rset is not None and rset.rowcount:
         return 1
@@ -311,7 +311,7 @@
 
 @objectify_selector
 @lltrace
-def empty_rset(cls, req, rset, *args, **kwargs):
+def empty_rset(cls, req, rset=None, *args, **kwargs):
     """accept empty result set"""
     if rset is not None and rset.rowcount == 0:
         return 1
@@ -319,7 +319,7 @@
 
 @objectify_selector
 @lltrace
-def one_line_rset(cls, req, rset, row=None, *args, **kwargs):
+def one_line_rset(cls, req, rset=None, row=None, *args, **kwargs):
     """if row is specified, accept result set with a single line of result,
     else accepts anyway
     """
@@ -329,7 +329,7 @@
 
 @objectify_selector
 @lltrace
-def two_lines_rset(cls, req, rset, *args, **kwargs):
+def two_lines_rset(cls, req, rset=None, *args, **kwargs):
     """accept result set with *at least* two lines of result"""
     if rset is not None and rset.rowcount > 1:
         return 1
@@ -337,7 +337,7 @@
 
 @objectify_selector
 @lltrace
-def two_cols_rset(cls, req, rset, *args, **kwargs):
+def two_cols_rset(cls, req, rset=None, *args, **kwargs):
     """accept result set with at least one line and two columns of result"""
     if rset is not None and rset.rowcount and len(rset.rows[0]) > 1:
         return 1
@@ -345,7 +345,7 @@
 
 @objectify_selector
 @lltrace
-def paginated_rset(cls, req, rset, *args, **kwargs):
+def paginated_rset(cls, req, rset=None, *args, **kwargs):
     """accept result set with more lines than the page size.
 
     Page size is searched in (respecting order):
@@ -366,7 +366,7 @@
 
 @objectify_selector
 @lltrace
-def sorted_rset(cls, req, rset, row=None, col=0, **kwargs):
+def sorted_rset(cls, req, rset=None, row=None, col=0, **kwargs):
     """accept sorted result set"""
     rqlst = rset.syntax_tree()
     if len(rqlst.children) > 1 or not rqlst.children[0].orderby:
@@ -375,7 +375,7 @@
 
 @objectify_selector
 @lltrace
-def one_etype_rset(cls, req, rset, row=None, col=0, *args, **kwargs):
+def one_etype_rset(cls, req, rset=None, row=None, col=0, *args, **kwargs):
     """accept result set where entities in the specified column (or 0) are all
     of the same type
     """
@@ -387,7 +387,7 @@
 
 @objectify_selector
 @lltrace
-def two_etypes_rset(cls, req, rset, row=None, col=0, **kwargs):
+def two_etypes_rset(cls, req, rset=None, row=None, col=0, **kwargs):
     """accept result set where entities in the specified column (or 0) are not
     of the same type
     """
@@ -420,7 +420,7 @@
 
 @objectify_selector
 @lltrace
-def primary_view(cls, req, rset, row=None, col=0, view=None, **kwargs):
+def primary_view(cls, req, rset=None, row=None, col=0, view=None, **kwargs):
     """accept if view given as named argument is a primary view, or if no view
     is given
     """
@@ -430,7 +430,7 @@
 
 @objectify_selector
 @lltrace
-def match_context_prop(cls, req, rset, row=None, col=0, context=None,
+def match_context_prop(cls, req, rset=None, row=None, col=0, context=None,
                        **kwargs):
     """accept if:
     * no context given
@@ -461,7 +461,7 @@
                            ','.join(sorted(str(s) for s in self.expected)))
 
     @lltrace
-    def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
+    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
         try:
             if not req.search_state[0] in self.expected:
                 return 0
@@ -554,7 +554,7 @@
     initializer
     """
     @lltrace
-    def __call__(self, cls, req, rset, row=None, col=0, view=None, **kwargs):
+    def __call__(self, cls, req, rset=None, row=None, col=0, view=None, **kwargs):
         if view is None or not view.id in self.expected:
             return 0
         return 1
@@ -571,7 +571,7 @@
         self.registry = registry
         self.oid = oid
 
-    def __call__(self, cls, req, rset, *args, **kwargs):
+    def __call__(self, cls, req, rset=None, *args, **kwargs):
         try:
             cls.vreg.select_object(self.registry, self.oid, req, rset, *args, **kwargs)
             return 1
@@ -850,7 +850,7 @@
         self.action = action
 
     @lltrace
-    def __call__(self, cls, req, rset, row=None, col=0, **kwargs):
+    def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs):
         if rset is None:
             return 0
         user = req.user
@@ -985,11 +985,11 @@
 primaryview_selector = deprecated_function(primary_view)
 contextprop_selector = deprecated_function(match_context_prop)
 
-def nfentity_selector(cls, req, rset, row=None, col=0, **kwargs):
+def nfentity_selector(cls, req, rset=None, row=None, col=0, **kwargs):
     return non_final_entity()(cls, req, rset, row, col)
 nfentity_selector = deprecated_function(nfentity_selector)
 
-def implement_interface(cls, req, rset, row=None, col=0, **kwargs):
+def implement_interface(cls, req, rset=None, row=None, col=0, **kwargs):
     return implements(*cls.accepts_interfaces)(cls, req, rset, row, col)
 _interface_selector = deprecated_function(implement_interface)
 interface_selector = deprecated_function(implement_interface)
@@ -1001,7 +1001,7 @@
 etype_form_selector = deprecated_function(accept_etype)
 accept_etype = deprecated_function(accept_etype, 'use specified_etype_implements')
 
-def searchstate_selector(cls, req, rset, row=None, col=0, **kwargs):
+def searchstate_selector(cls, req, rset=None, row=None, col=0, **kwargs):
     return match_search_state(cls.search_states)(cls, req, rset, row, col)
 searchstate_selector = deprecated_function(searchstate_selector)
 
@@ -1010,18 +1010,18 @@
 in_group_selector = deprecated_function(match_user_group)
 match_user_group = deprecated_function(match_user_group)
 
-def has_relation(cls, req, rset, row=None, col=0, **kwargs):
+def has_relation(cls, req, rset=None, row=None, col=0, **kwargs):
     return relation_possible(cls.rtype, role(cls), cls.etype,
                              getattr(cls, 'require_permission', 'read'))(cls, req, rset, row, col, **kwargs)
 has_relation = deprecated_function(has_relation)
 
-def one_has_relation(cls, req, rset, row=None, col=0, **kwargs):
+def one_has_relation(cls, req, rset=None, row=None, col=0, **kwargs):
     return relation_possible(cls.rtype, role(cls), cls.etype,
                              getattr(cls, 'require_permission', 'read',
                                      once_is_enough=True))(cls, req, rset, row, col, **kwargs)
 one_has_relation = deprecated_function(one_has_relation, 'use relation_possible selector')
 
-def accept_rset(cls, req, rset, row=None, col=0, **kwargs):
+def accept_rset(cls, req, rset=None, row=None, col=0, **kwargs):
     """simply delegate to cls.accept_rset method"""
     return implements(*cls.accepts)(cls, req, rset, row=row, col=col)
 accept_rset_selector = deprecated_function(accept_rset)
@@ -1036,7 +1036,7 @@
 accept_one_selector = deprecated_function(accept_one)
 
 
-def _rql_condition(cls, req, rset, row=None, col=0, **kwargs):
+def _rql_condition(cls, req, rset=None, row=None, col=0, **kwargs):
     if cls.condition:
         return rql_condition(cls.condition)(cls, req, rset, row, col)
     return 1
@@ -1045,12 +1045,12 @@
 rqlcondition_selector = deprecated_function(chainall(non_final_entity(), one_line_rset, _rql_condition,
                          name='rql_condition'))
 
-def but_etype_selector(cls, req, rset, row=None, col=0, **kwargs):
+def but_etype_selector(cls, req, rset=None, row=None, col=0, **kwargs):
     return but_etype(cls.etype)(cls, req, rset, row, col)
 but_etype_selector = deprecated_function(but_etype_selector)
 
 @lltrace
-def etype_rtype_selector(cls, req, rset, row=None, col=0, **kwargs):
+def etype_rtype_selector(cls, req, rset=None, row=None, col=0, **kwargs):
     schema = cls.schema
     perm = getattr(cls, 'require_permission', 'read')
     if hasattr(cls, 'etype'):
--- a/server/__init__.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/__init__.py	Wed Jul 01 11:33:40 2009 +0200
@@ -120,7 +120,7 @@
     handler.cmd_add_entity('CWProperty', pkey=u'system.version.cubicweb',
                            value=unicode(config.cubicweb_version()))
     for cube in config.cubes():
-        handler.cmd_add_entity('CWProperty', 
+        handler.cmd_add_entity('CWProperty',
                                pkey=u'system.version.%s' % cube.lower(),
                                value=unicode(config.cube_version(cube)))
     # yoo !
--- a/server/hooks.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/hooks.py	Wed Jul 01 11:33:40 2009 +0200
@@ -85,16 +85,16 @@
     """
     ftcontainer = session.repo.schema.rschema(rtype).fulltext_container
     if ftcontainer == 'subject':
-        FTIndexEntityOp(session, entity=session.entity(eidto))
+        FTIndexEntityOp(session, entity=session.entity_from_eid(eidto))
     elif ftcontainer == 'object':
-        FTIndexEntityOp(session, entity=session.entity(eidfrom))
+        FTIndexEntityOp(session, entity=session.entity_from_eid(eidfrom))
 def fti_update_after_delete_relation(session, eidfrom, rtype, eidto):
     """sync fulltext index when relevant relation is deleted. Reindexing both
     entities is necessary.
     """
     if session.repo.schema.rschema(rtype).fulltext_container:
-        FTIndexEntityOp(session, entity=session.entity(eidto))
-        FTIndexEntityOp(session, entity=session.entity(eidfrom))
+        FTIndexEntityOp(session, entity=session.entity_from_eid(eidto))
+        FTIndexEntityOp(session, entity=session.entity_from_eid(eidfrom))
 
 class SyncOwnersOp(PreCommitOperation):
 
@@ -379,7 +379,7 @@
     etype = session.describe(fromeid)[0]
     if not (session.is_super_session or 'managers' in session.user.groups):
         if not state is None:
-            entity = session.entity(fromeid)
+            entity = session.entity_from_eid(fromeid)
             # we should find at least one transition going to this state
             try:
                 iter(state.transitions(entity, toeid)).next()
--- a/server/msplanner.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/msplanner.py	Wed Jul 01 11:33:40 2009 +0200
@@ -553,9 +553,19 @@
         # NOTE: < 2 since may be 0 on queries such as Any X WHERE X eid 2
         if len(self._sourcesterms) < 2:
             self.needsplit = False
+            # if this is not the system source but we have only constant terms
+            # and no relation (other than eid), apply query on the system source
+            #
+            # testing for rqlst with nothing in vargraph nor defined_vars is the
+            # simplest way the check the condition explained below
+            if not self.system_source in self._sourcesterms and \
+                   not self.rqlst.vargraph and not self.rqlst.defined_vars:
+                self._sourcesterms = {self.system_source: {}}
         elif not self.needsplit:
             if not allequals(self._sourcesterms.itervalues()):
-                for terms in self._sourcesterms.itervalues():
+                for source, terms in self._sourcesterms.iteritems():
+                    if source is self.system_source:
+                        continue
                     if any(x for x in terms if not isinstance(x, Constant)):
                         self.needsplit = True
                         return
--- a/server/repository.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/repository.py	Wed Jul 01 11:33:40 2009 +0200
@@ -209,11 +209,6 @@
             # initialized)
             for source in self.sources:
                 source.init()
-            # call application level initialisation hooks
-            self.hm.call_hooks('server_startup', repo=self)
-            # register a task to cleanup expired session
-            self.looping_task(self.config['session-time']/3.,
-                              self.clean_sessions)
         else:
             # call init_creating so for instance native source can configurate
             # tsearch according to postgres version
@@ -225,6 +220,12 @@
         for i in xrange(config['connections-pool-size']):
             self._available_pools.put_nowait(ConnectionsPool(self.sources))
         self._shutting_down = False
+        if not config.creating:
+            # call application level initialisation hooks
+            self.hm.call_hooks('server_startup', repo=self)
+            # register a task to cleanup expired session
+            self.looping_task(self.config['session-time']/3.,
+                              self.clean_sessions)
 
     # internals ###############################################################
 
@@ -342,7 +343,6 @@
                             'connections pools size)')
 
     def _free_pool(self, pool):
-        pool.rollback()
         self._available_pools.put_nowait(pool)
 
     def pinfo(self):
--- a/server/rqlannotation.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/rqlannotation.py	Wed Jul 01 11:33:40 2009 +0200
@@ -22,21 +22,7 @@
     has_text_query = False
     need_distinct = rqlst.distinct
     for rel in rqlst.iget_nodes(Relation):
-        if rel.neged(strict=True):
-            if rel.is_types_restriction():
-                need_distinct = True
-            else:
-                rschema = getrschema(rel.r_type)
-                if not rschema.is_final():
-                    if rschema.inlined:
-                        try:
-                            var = rel.children[1].children[0].variable
-                        except AttributeError:
-                            pass # rewritten variable
-                        else:
-                            if not var.stinfo['constnode']:
-                                need_distinct = True
-        elif getrschema(rel.r_type).symetric:
+        if getrschema(rel.r_type).symetric:
             for vref in rel.iget_nodes(VariableRef):
                 stinfo = vref.variable.stinfo
                 if not stinfo['constnode'] and stinfo['selected']:
--- a/server/schemahooks.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/schemahooks.py	Wed Jul 01 11:33:40 2009 +0200
@@ -38,7 +38,7 @@
 def get_constraints(session, entity):
     constraints = []
     for cstreid in session.transaction_data.get(entity.eid, ()):
-        cstrent = session.entity(cstreid)
+        cstrent = session.entity_from_eid(cstreid)
         cstr = CONSTRAINTS[cstrent.type].deserialize(cstrent.value)
         cstr.eid = cstreid
         constraints.append(cstr)
--- a/server/schemaserial.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/schemaserial.py	Wed Jul 01 11:33:40 2009 +0200
@@ -136,7 +136,7 @@
                                {'x': etype, 'n': netype})
             # XXX should be donne as well on sqlite based sources
             if not etype in OLD_SCHEMA_TYPES and \
-               (getattr(dbhelper, 'case_sensitive', False) 
+               (getattr(dbhelper, 'case_sensitive', False)
                 or etype.lower() != netype.lower()):
                 session.system_sql('ALTER TABLE %s%s RENAME TO %s%s' % (
                     sqlutils.SQL_PREFIX, etype, sqlutils.SQL_PREFIX, netype))
--- a/server/session.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/session.py	Wed Jul 01 11:33:40 2009 +0200
@@ -84,10 +84,6 @@
         """return an entity class for the given entity type"""
         return self.vreg.etype_class(etype)
 
-    def entity(self, eid):
-        """return a result set for the given eid"""
-        return self.eid_rset(eid).get_entity(0, 0)
-
     def system_sql(self, sql, args=None):
         """return a sql cursor on the system database"""
         if not sql.split(None, 1)[0].upper() == 'SELECT':
@@ -270,6 +266,7 @@
             assert not self.pending_operations
             self.transaction_data.clear()
             self._touch()
+            self.debug('commit session %s done (no db activity)', self.id)
             return
         if self.commit_state:
             return
@@ -311,6 +308,7 @@
             assert not self.pending_operations
             self.transaction_data.clear()
             self._touch()
+            self.debug('rollback session %s done (no db activity)', self.id)
             return
         try:
             while self.pending_operations:
@@ -321,6 +319,7 @@
                     self.critical('rollback error', exc_info=sys.exc_info())
                     continue
             self.pool.rollback()
+            self.debug('rollback for session %s done', self.id)
         finally:
             self._touch()
             self.pending_operations[:] = []
@@ -359,16 +358,6 @@
             self._threaddata.transaction_data = {}
             return self._threaddata.transaction_data
 
-    @obsolete('use direct access to session.transaction_data')
-    def query_data(self, key, default=None, setdefault=False, pop=False):
-        if setdefault:
-            assert not pop
-            return self.transaction_data.setdefault(key, default)
-        if pop:
-            return self.transaction_data.pop(key, default)
-        else:
-            return self.transaction_data.get(key, default)
-
     @property
     def pending_operations(self):
         try:
@@ -457,6 +446,21 @@
             description.append(tuple(row_descr))
         return description
 
+    @obsolete('use direct access to session.transaction_data')
+    def query_data(self, key, default=None, setdefault=False, pop=False):
+        if setdefault:
+            assert not pop
+            return self.transaction_data.setdefault(key, default)
+        if pop:
+            return self.transaction_data.pop(key, default)
+        else:
+            return self.transaction_data.get(key, default)
+
+    @obsolete('use entity_from_eid(eid, etype=None)')
+    def entity(self, eid):
+        """return a result set for the given eid"""
+        return self.eid_rset(eid).get_entity(0, 0)
+
 
 class ChildSession(Session):
     """child (or internal) session are used to hijack the security system
--- a/server/sources/rql2sql.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/sources/rql2sql.py	Wed Jul 01 11:33:40 2009 +0200
@@ -490,10 +490,10 @@
                 sql.insert(1, 'FROM (SELECT 1) AS _T')
             sqls.append('\n'.join(sql))
         if select.need_intersect:
-            if distinct or not self.dbms_helper.intersect_all_support:
-                return '\nINTERSECT\n'.join(sqls)
-            else:
-                return '\nINTERSECT ALL\n'.join(sqls)
+            #if distinct or not self.dbms_helper.intersect_all_support:
+            return '\nINTERSECT\n'.join(sqls)
+            #else:
+            #    return '\nINTERSECT ALL\n'.join(sqls)
         elif distinct:
             return '\nUNION\n'.join(sqls)
         else:
@@ -661,13 +661,27 @@
         lhsvar, _, rhsvar, rhsconst = relation_info(relation)
         # we are sure here to have a lhsvar
         assert lhsvar is not None
-        lhssql = self._inlined_var_sql(lhsvar, relation.r_type)
         if isinstance(relation.parent, Not):
             self._state.done.add(relation.parent)
-            sql = "%s IS NULL" % lhssql
             if rhsvar is not None and not rhsvar._q_invariant:
-                sql = '(%s OR %s!=%s)' % (sql, lhssql, rhsvar.accept(self))
+                # if the lhs variable is only linked to this relation, this mean we
+                # only want the relation to NOT exists
+                self._state.push_scope()
+                lhssql = self._inlined_var_sql(lhsvar, relation.r_type)
+                rhssql = rhsvar.accept(self)
+                restrictions, tables = self._state.pop_scope()
+                restrictions.append('%s=%s' % (lhssql, rhssql))
+                if not tables:
+                    sql = 'NOT EXISTS(SELECT 1 WHERE %s)' % (
+                        ' AND '.join(restrictions))
+                else:
+                    sql = 'NOT EXISTS(SELECT 1 FROM %s WHERE %s)' % (
+                        ', '.join(tables), ' AND '.join(restrictions))
+            else:
+                lhssql = self._inlined_var_sql(lhsvar, relation.r_type)
+                sql = '%s IS NULL' % self._inlined_var_sql(lhsvar, relation.r_type)
             return sql
+        lhssql = self._inlined_var_sql(lhsvar, relation.r_type)
         if rhsconst is not None:
             return '%s=%s' % (lhssql, rhsconst.accept(self))
         if isinstance(rhsvar, Variable) and not rhsvar.name in self._varmap:
--- a/server/test/unittest_extlite.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/test/unittest_extlite.py	Wed Jul 01 11:33:40 2009 +0200
@@ -7,37 +7,32 @@
     sqlite_file = '_extlite_test.sqlite'
     def setUp(self):
         cnx1 = get_connection('sqlite', database=self.sqlite_file)
-        print 'SET IP'
         cu = cnx1.cursor()
         cu.execute('CREATE TABLE toto(name integer);')
         cnx1.commit()
         cnx1.close()
-        
+
     def tearDown(self):
         try:
             os.remove(self.sqlite_file)
         except:
             pass
+        
     def test(self):
         lock = threading.Lock()
-        
+
         def run_thread():
-            print 'run_thread'
             cnx2 = get_connection('sqlite', database=self.sqlite_file)
             lock.acquire()
-            print 't2 sel1'
             cu = cnx2.cursor()
             cu.execute('SELECT name FROM toto')
             self.failIf(cu.fetchall())
             cnx2.commit()
-            print 'done'
             lock.release()
             time.sleep(0.1)
             lock.acquire()
-            print 't2 sel2'
             cu.execute('SELECT name FROM toto')
             self.failUnless(cu.fetchall())
-            print 'done'
             lock.release()
 
         cnx1 = get_connection('sqlite', database=self.sqlite_file)
@@ -45,17 +40,13 @@
         thread = threading.Thread(target=run_thread)
         thread.start()
         cu = cnx1.cursor()
-        print 't1 sel'
         cu.execute('SELECT name FROM toto')
-        print 'done'
         lock.release()
         time.sleep(0.1)
         cnx1.commit()
         lock.acquire()
-        print 't1 insert'
         cu.execute("INSERT INTO toto(name) VALUES ('toto')")
         cnx1.commit()
-        print 'done'
         lock.release()
 
 if __name__ == '__main__':
--- a/server/test/unittest_msplanner.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/test/unittest_msplanner.py	Wed Jul 01 11:33:40 2009 +0200
@@ -1934,6 +1934,29 @@
                      [])],
                    {'x': self.session.user.eid})
 
+    def test_nonregr14_1(self):
+        repo._type_source_cache[999999] = ('CWUser', 'ldap', 999999)
+        self._test('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',
+                   [('OneFetchStep', [('Any 999999 WHERE 999999 owned_by 999999', [{}])],
+                     None, None, [self.system], {}, [])],
+                   {'x': 999999, 'u': 999999})
+
+    def test_nonregr14_2(self):
+        repo._type_source_cache[999999] = ('CWUser', 'ldap', 999999)
+        repo._type_source_cache[999998] = ('Note', 'system', 999998)
+        self._test('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',
+                   [('OneFetchStep', [('Any 999998 WHERE 999998 owned_by 999999', [{}])],
+                     None, None, [self.system], {}, [])],
+                   {'x': 999998, 'u': 999999})
+
+    def test_nonregr14_3(self):
+        repo._type_source_cache[999999] = ('CWUser', 'system', 999999)
+        repo._type_source_cache[999998] = ('CWUser', 'ldap', 999998)
+        self._test('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',
+                   [('OneFetchStep', [('Any 999998 WHERE 999998 owned_by 999999', [{}])],
+                     None, None, [self.system], {}, [])],
+                   {'x': 999998, 'u': 999999})
+
 
 class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
     """test planner related feature on a 3-sources repository:
@@ -2072,6 +2095,14 @@
                      )],
                    {'x': 999999})
 
+    def test_nonregr_eid_query(self):
+        self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
+        self._test('Any X WHERE X eid 999999',
+                   [('OneFetchStep', [('Any 999999', [{}])],
+                     None, None, [self.system], {}, []
+                     )],
+                   {'x': 999999})
+
 
 
 class FakeVCSSource(AbstractSource):
--- a/server/test/unittest_repository.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/test/unittest_repository.py	Wed Jul 01 11:33:40 2009 +0200
@@ -56,13 +56,12 @@
         namecol = SQL_PREFIX + 'name'
         finalcol = SQL_PREFIX + 'final'
         try:
-            sqlcursor = pool['system']
-            sqlcursor.execute('SELECT %s FROM %s WHERE %s is NULL' % (
+            cu = self.session.system_sql('SELECT %s FROM %s WHERE %s is NULL' % (
                 namecol, table, finalcol))
-            self.assertEquals(sqlcursor.fetchall(), [])
-            sqlcursor.execute('SELECT %s FROM %s WHERE %s=%%(final)s ORDER BY %s'
+            self.assertEquals(cu.fetchall(), [])
+            cu = self.session.system_sql('SELECT %s FROM %s WHERE %s=%%(final)s ORDER BY %s'
                               % (namecol, table, finalcol, namecol), {'final': 'TRUE'})
-            self.assertEquals(sqlcursor.fetchall(), [(u'Boolean',), (u'Bytes',),
+            self.assertEquals(cu.fetchall(), [(u'Boolean',), (u'Bytes',),
                                                      (u'Date',), (u'Datetime',),
                                                      (u'Decimal',),(u'Float',),
                                                      (u'Int',),
@@ -358,38 +357,36 @@
         entity.eid = -1
         entity.complete = lambda x: None
         self.repo.add_info(self.session, entity, self.repo.sources_by_uri['system'])
-        cursor = self.session.pool['system']
-        cursor.execute('SELECT * FROM entities WHERE eid = -1')
-        data = cursor.fetchall()
+        cu = self.session.system_sql('SELECT * FROM entities WHERE eid = -1')
+        data = cu.fetchall()
         self.assertIsInstance(data[0][3], datetime)
         data[0] = list(data[0])
         data[0][3] = None
         self.assertEquals(tuplify(data), [(-1, 'Personne', 'system', None, None)])
         self.repo.delete_info(self.session, -1)
         #self.repo.commit()
-        cursor.execute('SELECT * FROM entities WHERE eid = -1')
-        data = cursor.fetchall()
+        cu = self.session.system_sql('SELECT * FROM entities WHERE eid = -1')
+        data = cu.fetchall()
         self.assertEquals(data, [])
 
 
 class FTITC(RepositoryBasedTC):
 
     def test_reindex_and_modified_since(self):
-        cursor = self.session.pool['system']
         eidp = self.execute('INSERT Personne X: X nom "toto", X prenom "tutu"')[0][0]
         self.commit()
         ts = datetime.now()
         self.assertEquals(len(self.execute('Personne X WHERE X has_text "tutu"')), 1)
-        cursor.execute('SELECT mtime, eid FROM entities WHERE eid = %s' % eidp)
-        omtime = cursor.fetchone()[0]
+        cu = self.session.system_sql('SELECT mtime, eid FROM entities WHERE eid = %s' % eidp)
+        omtime = cu.fetchone()[0]
         # our sqlite datetime adapter is ignore seconds fraction, so we have to
         # ensure update is done the next seconds
         time.sleep(1 - (ts.second - int(ts.second)))
         self.execute('SET X nom "tata" WHERE X eid %(x)s', {'x': eidp}, 'x')
         self.commit()
         self.assertEquals(len(self.execute('Personne X WHERE X has_text "tutu"')), 1)
-        cursor.execute('SELECT mtime FROM entities WHERE eid = %s' % eidp)
-        mtime = cursor.fetchone()[0]
+        cu = self.session.system_sql('SELECT mtime FROM entities WHERE eid = %s' % eidp)
+        mtime = cu.fetchone()[0]
         self.failUnless(omtime < mtime)
         self.commit()
         date, modified, deleted = self.repo.entities_modified_since(('Personne',), omtime)
--- a/server/test/unittest_rql2sql.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/test/unittest_rql2sql.py	Wed Jul 01 11:33:40 2009 +0200
@@ -251,9 +251,9 @@
 
     # Any O WHERE NOT S corrected_in O, S eid %(x)s, S concerns P, O version_of P, O in_state ST, NOT ST name "published", O modification_date MTIME ORDERBY MTIME DESC LIMIT 9
     ('Any O WHERE NOT S ecrit_par O, S eid 1, S inline1 P, O inline2 P',
-     '''SELECT DISTINCT O.cw_eid
+     '''SELECT O.cw_eid
 FROM cw_Note AS S, cw_Personne AS O
-WHERE (S.cw_ecrit_par IS NULL OR S.cw_ecrit_par!=O.cw_eid) AND S.cw_eid=1 AND O.cw_inline2=S.cw_inline1'''),
+WHERE NOT EXISTS(SELECT 1 WHERE S.cw_ecrit_par=O.cw_eid) AND S.cw_eid=1 AND O.cw_inline2=S.cw_inline1'''),
 
     ('DISTINCT Any S ORDERBY stockproc(SI) WHERE NOT S ecrit_par O, S para SI',
      '''SELECT T1.C0 FROM (SELECT DISTINCT S.cw_eid AS C0, STOCKPROC(S.cw_para) AS C1
@@ -698,7 +698,6 @@
 FROM cw_Tag AS S, cw_Tag AS T, tags_relation AS rel_tags0
 WHERE NOT (T.cw_eid=28258) AND rel_tags0.eid_from=T.cw_eid AND rel_tags0.eid_to=S.cw_eid'''),
 
-
     ('Any X,Y WHERE X created_by Y, X eid 5, NOT Y eid 6',
      '''SELECT 5, rel_created_by0.eid_to
 FROM created_by_relation AS rel_created_by0
@@ -736,25 +735,25 @@
 WHERE NOT EXISTS(SELECT 1 FROM evaluee_relation AS rel_evaluee0,cw_CWUser AS Y WHERE rel_evaluee0.eid_from=Y.cw_eid AND rel_evaluee0.eid_to=X.cw_eid)'''),
 
     ('Any X,T WHERE X title T, NOT X is Bookmark',
-     '''SELECT DISTINCT X.cw_eid, X.cw_title
+     '''SELECT X.cw_eid, X.cw_title
 FROM cw_Card AS X
-UNION
-SELECT DISTINCT X.cw_eid, X.cw_title
+UNION ALL
+SELECT X.cw_eid, X.cw_title
 FROM cw_EmailThread AS X'''),
 
     ('Any K,V WHERE P is CWProperty, P pkey K, P value V, NOT P for_user U',
-     '''SELECT DISTINCT P.cw_pkey, P.cw_value
+     '''SELECT P.cw_pkey, P.cw_value
 FROM cw_CWProperty AS P
 WHERE P.cw_for_user IS NULL'''),
 
     ('Any S WHERE NOT X in_state S, X is IN(Affaire, CWUser)',
-     '''SELECT DISTINCT S.cw_eid
-FROM cw_Affaire AS X, cw_State AS S
-WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)
+     '''SELECT S.cw_eid
+FROM cw_State AS S
+WHERE NOT EXISTS(SELECT 1 FROM cw_Affaire AS X WHERE X.cw_in_state=S.cw_eid)
 INTERSECT
-SELECT DISTINCT S.cw_eid
-FROM cw_CWUser AS X, cw_State AS S
-WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)'''),
+SELECT S.cw_eid
+FROM cw_State AS S
+WHERE NOT EXISTS(SELECT 1 FROM cw_CWUser AS X WHERE X.cw_in_state=S.cw_eid)'''),
     ]
 
 OUTER_JOIN = [
@@ -1030,9 +1029,9 @@
 WHERE N.cw_ecrit_par=P.cw_eid AND N.cw_eid=0'''),
 
     ('Any N WHERE NOT N ecrit_par P, P nom "toto"',
-     '''SELECT DISTINCT N.cw_eid
+     '''SELECT N.cw_eid
 FROM cw_Note AS N, cw_Personne AS P
-WHERE (N.cw_ecrit_par IS NULL OR N.cw_ecrit_par!=P.cw_eid) AND P.cw_nom=toto'''),
+WHERE NOT EXISTS(SELECT 1 WHERE N.cw_ecrit_par=P.cw_eid) AND P.cw_nom=toto'''),
 
     ('Any P WHERE N ecrit_par P, N eid 0',
     '''SELECT N.cw_ecrit_par
@@ -1045,9 +1044,9 @@
 WHERE N.cw_ecrit_par=P.cw_eid AND N.cw_eid=0'''),
 
     ('Any P WHERE NOT N ecrit_par P, P is Personne, N eid 512',
-     '''SELECT DISTINCT P.cw_eid
+     '''SELECT P.cw_eid
 FROM cw_Note AS N, cw_Personne AS P
-WHERE (N.cw_ecrit_par IS NULL OR N.cw_ecrit_par!=P.cw_eid) AND N.cw_eid=512'''),
+WHERE NOT EXISTS(SELECT 1 WHERE N.cw_ecrit_par=P.cw_eid) AND N.cw_eid=512'''),
 
     ('Any S,ES,T WHERE S state_of ET, ET name "CWUser", ES allowed_transition T, T destination_state S',
      '''SELECT T.cw_destination_state, rel_allowed_transition1.eid_from, T.cw_eid
@@ -1070,23 +1069,23 @@
 
 INTERSECT = [
     ('Any SN WHERE NOT X in_state S, S name SN',
-     '''SELECT DISTINCT S.cw_name
-FROM cw_Affaire AS X, cw_State AS S
-WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)
+     '''SELECT S.cw_name
+FROM cw_State AS S
+WHERE NOT EXISTS(SELECT 1 FROM cw_Affaire AS X WHERE X.cw_in_state=S.cw_eid)
 INTERSECT
-SELECT DISTINCT S.cw_name
-FROM cw_CWUser AS X, cw_State AS S
-WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)
+SELECT S.cw_name
+FROM cw_State AS S
+WHERE NOT EXISTS(SELECT 1 FROM cw_CWUser AS X WHERE X.cw_in_state=S.cw_eid)
 INTERSECT
-SELECT DISTINCT S.cw_name
-FROM cw_Note AS X, cw_State AS S
-WHERE (X.cw_in_state IS NULL OR X.cw_in_state!=S.cw_eid)'''),
+SELECT S.cw_name
+FROM cw_State AS S
+WHERE NOT EXISTS(SELECT 1 FROM cw_Note AS X WHERE X.cw_in_state=S.cw_eid)'''),
 
     ('Any PN WHERE NOT X travaille S, X nom PN, S is IN(Division, Societe)',
      '''SELECT X.cw_nom
 FROM cw_Personne AS X
 WHERE NOT EXISTS(SELECT 1 FROM travaille_relation AS rel_travaille0,cw_Division AS S WHERE rel_travaille0.eid_from=X.cw_eid AND rel_travaille0.eid_to=S.cw_eid)
-INTERSECT ALL
+INTERSECT
 SELECT X.cw_nom
 FROM cw_Personne AS X
 WHERE NOT EXISTS(SELECT 1 FROM travaille_relation AS rel_travaille0,cw_Societe AS S WHERE rel_travaille0.eid_from=X.cw_eid AND rel_travaille0.eid_to=S.cw_eid)'''),
--- a/server/test/unittest_schemaserial.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/server/test/unittest_schemaserial.py	Wed Jul 01 11:33:40 2009 +0200
@@ -94,7 +94,7 @@
             ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWAttribute',
              {'rt': 'cardinality', 'oe': 'String', 'ctname': u'SizeConstraint', 'se': 'CWAttribute', 'value': u'max=2'}),
             ('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, ER name %(rt)s, SE name %(se)s, OE name %(oe)s, EDEF is CWAttribute',
-             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'StaticVocabularyConstraint', 'se': 'CWAttribute', 'value': u"u'?1', u'11', u'??', u'1?'"}),
+             {'rt': 'cardinality', 'oe': 'String', 'ctname': u'StaticVocabularyConstraint', 'se': 'CWAttribute', 'value': u"u'?1', u'11'"}),
             ])
 
 
--- a/skeleton/__pkginfo__.py.tmpl	Wed Jul 01 11:33:18 2009 +0200
+++ b/skeleton/__pkginfo__.py.tmpl	Wed Jul 01 11:33:40 2009 +0200
@@ -17,16 +17,16 @@
 short_desc = '%(shortdesc)s'
 long_desc = '''%(longdesc)s'''
 
-from os import listdir as _listdir
-from os.path import join, isdir
-
 web = 'http://www.cubicweb.org/project/%%s' %% distname
 
 pyversions = ['2.4']
 
-#from cubicweb.devtools.pkginfo import get_distutils_datafiles
-CUBES_DIR = join('share', 'cubicweb', 'cubes')
-THIS_CUBE_DIR = join(CUBES_DIR, '%(cubename)s')
+
+from os import listdir as _listdir
+from os.path import join, isdir, exists, dirname
+from glob import glob
+
+THIS_CUBE_DIR = join('share', 'cubicweb', 'cubes', modname)
 
 def listdir(dirpath):
     return [join(dirpath, fname) for fname in _listdir(dirpath)
@@ -34,12 +34,11 @@
             and not fname.endswith('~')
             and not isdir(join(dirpath, fname))]
 
-from glob import glob
 try:
     data_files = [
         # common files
         [THIS_CUBE_DIR, [fname for fname in glob('*.py') if fname != 'setup.py']],
-        ]    
+        ]
     # check for possible extended cube layout
     for dirname in ('entities', 'views', 'sobjects', 'hooks', 'schema', 'data', 'i18n', 'migration'):
         if isdir(dirname):
@@ -47,8 +46,9 @@
     # Note: here, you'll need to add subdirectories if you want
     # them to be included in the debian package
 except OSError:
+    if exists(dirname(__file__)):
+        raise
     # we are in an installed directory
-    pass
 
 
 cube_eid = None # <=== FIXME if you need direct bug-subscription
--- a/sobjects/supervising.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/sobjects/supervising.py	Wed Jul 01 11:33:40 2009 +0200
@@ -48,7 +48,7 @@
     events = ('before_delete_entity',)
 
     def _call(self, eid):
-        entity = self.session.entity(eid)
+        entity = self.session.entity_from_eid(eid)
         try:
             title = entity.dc_title()
         except:
--- a/test/unittest_entity.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/test/unittest_entity.py	Wed Jul 01 11:33:40 2009 +0200
@@ -296,6 +296,8 @@
         self.assertEquals(e.printable_value('content'), e['content'])
         e['content'] = u'été'
         self.assertEquals(e.printable_value('content'), e['content'])
+        e['content'] = u'hop\r\nhop\nhip\rmomo'
+        self.assertEquals(e.printable_value('content'), u'hop\nhop\nhip\nmomo')
 
 
     def test_fulltextindex(self):
--- a/view.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/view.py	Wed Jul 01 11:33:40 2009 +0200
@@ -369,20 +369,20 @@
 
     category = 'anyrsetview'
 
-    def columns_labels(self, tr=True):
+    def columns_labels(self, mainindex=0, tr=True):
         if tr:
-            translate = display_name
+            translate = lambda val, req=self.req: display_name(req, val)
         else:
-            translate = lambda req, val: val
-        rqlstdescr = self.rset.syntax_tree().get_description()[0] # XXX missing Union support
+            translate = lambda val: val
+        # XXX [0] because of missing Union support
+        rqlstdescr = self.rset.syntax_tree().get_description(mainindex,
+                                                             translate)[0]
         labels = []
-        for colindex, attr in enumerate(rqlstdescr):
+        for colindex, label in enumerate(rqlstdescr):
             # compute column header
-            if colindex == 0 or attr == 'Any': # find a better label
-                label = ','.join(translate(self.req, et)
+            if label == 'Any': # find a better label
+                label = ','.join(translate(et)
                                  for et in self.rset.column_types(colindex))
-            else:
-                label = translate(self.req, attr)
             labels.append(label)
         return labels
 
--- a/vregistry.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/vregistry.py	Wed Jul 01 11:33:40 2009 +0200
@@ -245,6 +245,9 @@
                          removed_id, obj.id, registryname)
 
     def register_and_replace(self, obj, replaced, registryname=None):
+        # XXXFIXME this is a duplication of unregister()
+        # remove register_and_replace in favor of unregister + register
+        # or simplify by calling unregister then register here
         if hasattr(replaced, 'classid'):
             replaced = replaced.classid()
         registryname = registryname or obj.__registry__
--- a/web/box.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/box.py	Wed Jul 01 11:33:40 2009 +0200
@@ -6,6 +6,7 @@
 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
 __docformat__ = "restructuredtext en"
+_ = unicode
 
 from logilab.mtconverter import html_escape
 
@@ -20,8 +21,6 @@
                                       RawBoxItem, BoxSeparator)
 from cubicweb.web.action import UnregisteredAction
 
-_ = unicode
-
 
 class BoxTemplate(View):
     """base template for boxes, usually a (contextual) list of possible
--- a/web/controller.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/controller.py	Wed Jul 01 11:33:40 2009 +0200
@@ -182,6 +182,12 @@
         elif '__redirectpath' in self.req.form:
             # if redirect path was explicitly specified in the form, use it
             path = self.req.form['__redirectpath']
+            if self._edited_entity:
+                msg = newparams.get('__message', '')
+                msg += ' (<a href="%s">%s</a>)' % (
+                    self._edited_entity.absolute_url(),
+                    self.req._('click here to see created entity'))
+                newparams['__createdpath'] = self._edited_entity.rest_path()
         elif self._after_deletion_path:
             # else it should have been set during form processing
             path, params = self._after_deletion_path
--- a/web/data/cubicweb.preferences.js	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/data/cubicweb.preferences.js	Wed Jul 01 11:33:40 2009 +0200
@@ -114,36 +114,37 @@
 
 function setCurrentValues(form){
     jQuery(form).find('[name^=value]').each(function () {
-	    var input = jQuery(this);
-	    var name = input.attr('name');
-	    if(input.attr('type') == 'radio'){
-		// NOTE: there seems to be a bug with jQuery(input).attr('checked')
-		//       in our case, we can't rely on its value, we use
-		//       the DOM API instead.
-		if(input[0].checked){
-		    prefsValues[name] = input.val();
-		}
-	    }else{
+	var input = jQuery(this);
+	var name = input.attr('name');
+	if(input.attr('type') == 'radio'){
+	    // NOTE: there seems to be a bug with jQuery(input).attr('checked')
+	    //       in our case, we can't rely on its value, we use
+	    //       the DOM API instead.
+	    if(input[0].checked){
 		prefsValues[name] = input.val();
 	    }
-	    jQuery('[name=edits-'+ name + ']').val(prefsValues[name]);
-	});
+	}else{
+	    prefsValues[name] = input.val();
+	}
+	jQuery(form).find('input[name=edits-'+ name + ']').val(prefsValues[name]);
+    });
 }
 
 function initEvents(){
-  jQuery('form').each(function() {
-	  var form = jQuery(this);
-	  freezeFormButtons(form.attr('id'));
-	  form.find('input[type=text]').keyup(function(){
-		  checkValues(form);
-          });
-	  form.find('input[type=radio]').change(function(){
-		  checkValues(form);
-          });
-	  form.find('select').change(function(){
-		  checkValues(form);
-          });
-	  setCurrentValues(form);
+    jQuery('form').each(function() {
+	var form = jQuery(this);
+	//freezeFormButtons(form.attr('id'));
+	form.find('input.validateButton').attr('disabled', 'disabled');
+	form.find('input[type=text]').keyup(function(){
+	    checkValues(form);
+	});
+	form.find('input[type=radio]').change(function(){
+	    checkValues(form);
+	});
+	form.find('select').change(function(){
+	    checkValues(form);
+	});
+	setCurrentValues(form);
     });
 }
 
--- a/web/formfields.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/formfields.py	Wed Jul 01 11:33:40 2009 +0200
@@ -164,7 +164,12 @@
         widgets which desire it."""
         if self.choices is not None:
             if callable(self.choices):
-                vocab = self.choices(req=form.req)
+                try:
+                    vocab = self.choices(form=form)
+                except TypeError:
+                    warn('vocabulary method (eg field.choices) should now take '
+                         'the form instance as argument', DeprecationWarning)
+                    vocab = self.choices(req=form.req)
             else:
                 vocab = self.choices
             if vocab and not isinstance(vocab[0], (list, tuple)):
--- a/web/request.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/request.py	Wed Jul 01 11:33:40 2009 +0200
@@ -150,6 +150,11 @@
                 del self.form[k]
             else:
                 self.form[k] = v
+        # special key for created entity, added in controller's reset method
+        if '__createdpath' in params:
+            self.message += ' (<a href="%s">%s</a>)' % (
+                self.build_url(params.pop('__createdpath')),
+                self._('click here to see created entity'))
 
     def no_script_form_param(self, param, default=None, value=None):
         """ensure there is no script in a user form param
--- a/web/test/unittest_form.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/test/unittest_form.py	Wed Jul 01 11:33:40 2009 +0200
@@ -5,6 +5,7 @@
 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
+from __future__ import with_statement
 
 from xml.etree.ElementTree import fromstring
 
@@ -98,6 +99,14 @@
         inputs = pageinfo.find_tag('input', False)
         self.failIf(any(attrs for t, attrs in inputs if attrs.get('name') == '__linkto'))
 
+    def test_reledit_composite_field(self):
+        rset = self.execute('INSERT BlogEntry X: X title "cubicweb.org", X content "hop"')
+        form = self.vreg.select_object('views', 'reledit', self.request(),
+                                       rset=rset, row=0, rtype='content')
+        data = form.render(row=0, rtype='content')
+        self.failUnless('edits-content' in data)
+        self.failUnless('edits-content_format' in data)
+
     # form view tests #########################################################
 
     def test_massmailing_formview(self):
@@ -183,7 +192,7 @@
                 return 'ascii'
             def form_field_format(self, field):
                 return 'text/plain'
-        file = self.add_entity('File', name=u"pouet.txt", data_encoding=u'UTF-8', 
+        file = self.add_entity('File', name=u"pouet.txt", data_encoding=u'UTF-8',
                                data=Binary('new widgets system'))
         form = EFFForm(self.req, redirect_path='perdu.com', entity=file)
         self.assertTextEquals(self._render_entity_field('data', form),
--- a/web/test/unittest_views_apacherewrite.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/test/unittest_views_apacherewrite.py	Wed Jul 01 11:33:40 2009 +0200
@@ -12,14 +12,14 @@
 class ApacheURLRewriteTC(TestCase):
 
     def test(self):
-        class MyAppRules(ApacheURLRewrite): 
+        class MyAppRules(ApacheURLRewrite):
             rules = [
                 RewriteCond('logilab\.fr', match='host',
                             rules=[('/(.*)', r'http://www.logilab.fr/\1')],
                             action='redirect'),
                 RewriteCond('(www)\.logilab\.fr', match='host', action='stop'),
                 RewriteCond('/(data|json)/', match='path', action='stop'),
-                RewriteCond('(?P<cat>.*)\.logilab\.fr', match='host', 
+                RewriteCond('(?P<cat>.*)\.logilab\.fr', match='host',
                             rules=[('/(.*)', r'/m_%(cat)s/\1')]),
                 ]
         urlrewriter = MyAppRules()
--- a/web/test/unittest_views_baseviews.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/test/unittest_views_baseviews.py	Wed Jul 01 11:33:40 2009 +0200
@@ -103,9 +103,9 @@
 
     def test_sortvalue_with_display_col(self):
         e, rset, view = self._prepare_entity()
-        rqlstdescr = rset.syntax_tree().get_description()[0] # XXX missing Union support
+        labels = rset.column_labels()
         table = TableWidget(view)
-        table.columns = view.get_columns(rqlstdescr, [1, 2], None, None, None, None, 0)
+        table.columns = view.get_columns(labels, [1, 2], None, None, None, None, 0)
         expected = ['loo"ong blabla'[:10], e.creation_date.strftime('%Y-%m-%d %H:%M')]
         got = [loadjson(value) for _, value in table.itercols(0)]
         self.assertListEqual(got, expected)
--- a/web/uicfg.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/uicfg.py	Wed Jul 01 11:33:40 2009 +0200
@@ -129,6 +129,21 @@
         self._counter += 1
         tag.setdefault('order', self._counter)
 
+    def tag_subject_of(self, key, tag):
+        subj, rtype, obj = key
+        if obj != '*':
+            self.warning('using explict target type in display_ctrl.tag_subject_of() '
+                         'has no effect, use (%s, %s, "*") instead of (%s, %s, %s)',
+                         subj, rtype, subj, rtype, obj)
+        super(DisplayCtrlRelationTags, self).tag_subject_of((subj, rtype, '*'), tag)
+
+    def tag_object_of(self, key, tag):
+        subj, rtype, obj = key
+        if subj != '*':
+            self.warning('using explict subject type in display_ctrl.tag_object_of() '
+                         'has no effect, use ("*", %s, %s) instead of (%s, %s, %s)',
+                         rtype, obj, subj, rtype, obj)
+        super(DisplayCtrlRelationTags, self).tag_object_of(('*', rtype, obj), tag)
 
 def init_primaryview_display_ctrl(rtag, sschema, rschema, oschema, role):
     if role == 'subject':
--- a/web/views/__init__.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/__init__.py	Wed Jul 01 11:33:40 2009 +0200
@@ -53,9 +53,15 @@
             return True
     return False
 
-VID_BY_MIMETYPE = {'text/xml': 'xml',
-                   # XXX rss, owl...
-                  }
+# FIXME: VID_BY_MIMETYPE is unfortunately a bit too naive since
+#        some browsers (e.g. FF2) send a bunch of mimetypes in
+#        the Accept header, for instance:
+#          text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,
+#          text/plain;q=0.8,image/png,*/*;q=0.5
+VID_BY_MIMETYPE = {
+    #'text/xml': 'xml',
+    # XXX rss, owl...
+}
 def vid_from_rset(req, rset, schema):
     """given a result set, return a view id"""
     if rset is None:
--- a/web/views/actions.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/actions.py	Wed Jul 01 11:33:40 2009 +0200
@@ -40,11 +40,11 @@
         return 0
 
 @objectify_selector
-def match_searched_etype(cls, req, rset, **kwargs):
+def match_searched_etype(cls, req, rset=None, **kwargs):
     return req.match_search_state(rset)
 
 @objectify_selector
-def view_is_not_default_view(cls, req, rset, **kwargs):
+def view_is_not_default_view(cls, req, rset=None, **kwargs):
     # interesting if it propose another view than the current one
     vid = req.form.get('vid')
     if vid and vid != vid_from_rset(req, rset, cls.schema):
@@ -52,7 +52,7 @@
     return 0
 
 @objectify_selector
-def addable_etype_empty_rset(cls, req, rset, **kwargs):
+def addable_etype_empty_rset(cls, req, rset=None, **kwargs):
     if rset is not None and not rset.rowcount:
         rqlst = rset.syntax_tree()
         if len(rqlst.children) > 1:
--- a/web/views/basecomponents.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/basecomponents.py	Wed Jul 01 11:33:40 2009 +0200
@@ -30,7 +30,7 @@
     id = 'rqlinput'
     property_defs = VISIBLE_PROP_DEF
     visible = False
-    
+
     def call(self, view=None):
         if hasattr(view, 'filter_box_context_info'):
             rset = view.filter_box_context_info()[0]
@@ -46,7 +46,7 @@
 <input type="text" id="rql" name="rql" value="%s"  title="%s" tabindex="%s" accesskey="q" class="searchField" />
 <input type="submit" value="" class="rqlsubmit" tabindex="%s" />
 </fieldset>
-''' % (not self.propval('visible') and 'hidden' or '', 
+''' % (not self.propval('visible') and 'hidden' or '',
        self.build_url('view'), html_escape(rql), req._('full text or RQL query'), req.next_tabindex(),
         req.next_tabindex()))
         if self.req.search_state[0] != 'normal':
--- a/web/views/cwproperties.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/cwproperties.py	Wed Jul 01 11:33:40 2009 +0200
@@ -14,7 +14,7 @@
 
 from cubicweb import UnknownProperty
 from cubicweb.selectors import (one_line_rset, none_rset, implements,
-                                match_user_groups)
+                                match_user_groups, objectify_selector)
 from cubicweb.view import StartupView
 from cubicweb.web import uicfg, stdmsgs
 from cubicweb.web.form import FormViewMixIn
@@ -218,8 +218,10 @@
         subform.form_add_hidden('pkey', key, eidparam=True)
         form.form_add_subform(subform)
         return subform
-    
-def is_user_prefs(cls, req, rset, row=None, col=0, **kwargs):
+
+
+@objectify_selector
+def is_user_prefs(cls, req, rset=None, row=None, col=0, **kwargs):
     return req.user.eid == rset[row or 0][col]
 
 
@@ -228,7 +230,7 @@
     __select__ = (
         # we don't want guests to be able to come here
         match_user_groups('users', 'managers') &
-        (none_rset() | ((one_line_rset() & is_user_prefs) &
+        (none_rset() | ((one_line_rset() & is_user_prefs()) &
                         (one_line_rset() & match_user_groups('managers'))))
         )
 
--- a/web/views/editviews.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/editviews.py	Wed Jul 01 11:33:40 2009 +0200
@@ -6,6 +6,7 @@
 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
 """
 __docformat__ = "restructuredtext en"
+_ = unicode
 
 from simplejson import dumps
 
@@ -21,7 +22,6 @@
 from cubicweb.web.views.editforms import relation_id
 from cubicweb.web.views.baseviews import FinalView
 
-_ = unicode
 
 class SearchForAssociationView(EntityView):
     """view called by the edition view when the user asks to search for
--- a/web/views/emailaddress.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/emailaddress.py	Wed Jul 01 11:33:40 2009 +0200
@@ -99,18 +99,17 @@
         if entity.reverse_primary_email:
             self.w(u'<b>')
         if entity.alias:
-            mailto = u'%s <%s>' % (entity.alias, entity.display_address())
+            alias = entity.alias
         elif entity.reverse_use_email:
-            mailto = "mailto:%s <%s>" % \
-                (entity.reverse_use_email[0].dc_title(),
-                 entity.display_address())
+            alias = entity.reverse_use_email[0].dc_title()
+        else:
+            alias = None
+        if alias:
+            mailto = "mailto:%s <%s>" % (alias, entity.display_address())
         else:
             mailto = "mailto:%s" % entity.display_address()
         self.w(u'<a href="%s">%s</a>' % (html_escape(mailto),
                                          html_escape(entity.display_address())))
-
-        if entity.alias:
-            self.w(u'&gt;\n')
         if entity.reverse_primary_email:
             self.w(u'</b>')
 
--- a/web/views/facets.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/facets.py	Wed Jul 01 11:33:40 2009 +0200
@@ -19,7 +19,7 @@
                                 prepare_facets_rqlst, filter_hiddens)
 
 @objectify_selector
-def contextview_selector(cls, req, rset, row=None, col=None, view=None,
+def contextview_selector(cls, req, rset=None, row=None, col=None, view=None,
                          **kwargs):
     if view and getattr(view, 'filter_box_context_info', lambda: None)():
         return 1
--- a/web/views/formrenderers.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/formrenderers.py	Wed Jul 01 11:33:40 2009 +0200
@@ -215,12 +215,29 @@
 
 
 class BaseFormRenderer(FormRenderer):
-    """use form_renderer_id = 'base' if you want base FormRenderer without
-    adaptation by selection
+    """use form_renderer_id = 'base' if you want base FormRenderer layout even
+    when selected for an entity
     """
     id = 'base'
 
 
+class EntityBaseFormRenderer(BaseFormRenderer):
+    """use form_renderer_id = 'base' if you want base FormRenderer layout even
+    when selected for an entity
+    """
+    __select__ = entity_implements('Any')
+
+    def display_field(self, form, field):
+        if not super(EntityBaseFormRenderer, self).display_field(form, field):
+            if isinstance(field, HiddenInitialValueField):
+                field = field.visible_field
+            ismeta = form.edited_entity.e_schema.is_metadata(field.name)
+            return ismeta is not None and (
+                ismeta[0] in self.display_fields or
+                (ismeta[0], 'subject') in self.display_fields)
+        return True
+
+
 class HTableFormRenderer(FormRenderer):
     """display fields horizontally in a table
 
@@ -310,9 +327,11 @@
         w(u'</tr>')
 
 
-class EntityFormRenderer(FormRenderer):
+class EntityFormRenderer(EntityBaseFormRenderer):
     """specific renderer for entity edition form (edition)"""
-    __select__ = entity_implements('Any') & yes()
+    id = 'default'
+    # needs some additional points in some case (XXX explain cases)
+    __select__ = EntityBaseFormRenderer.__select__ & yes()
 
     _options = FormRenderer._options + ('display_relations_form',)
     display_relations_form = True
--- a/web/views/plots.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/plots.py	Wed Jul 01 11:33:40 2009 +0200
@@ -20,13 +20,13 @@
 from cubicweb.web.views import baseviews
 
 @objectify_selector
-def at_least_two_columns(cls, req, rset, *args, **kwargs):
+def at_least_two_columns(cls, req, rset=None, *args, **kwargs):
     if not rset:
         return 0
     return len(rset.rows[0]) >= 2
 
 @objectify_selector
-def all_columns_are_numbers(cls, req, rset, *args, **kwargs):
+def all_columns_are_numbers(cls, req, rset=None, *args, **kwargs):
     """accept result set with at least one line and two columns of result
     all columns after second must be of numerical types"""
     for etype in rset.description[0]:
@@ -35,14 +35,14 @@
     return 1
 
 @objectify_selector
-def second_column_is_number(cls, req, rset, *args, **kwargs):
+def second_column_is_number(cls, req, rset=None, *args, **kwargs):
     etype = rset.description[0][1]
     if etype not  in ('Int', 'Float'):
         return 0
     return 1
 
 @objectify_selector
-def columns_are_date_then_numbers(cls, req, rset, *args, **kwargs):
+def columns_are_date_then_numbers(cls, req, rset=None, *args, **kwargs):
     etypes = rset.description[0]
     if etypes[0] not in ('Date', 'Datetime'):
         return 0
--- a/web/views/primary.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/primary.py	Wed Jul 01 11:33:40 2009 +0200
@@ -57,7 +57,9 @@
         self.content_navigation_components('navcontenttop')
         try:
             self.render_entity_attributes(entity)
-        except TypeError: # XXX bw compat
+        except TypeError, e: # XXX bw compat
+            if 'render_entity' not in e.args[0]:
+                raise
             warn('siderelations argument of render_entity_attributes is '
                  'deprecated (%s)' % self.__class__)
             self.render_entity_attributes(entity, [])
@@ -65,7 +67,9 @@
         if self.main_related_section:
             try:
                 self.render_entity_relations(entity)
-            except TypeError: # XXX bw compat
+            except TypeError, e: # XXX bw compat
+                if 'render_entity' not in e.args[0]:
+                    raise
                 warn('siderelations argument of render_entity_relations is '
                      'deprecated')
                 self.render_entity_relations(entity, [])
@@ -115,7 +119,19 @@
 
     def render_entity_attributes(self, entity, siderelations=None):
         for rschema, tschemas, role, dispctrl in self._section_def(entity, 'attributes'):
-            vid =  dispctrl.get('vid', 'reledit')
+            # don't use reledit as default vid for composite relation
+            if rschema.is_final():
+                defaultvid = 'reledit'
+            # XXX use entity.e_schema.role_rproperty(role, rschema, 'composite', tschemas[0]) once yams > 0.23.0 is out
+            elif role == 'subject' and \
+                 rschema.rproperty(entity.e_schema, tschemas[0], 'composite'):
+                defaultvid = 'csv'
+            elif role == 'object' and \
+                 rschema.rproperty(tschemas[0], entity.e_schema, 'composite'):
+                defaultvid = 'csv'
+            else:
+                defaultvid = 'reledit'
+            vid =  dispctrl.get('vid', defaultvid)
             if rschema.is_final() or vid == 'reledit':
                 value = entity.view(vid, rtype=rschema.type, role=role)
             else:
--- a/web/views/schema.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/schema.py	Wed Jul 01 11:33:40 2009 +0200
@@ -64,7 +64,7 @@
     title = _('in memory entity schema')
     main_related_section = False
     skip_rels = SKIPPED_RELS
-    tabs = [_('cwetype-schema-text'), _('cwetype-schema-image'), 
+    tabs = [_('cwetype-schema-text'), _('cwetype-schema-image'),
             _('cwetype-schema-permissions'), _('cwetype-workflow')]
     default_tab = 'cwetype-schema-text'
 
@@ -133,22 +133,22 @@
         entity = self.entity(row, col)
         self.w(u'<h2>%s</h2>' % _('Add permissions'))
         rset = self.req.execute('Any P WHERE X add_permission P, '
-                                'X eid %(x)s', 
+                                'X eid %(x)s',
                                 {'x': entity.eid})
         self.wview('outofcontext', rset, 'null')
         self.w(u'<h2>%s</h2>' % _('Read permissions'))
         rset = self.req.execute('Any P WHERE X read_permission P, '
-                                'X eid %(x)s', 
+                                'X eid %(x)s',
                                 {'x': entity.eid})
         self.wview('outofcontext', rset, 'null')
         self.w(u'<h2>%s</h2>' % _('Update permissions'))
         rset = self.req.execute('Any P WHERE X update_permission P, '
-                                'X eid %(x)s', 
+                                'X eid %(x)s',
                                 {'x': entity.eid})
         self.wview('outofcontext', rset, 'null')
         self.w(u'<h2>%s</h2>' % _('Delete permissions'))
         rset = self.req.execute('Any P WHERE X delete_permission P, '
-                                'X eid %(x)s', 
+                                'X eid %(x)s',
                                 {'x': entity.eid})
         self.wview('outofcontext', rset, 'null')
 
--- a/web/views/startup.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/startup.py	Wed Jul 01 11:33:40 2009 +0200
@@ -177,6 +177,7 @@
         self.w(u'<h1>%s</h1>' % _('Schema of the data model'))
         self.render_tabs(self.tabs, self.default_tab)
 
+
 class SchemaTabImageView(StartupView):
     id = 'schema-image'
 
@@ -189,6 +190,7 @@
             html_escape(self.req.build_url('view', vid='schemagraph', withmeta=0)),
             self.req._("graphical representation of the application'schema")))
 
+
 class SchemaTabTextView(StartupView):
     id = 'schema-text'
 
@@ -205,11 +207,12 @@
 
 
 class ManagerSchemaPermissionsView(StartupView, SecurityViewMixIn):
-    id = 'schema_security'
+    id = 'schema-security'
     __select__ = StartupView.__select__ & match_user_groups('managers')
 
     def call(self, display_relations=True,
              skiprels=('is', 'is_instance_of', 'identity', 'owned_by', 'created_by')):
+        self.req.add_css('cubicweb.acl.css')
         _ = self.req._
         formparams = {}
         formparams['sec'] = self.id
@@ -222,28 +225,31 @@
             entities = [eschema for eschema in entities
                         if not eschema.meta]
         # compute relations
-        relations = []
         if display_relations:
             relations = [rschema for rschema in schema.relations()
                          if not (rschema.is_final() or rschema.type in skiprels)]
             if not formparams['withmeta']:
                 relations = [rschema for rschema in relations
                              if not rschema.meta]
+        else:
+            relations = []
         # index
         self.w(u'<div id="schema_security"><a id="index" href="index"/>')
         self.w(u'<h2 class="schema">%s</h2>' % _('index').capitalize())
         self.w(u'<h4>%s</h4>' %   _('Entities').capitalize())
         ents = []
         for eschema in sorted(entities):
-            url = html_escape(self.build_url('schema', **formparams) + '#' + eschema.type)
-            ents.append(u'<a class="grey" href="%s">%s</a> (%s)' % (url,  eschema.type, _(eschema.type)))
-        self.w('%s' %  ', '.join(ents))
+            url = html_escape(self.build_url('schema', **formparams))
+            ents.append(u'<a class="grey" href="%s#%s">%s</a> (%s)' % (
+                url,  eschema.type, eschema.type, _(eschema.type)))
+        self.w(u', '.join(ents))
         self.w(u'<h4>%s</h4>' % (_('relations').capitalize()))
         rels = []
-        for eschema in sorted(relations):
-            url = html_escape(self.build_url('schema', **formparams) + '#' + eschema.type)
-            rels.append(u'<a class="grey" href="%s">%s</a> (%s), ' %  (url , eschema.type, _(eschema.type)))
-        self.w('%s' %  ', '.join(ents))
+        for rschema in sorted(relations):
+            url = html_escape(self.build_url('schema', **formparams))
+            rels.append(u'<a class="grey" href="%s#%s">%s</a> (%s), ' %  (
+                url , rschema.type, rschema.type, _(rschema.type)))
+        self.w(u', '.join(ents))
         # entities
         self.display_entities(entities, formparams)
         # relations
--- a/web/views/tableview.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/tableview.py	Wed Jul 01 11:33:40 2009 +0200
@@ -105,11 +105,10 @@
         req = self.req
         req.add_js('jquery.tablesorter.js')
         req.add_css(('cubicweb.tablesorter.css', 'cubicweb.tableview.css'))
-        rqlst = rset.syntax_tree()
         # get rql description first since the filter form may remove some
         # necessary information
-        rqlstdescr = rqlst.get_description()[0] # XXX missing Union support
         mainindex = self.main_var_index()
+        computed_labels = self.columns_labels(mainindex)
         hidden = True
         if not subvid and 'subvid' in req.form:
             subvid = req.form.pop('subvid')
@@ -154,8 +153,8 @@
             self.render_actions(divid, actions)
         # render table
         table = TableWidget(self)
-        for column in self.get_columns(rqlstdescr, displaycols, headers, subvid,
-                                       cellvids, cellattrs, mainindex):
+        for column in self.get_columns(computed_labels, displaycols, headers,
+                                       subvid, cellvids, cellattrs, mainindex):
             table.append_column(column)
         table.render(self.w)
         self.w(u'</div>\n')
@@ -188,20 +187,15 @@
         box.render(w=self.w)
         self.w(u'<div class="clear"/>')
 
-    def get_columns(self, rqlstdescr, displaycols, headers, subvid, cellvids,
-                    cellattrs, mainindex):
+    def get_columns(self, computed_labels, displaycols, headers, subvid,
+                    cellvids, cellattrs, mainindex):
         columns = []
-        for colindex, attr in enumerate(rqlstdescr):
+        for colindex, label in enumerate(computed_labels):
             if colindex not in displaycols:
                 continue
             # compute column header
             if headers is not None:
                 label = headers[displaycols.index(colindex)]
-            elif colindex == 0 or attr == 'Any': # find a better label
-                label = ','.join(display_name(self.req, et)
-                                 for et in self.rset.column_types(colindex))
-            else:
-                label = display_name(self.req, attr)
             if colindex == mainindex:
                 label += ' (%s)' % self.rset.rowcount
             column = TableColumn(label, colindex)
@@ -214,7 +208,6 @@
                 column.append_renderer(self.finalview, colindex)
             else:
                 column.append_renderer(subvid or 'incontext', colindex)
-
             if cellattrs and colindex in cellattrs:
                 for name, value in cellattrs[colindex].iteritems():
                     column.add_attr(name, value)
--- a/web/views/xmlrss.py	Wed Jul 01 11:33:18 2009 +0200
+++ b/web/views/xmlrss.py	Wed Jul 01 11:33:40 2009 +0200
@@ -79,7 +79,7 @@
         w = self.w
         rset, descr = self.rset, self.rset.description
         eschema = self.schema.eschema
-        labels = self.columns_labels(False)
+        labels = self.columns_labels(tr=False)
         w(u'<?xml version="1.0" encoding="%s"?>\n' % self.req.encoding)
         w(u'<%s query="%s">\n' % (self.xml_root, xml_escape(rset.printable_rql())))
         for rowindex, row in enumerate(self.rset):