merge
authorLaure Bourgois <Laure.Bourgois@logilab.fr>
Fri, 21 Nov 2008 17:37:27 +0100
changeset 126 80c65c9f7c41
parent 125 979dbe0cade3 (current diff)
parent 124 451061423290 (diff)
child 127 ae611743f5c6
child 142 0425ee84cfa6
merge
doc/book/en/01-intro.en.txt
doc/book/en/01-introduction.en.txt
doc/book/en/02-foundation.en.txt
doc/book/en/02-install.en.txt
doc/book/en/03-create-app.en.txt
doc/book/en/03-definition-schema.en.txt
doc/book/en/03-sect-definition-schema.en.txt
doc/book/en/03-sect-stdlib-schemas.en.txt
doc/book/en/03-setup.en.txt
doc/book/en/04-define-schema.en.txt
doc/book/en/04-develop-views.en.txt
doc/book/en/05-components.en.txt
doc/book/en/05-define-views.en.txt
doc/book/en/06-define-workflows.en.txt
doc/book/en/06-maintemplate.en.txt
doc/book/en/07-data-as-objects.en.txt
doc/book/en/07-rss-xml.en.txt
doc/book/en/08-rql.en.txt
doc/book/en/08-site-config.en.txt
doc/book/en/09-instance-config.en.txt
doc/book/en/09-urlrewrite.en.txt
doc/book/en/10-form-management.en.txt
doc/book/en/10-security.en.txt
doc/book/en/11-ajax-json.en.txt
doc/book/en/11-definition-workflow.en.txt
doc/book/en/11-faq.en.txt
doc/book/en/12-internationalization.en.txt
doc/book/en/12-reference.en.txt
doc/book/en/12-ui-components.en.txt
doc/book/en/13-security.en.txt
doc/book/en/14-hooks.en.txt
doc/book/en/15-notifications.en.txt
doc/book/en/16-rql.en.txt
doc/book/en/17-migration.en.txt
doc/book/en/18-tests.en.txt
doc/book/en/19-i18n.en.txt
doc/book/en/20-gae.en.txt
doc/book/en/21-02-querier.en.txt
doc/book/en/21-appendix.en.txt
doc/book/en/22-faq.en.txt
doc/book/fr/01-intro.fr.txt
doc/book/fr/02-install.fr.txt
doc/book/fr/03-create-app.fr.txt
doc/book/fr/04-develop-views.fr.txt
doc/book/fr/05-components.fr.txt
doc/book/fr/06-maintemplate.fr.txt
doc/book/fr/07-rss-xml.fr.txt
doc/book/fr/08-rql.fr.txt
doc/book/fr/09-urlrewrite.fr.txt
doc/book/fr/10-security.fr.txt
doc/book/fr/20-gae.fr.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-00-introduction.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,24 @@
+.. -*- coding: utf-8 -*-
+
+.. _Overview:
+
+Quick overview of `CubicWeb`
+============================
+
+`CubicWeb` allows us to develop web applications instances based on
+one or more `cubes`.
+
+What we call a `cube` is a model defining the data types and views. 
+A `cube` is a reusable component grouped with others cubes in the file
+system.
+
+An `instance` refers to a specific installation of one or more `cubes`
+ where are grouped configuration files of the final web application.
+
+In this document, we will show you how to create a `cube` and how to use it
+in an `instance` for your web application.
+
+.. include:: 01-01-create-cube.en.txt
+.. include:: 01-05-components.en.txt
+.. include:: 01-06-maintemplate.en.txt
+.. include:: 01-07-rss-xml.en.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-01-create-cube.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,314 @@
+.. -*- coding: utf-8 -*-
+
+Create your cube
+----------------
+
+After you installed your `CubicWeb` development environment, you can start
+to build your first cube: ::
+
+  cubicweb-ctl newcube blog
+
+This will create in ``/path/to/forest/cubes`` a directory containing: ::
+
+  blog/
+  |
+  |-- data/
+  |   |-- cubes.blog.css
+  |   |-- cubes.blog.js  
+  |   |-- external_resources
+  |
+  |-- debian/
+  |   |-- changelog
+  |   |-- compat
+  |   |-- control
+  |   |-- copyright
+  |   |-- cubicweb-blog.prerm
+  |   |-- rules
+  |
+  |-- entities.py
+  |
+  |-- i18n/
+  |   |-- en.po
+  |   |-- fr.po
+  |
+  |-- __init__.py
+  |
+  |-- MANIFEST.in
+  |
+  |-- migration/
+  |   |-- postcreate.py
+  |   |-- precreate.py
+  |
+  |-- __pkginfo__.py
+  |
+  |-- schema.py
+  |
+  |-- setup.py
+  |
+  |-- site_cubicweb.py
+  |
+  |-- sobjects.py
+  |
+  |-- test/
+  |   |-- data/
+  |       |-- bootstrap_cubes
+  |   |-- pytestconf.py
+  |   |-- realdb_test_blog.py
+  |   |-- test_blog.py
+  |
+  |-- views.py
+
+Any changes applied to your data model should be done in this
+directory.
+
+
+Define your data schema
+-----------------------
+
+The data model or schema is hte core of your `CubicWeb` application.
+This is where is defined the type of content you application will handle.
+
+The data model is defined in the file ``schema.py`` of your cube
+``blog`` such as follows.
+
+::
+
+  from cubicweb.schema import format_constraint
+  class Blog(EntityType):
+    title = String(maxsize=50, required=True)
+    description = String()
+
+  class BlogEntry(EntityType):
+    title = String(required=True, fulltextindexed=True, maxsize=256)
+    publish_date = Date(default='TODAY')
+    content = String(required=True, fulltextindexed=True)
+    entry_of = SubjectRelation('Blog', cardinality='?*') 
+
+
+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. 
+The description is a string that is not constrained.
+
+A BlogEntry has a title, a publish_date and a content. The title is a
+string that is required and must be less than 100 characters. The
+publish_date is a Date with a default value of TODAY, meaning that
+when a BlogEntry is created, its publish_date will be the current day
+unless it is modified. The content is a string that will be indexed in
+the full-text index and has no constraint.
+
+A BlogEntry also has a relationship ``entry_of`` that links it to a
+Blog. The cardinality ``?*`` means that a BlogEntry can be part of
+zero or one Blog (``?`` means `zero or one`) and that a Blog can
+have any number of BlogEntry (``*`` means `any number including
+zero`). For completeness, remember that ``+`` means `one or more`.
+
+
+Create your instance
+--------------------
+
+::
+  
+  cubicweb-ctl create blog blogdemo
+
+
+This command will create a directory ``~/etc/cubicweb.d/blogdemo``
+which will contain all the configuration files required to start
+you web application.
+
+The instance ``blogdemo`` is based on the cube ``blog``.
+
+
+Welcome in your web application
+-------------------------------
+
+Run your application with the following command: ::
+
+  cubicweb-ctl start -D blogdemo
+
+
+You can now access to your web application to create blogs and post messages
+by visitin the URL http://localhost:8080/.
+A login form will first be prompted. By default, the application will not allow
+anonymous user to get in the application. You should then use the admin
+account you created at the time you initialized the database with
+``cubicweb-ctl create``.
+
+.. image:: images/login-form.png
+
+
+Once authenticated, you can start playing with your application 
+and create entities. Bravo!
+
+.. image:: images/blog-demo-first-page.png
+
+Please notice that so far, `CubicWeb` franework managed all aspects of 
+the web application based in the schema provided at first.
+
+
+Create entities
+---------------
+
+We will now create a couple of entities in our web application.
+
+Create a Blog
+~~~~~~~~~~~~~
+
+Let us create a few of these entities. Click on the `[+]` at the right
+of the link Blog.  Call this new Blog ``Tech-blog`` and type in
+``everything about technology`` as the description, then validate the
+form by clicking on ``Validate``.
+
+.. image:: images/cbw-create-blog.en.png
+   :alt: from to create blog
+
+Click on the logo at top left to get back to the home page, then
+follow the Blog link that will list for you all the existing Blog.
+You should be seeing a list with a single item ``Tech-blog`` you
+just created.
+
+.. image:: images/cbw-list-one-blog.en.png
+   :alt: displaying a list of a single blog
+
+Clicking on this item will get you to its detailed description except
+that in this case, there is not much to display besides the name and
+the phrase ``everything about technology``.
+
+Now get back to the home page by clicking on the top-left logo, then
+create a new Blog called ``MyLife`` and get back to the home page
+again to follow the Blog link for the second time. The list now
+has two items.
+
+.. image:: images/cbw-list-two-blog.en.png
+   :alt: displaying a list of two blogs
+
+Create a BlogEntry
+~~~~~~~~~~~~~~~~~~
+
+Get back to the home page and click on [+] at the right of the link
+BlogEntry. Call this new entry ``Hello World`` and type in some text
+before clicking on ``Validate``. You added a new blog entry without
+saying to what blog it belongs. There is a box on the left entitled
+``actions``, click on the menu item ``modify``. You are back to the form
+to edit the blog entry you just created, except that the form now has
+another section with a combobox titled ``add relation``. Chose
+``entry_of`` in this menu and a second combobox appears where you pick
+``MyLife``. 
+
+You could also have, at the time you started to fill the form for a
+new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the 
+combobox titled ``add relation`` would have showed up.
+
+
+.. image:: images/cbw-add-relation-entryof.en.png
+   :alt: editing a blog entry to add a relation to a blog
+
+Validate the changes by clicking ``Validate``. The entity BlogEntry
+that is displayed now includes a link to the entity Blog named
+``MyLife``.
+
+.. image:: images/cbw-detail-one-blogentry.en.png
+   :alt: displaying the detailed view of a blogentry
+
+Note that all of this was handled by the framework and that the only input
+that was provided so far is the schema. To get a graphical view of the schema,
+point your browser to the URL http://localhost:8080/schema
+
+.. image:: images/cbw-schema.en.png
+   :alt: graphical view of the schema (aka data-model)
+
+
+Define your entities views
+--------------------------
+
+The views selection principle
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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 resulsets it can be applied to
+
+
+`CubicWeb` provides a lot of standard views for the type
+`EntityView`, for a complete list, you
+will have to 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
+mecanism which computes a score used to identify which view
+is the best to apply for the `result set` we are trying to 
+display. 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. We will see more details
+on this in :ref:`DefinitionVues`.
+
+For example, the view named ``primary`` is the one used to display
+a single entity. We will now show you hos to customize this view.
+
+
+View customization
+~~~~~~~~~~~~~~~~~~
+
+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``.
+
+We can by example add in front of the pulication date a prefix specifying
+the date we see is the publication date.
+
+To do so, please apply the following changes:
+
+:: 
+
+  from cubicweb.web.views import baseviews
+
+
+  class BlogEntryPrimaryView(baseviews.PrimaryView):
+
+    accepts = ('BlogEntry',)
+
+    def render_entity_title(self, entity):
+        self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title()))
+
+    def content_format(self, entity):
+        return entity.view('reledit', rtype='content_format')
+
+    def cell_call(self, row, col):
+        entity = self.entity(row, col)
+
+        # display entity attributes with prefixes
+        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:
+            self.render_entity_relations(entity, siderelations)
+
+.. note::
+  When a view is modified, it is not required to restart the application
+  server. Save the Python file and reload the page in your web browser
+  to view the changes.
+
+You can now see that the publication date has a prefix.
+
+.. image:: images/cbw-update-primary-view.en.png
+   :alt: modified primary view
+
+
+The above source code defines a new primary view for
+``BlogEntry``. 
+
+Since views are applied to resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates. We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. In our
+example we use it to output HTML tags and values of the entity's attributes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-05-components.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,150 @@
+.. -*- coding: utf-8 -*-
+
+.. _components:
+
+Components
+----------
+
+What is a component
+~~~~~~~~~~~~~~~~~~~
+
+A component is a model grouping one or more entity types and/or views associated
+in order to provide a specific feature or even a complete application using
+others components.
+You can decide to write your own set of components if you wish to re-use the 
+entity types you develop. By default, LAX comes with its owns set of components
+that you can start using right away.
+
+
+Standard library
+~~~~~~~~~~~~~~~~
+
+A library of standard components is part of the `LAX` release (look at
+``lax/skel/ginco-apps``). Components provide entities and views. With
+``lax-0.4``, you should get a set of application entities and system
+entities you can re-use.
+
+The available application entities are:
+
+* addressbook: PhoneNumber and PostalAddress
+
+* ebasket: Basket (like a shopping cart)
+
+* eblog: Blog (a *very* basic blog)
+
+* eclassfolder: Folder (to organize things but grouping them in folders)
+
+* eclasstags: Tag (to tag anything)
+
+
+* efile: File (to allow users to upload and store binary or text files)
+
+* elink: Link (to collect links to web resources)
+
+* emailinglist: MailingList (to reference a mailing-list and the URLs
+  for its archives and its admin interface)
+
+* eperson: Person (easily mixed with addressbook)
+
+* etask: Task (something to be done between start and stop date)
+
+* ezone: Zone (to define places within larger places, for example a
+  city in a state in a country)
+
+The available system entities are:
+
+* ecomment: Comment (to attach comment threads to entities)
+
+
+
+Adding comments to BlogDemo
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To import a component in your application just change the line in the
+``app.conf`` file. For example::
+
+    included-yams-components=ecomment
+
+will make the ``Comment`` entity available in your ``BlogDemo``
+application.
+
+Change the schema to add a relationship between ``BlogEntry`` and
+``Comment`` and you are done. Since the ecomment component defines the
+``comments`` relationship, adding the line::
+
+    comments = ObjectRelation('Comment', cardinality='1*', composite='object')
+
+to the definition of a ``BlogEntry`` will be enough.
+
+Clear the datastore and restart.
+
+Component structure
+~~~~~~~~~~~~~~~~~~~
+
+A complex component is structured as follows:
+::
+
+  mycomponent/
+  |
+  |-- schema.py
+  |
+  |-- entities/
+  |
+  |-- sobjects/
+  |
+  |-- views/
+  |
+  |-- test/
+  |
+  |-- i18n/
+  |
+  |-- data/
+  |
+  |-- migration/
+  | |- postcreate.py
+  | \- depends.map
+  |
+  |-- debian/
+  |
+  \-- __pkginfo__.py
+
+We can also define simple Python module instead of directories (packages), for example:
+::
+
+  mycomponent/
+  |
+  |-- entities.py
+  |-- hooks.py
+  \-- views.py
+
+
+where:
+
+* ``schema`` contains the definition of the schema (server side only)
+* ``entities`` contains entities definition (server side and web interface)
+* ``sobjects`` contains hooks and/or notification views (server side only)
+* ``views`` contains the web interface components (web interface only)
+* ``test`` contains tests related to the application (not installed)
+* ``i18n`` contains messages catalogs for supported languages (server side and
+  web interface)
+* ``data`` contains data files for static content (images, css, javascripts)
+  ...(web interface only)
+* ``migration`` contains initialization file for new instances (``postcreate.py``)
+  and a file containing dependencies of the component depending on the version
+  (``depends.map``)
+* ``debian`` contains all the files managing debian packaging (you will find
+  the usual files ``control``, ``rules``, ``changelog``... not installed)
+* file ``__pkginfo__.py`` provides component meta-data, especially the distribution
+  and the current version(server side and web interface) or sub-components used by
+  the component.
+ 
+At least you should have:
+
+* the file ``__pkginfo__.py``
+* schema definition
+
+[WRITE ME]
+
+* explain the component architecture
+
+* add comments to the blog by importing the comments component
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-06-maintemplate.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,209 @@
+.. -*- coding: utf-8 -*-
+
+Views & Templates
+-----------------
+
+Look at ``lax/skel/ginco/web/views/basetemplates.py`` and you will
+find the base templates used to generate HTML for your application.
+
+A page is composed as indicated on the schema below:
+
+.. image:: images/lax-book.06-main-template-layout.en.png
+
+In this section we will go through a couple of the primary templates
+you must be interested in, that is to say, the HTMLPageHeader,
+the HTMLPageFooter and the TheMainTemplate.
+
+
+HTMLPageHeader
+~~~~~~~~~~~~~~~
+
+Let's use a different logo than the default one provided with LAX
+and customize our header.
+
+Change logo
+```````````
+
+The easiest way to use a different logo is to replace the existing
+``logo.png`` in ``myapp/data`` by your prefered icon and refresh.
+By default all application will look for a ``logo.png`` to be 
+rendered in the logo section.
+
+.. image:: images/lax-book.06-main-template-logo.en.png
+
+[ADD]
+customized external_resources in myapp/data cd crih for reference
+
+[WRITE ME]
+ADD how to use external_resources variables used in ginco/web/webconfig.py
+
+Customize header
+`````````````````
+
+Let's now move the search box in the header and remove the login form
+from the header. We'll show how to move it to the left column of the application.
+
+Let's sat we do not want anymore the login menu to be in the header, but we 
+prefer it to be in the left column just below the logo. As the left column is
+rendered by ``TheMainTemplate``, we will show how to do it in TheMainTemplate_. 
+
+First, to remove the login menu, we just need to comment out the display of the
+login component such as follows: ::
+
+  class MyHTMLPageHeader(HTMLPageHeader):
+    
+      def main_header(self, view):
+          """build the top menu with authentification info and the rql box"""
+          self.w(u'<table id="header"><tr>\n')
+          self.w(u'<td id="firstcolumn">')
+          self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+          self.w(u'</td>\n')
+          # appliname and breadcrumbs
+          self.w(u'<td id="headtext">')
+          comp = self.vreg.select_component('appliname', self.req, self.rset)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w)
+          comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w, view=view)
+          self.w(u'</td>')
+          # logged user and help
+          #self.w(u'<td>\n')
+          #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
+          #comp.dispatch(w=self.w)
+          #self.w(u'</td><td>')
+
+          self.w(u'<td>')
+          helpcomp = self.vreg.select_component('help', self.req, self.rset)
+          if helpcomp: # may not be available if Card is not defined in the schema
+              helpcomp.dispatch(w=self.w)
+          self.w(u'</td>')
+          # lastcolumn
+          self.w(u'<td id="lastcolumn">')
+          self.w(u'</td>\n')
+          self.w(u'</tr></table>\n')
+          self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden',
+                        title=False, message=False)
+
+
+
+.. image:: images/lax-book.06-header-no-login.en.png
+
+Let's now move the search box in the top-right header area. To do so, we will
+first create a method to get the search box display and insert it in the header
+table.
+
+::
+
+ from ginco.web.views.basetemplates import HTMLPageHeader
+ class MyHTMLPageHeader(HTMLPageHeader):
+    def main_header(self, view):
+        """build the top menu with authentification info and the rql box"""
+        self.w(u'<table id="header"><tr>\n')
+        self.w(u'<td id="firstcolumn">')
+        self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+        self.w(u'</td>\n')
+        # appliname and breadcrumbs
+        self.w(u'<td id="headtext">')
+        comp = self.vreg.select_component('appliname', self.req, self.rset)
+        if comp and comp.propval('visible'):
+            comp.dispatch(w=self.w)
+        comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
+        if comp and comp.propval('visible'):
+            comp.dispatch(w=self.w, view=view)
+        self.w(u'</td>')
+        
+        # logged user and help
+        #self.w(u'<td>\n')
+        #comp = self.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')
+        self.w(u'</td>')
+
+        self.w(u'<td>')
+        helpcomp = self.vreg.select_component('help', self.req, self.rset)
+        if helpcomp: # may not be available if Card is not defined in the schema
+            helpcomp.dispatch(w=self.w)
+        self.w(u'</td>')
+        # lastcolumn
+        self.w(u'<td id="lastcolumn">')
+        self.w(u'</td>\n')
+        self.w(u'</tr></table>\n')
+        self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden',
+                      title=False, message=False)
+
+    def get_searchbox(self, view, context):
+        boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset,
+                                                 view=view, context=context))
+        if boxes:
+            for box in boxes:
+                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: 
+::
+
+  form ginco.web.views.basetemplates import HTMLPageFooter
+  class MyHTMLPageFooter(HTMLPageFooter):
+      def call(self, **kwargs):
+          self.w(u'<div class="footer">')
+          self.w(u'This website has been created with <a href="http://lax.logilab.org">LAX</a>.')
+          self.w(u'</div>')
+
+Updating a view does not require any restart of the server. By reloading
+the page you can see your new page footer.
+
+
+TheMainTemplate
+~~~~~~~~~~~~~~~
+
+.. _TheMainTemplate:
+
+The MainTemplate is a bit complex as it tries to accomodate many
+different cases. We are now about to go through it and cutomize entirely
+our application.
+
+TheMainTemplate is responsible for the general layout of the entire application. 
+It defines the template of ``id = main`` that is used by the application. Is 
+also defined in ``ginco/web/views/basetemplates.py`` another template that can
+be used based on TheMainTemplate called SimpleMainTemplate which does not have 
+a top section.
+
+.. image:: images/lax-book.06-simple-main-template.en.png
+
+CSS changes
+~~~~~~~~~~~
+
+We cannot modify the order in which the application is reading the CSS. In
+the case we want to create new CSS style, the best is to define it a in a new
+CSS located under ``myapp/data/``.
+
+If you want to modify an existing CSS styling property, you will have to use
+``!important`` declaration to override the existing property. The application
+apply a higher priority on the default CSS and you can not change that. 
+Customized CSS will not be read first.
+
+[TODO]
+Add login menu in left column
+
+
+[WRITE ME]
+
+* customize MainTemplate and show that everything in the user
+  interface can be changed
+
+[TODO]
+Rajouter une section pour definir la terminologie utilisee.
+Dans ginco-doc rajouter une section pour erudi-ctl shell ou
+on liste les commandes dispos.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-07-rss-xml.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,45 @@
+.. -*- coding: utf-8 -*-
+
+RSS Channel
+-----------
+
+Assuming you have several blog entries, click on the title of the
+search box in the left column. A larger search box should appear. Enter::
+
+   Any X ORDERBY D WHERE X is BlogEntry, X creation_date D
+
+and you get a list of blog entries.
+
+Click on your login at the top right corner. Chose "user preferences",
+then "boxes", then "possible views box" and check "visible = yes"
+before validating your changes.
+
+Enter the same query in the search box and you will see the same list,
+plus a box titled "possible views" in the left column. Click on
+"entityview", then "RSS". 
+
+You just applied the "RSS" view to the RQL selection you requested.
+
+That's it, you have a RSS channel for your blog.
+
+Try again with::
+
+    Any X ORDERBY D WHERE X is BlogEntry, X creation_date D, 
+    X entry_of B, B title "MyLife"
+
+Another RSS channel, but a bit more focused.
+
+A last one for the road::
+
+    Any C ORDERBY D WHERE C is Comment, C creation_date D LIMIT 15
+    
+displayed with the RSS view, that's a channel for the last fifteen
+comments posted.
+
+[WRITE ME]
+
+* show that the RSS view can be used to display an ordered selection
+  of blog entries, thus providing a RSS channel
+
+* show that a different selection (by category) means a different channel
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-08-book-map.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,10 @@
+.. -*- coding: utf-8 -*-
+
+Book map
+=========
+
+[WRITE ME]
+
+* explain how to use this book and what chapters to read in what order depending on the
+  objectives of the reader
+
--- a/doc/book/en/01-intro.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Introduction
-============
-
-This book uses version 0.4.0 of `LAX`.
-
-What is  `LAX` ?
-----------------
-
-`LAX` stands for `Logilab Appengine eXtension`. It is a web application framework 
-based on `Google AppEngine`.
-
-`LAX` is a port of the web framework Logilab_ has been developping since 2001.
-This framework originally published data queried from different sources including
-SQL databases, LDAP directories and concurrent versionning systems
-(like subversion). In April/May 2008, it was adapted to run also on
-top of `Google AppEngine`'s datastore.
-
-`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]_. 
-
-`LAX` competes with other Python web application frameworks to get
-developers' attention and support. It originates from Logilab and is
-the result of about ten years of experience in developing large-scale
-web applications.
-
-Distinctive features include a data-model driven engine, a full-blown
-query language, a selection/view mechanism for HTML/XML/text
-generation, reuseable components, etc. It all sums up to very fast and
-efficient development.
-
-If you like Python and its standard library, chances are you will like
-`LAX` for it comes with batteries included thanks to its standard
-component library.
-
-Compare `LAX` with other frameworks and see for yourself what is your
-best option.
-
-.. _Logilab: http://www.logilab.fr/
-.. [1] for more on this matter, read our blog at http://www.logilab.org/blog/5216
-
-Essentials
-----------
-
-Schema
-
-  The schema defines the data model of an application as entities and
-  relationships. It is the core of an application.  Entities and
-  relationships are modeled with a comprehensive language made of
-  Python classes. 
-
-Query language
-
-  A full-blown query language named RQL is used to formulate 
-  requests to the datastore.
-
-Result set
-
-  A resultset encapsulates the results of a request sent to
-  the datastore and informations about this request.  
-
-Views 
-
-  A view is applied to a `result set` to present it as HTML, XML,
-  JSON, CSV, etc. Views are implemented as Python classes. There is no
-  templating language.
-
-Generated user interface
-
-  A user interface is generated on-the-fly from the schema definition:
-  entities can be created, displayed, updated and deleted. As display
-  views are not very fancy, it is usually necessary to develop your
-  own. Any generated view can be overridden by defining a new one with
-  the same identifier.
-
-Components
-
-  Pieces of schema and sets of views can be combined into
-  components. Larger applications can be built faster by importing
-  components, adding entities and relationships and overriding the
-  views that need to display or edit informations not provided by
-  components.
--- a/doc/book/en/01-introduction.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Overview:
-
-Quick overview of `CubicWeb`
-============================
-
-`CubicWeb` allows us to develop web applications instances based on
-one or more `cubes`.
-
-What we call a `cube` is a model defining the data types and views. 
-A `cube` is a reusable component grouped with others cubes in the file
-system.
-
-An `instance` refers to a specific installation of one or more `cubes`
- where are grouped configuration files of the final web application.
-
-In this document, we will show you how to create a `cube` and how to use it
-in an `instance` for your web application.
-
-Create your cube
-----------------
-
-After you installed your `CubicWeb` development environment, you can start
-to build your first cube: ::
-
-  cubicweb-ctl newcube blog
-
-This will create in ``/path/to/forest/cubes`` a directory containing: ::
-
-  blog/
-  |
-  |-- data/
-  |   |-- cubes.blog.css
-  |   |-- cubes.blog.js  
-  |   |-- external_resources
-  |
-  |-- debian/
-  |   |-- changelog
-  |   |-- compat
-  |   |-- control
-  |   |-- copyright
-  |   |-- cubicweb-blog.prerm
-  |   |-- rules
-  |
-  |-- entities.py
-  |
-  |-- i18n/
-  |   |-- en.po
-  |   |-- fr.po
-  |
-  |-- __init__.py
-  |
-  |-- MANIFEST.in
-  |
-  |-- migration/
-  |   |-- postcreate.py
-  |   |-- precreate.py
-  |
-  |-- __pkginfo__.py
-  |
-  |-- schema.py
-  |
-  |-- setup.py
-  |
-  |-- site_cubicweb.py
-  |
-  |-- sobjects.py
-  |
-  |-- test/
-  |   |-- data/
-  |       |-- bootstrap_cubes
-  |   |-- pytestconf.py
-  |   |-- realdb_test_blog.py
-  |   |-- test_blog.py
-  |
-  |-- views.py
-
-Any changes applied to your data model should be done in this
-directory.
-
-
-Define your data schema
------------------------
-
-The data model or schema is hte core of your `CubicWeb` application.
-This is where is defined the type of content you application will handle.
-
-The data model is defined in the file ``schema.py`` of your cube
-``blog`` such as follows.
-
-::
-
-  from cubicweb.schema import format_constraint
-  class Blog(EntityType):
-    title = String(maxsize=50, required=True)
-    description = String()
-
-  class BlogEntry(EntityType):
-    title = String(required=True, fulltextindexed=True, maxsize=256)
-    publish_date = Date(default='TODAY')
-    content = String(required=True, fulltextindexed=True)
-    entry_of = SubjectRelation('Blog', cardinality='?*') 
-
-
-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. 
-The description is a string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a content. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The content is a string that will be indexed in
-the full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that links it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-
-Create your instance
---------------------
-
-::
-  
-  cubicweb-ctl create blog blogdemo
-
-
-This command will create a directory ``~/etc/cubicweb.d/blogdemo``
-which will contain all the configuration files required to start
-you web application.
-
-The instance ``blogdemo`` is based on the cube ``blog``.
-
-
-Welcome in your web application
--------------------------------
-
-Run your application with the following command: ::
-
-  cubicweb-ctl start -D blogdemo
-
-
-You can now access to your web application to create blogs and post messages
-by visitin the URL http://localhost:8080/.
-A login form will first be prompted. By default, the application will not allow
-anonymous user to get in the application. You should then use the admin
-account you created at the time you initialized the database with
-``cubicweb-ctl create``.
-
-.. image:: images/login-form.png
-
-
-Once authenticated, you can start playing with your application 
-and create entities. Bravo!
-
-.. image:: images/blog-demo-first-page.png
-
-Please notice that so far, `CubicWeb` franework managed all aspects of 
-the web application based in the schema provided at first.
-
-
-Create entities
----------------
-
-We will now create a couple of entities in our web application.
-
-Create a Blog
-~~~~~~~~~~~~~
-
-Let us create a few of these entities. Click on the `[+]` at the right
-of the link Blog.  Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the
-form by clicking on ``Validate``.
-
-.. image:: images/cbw-create-blog.en.png
-   :alt: from to create blog
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link that will list for you all the existing Blog.
-You should be seeing a list with a single item ``Tech-blog`` you
-just created.
-
-.. image:: images/cbw-list-one-blog.en.png
-   :alt: displaying a list of a single blog
-
-Clicking on this item will get you to its detailed description except
-that in this case, there is not much to display besides the name and
-the phrase ``everything about technology``.
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-.. image:: images/cbw-list-two-blog.en.png
-   :alt: displaying a list of two blogs
-
-Create a BlogEntry
-~~~~~~~~~~~~~~~~~~
-
-Get back to the home page and click on [+] at the right of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``Validate``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``. 
-
-You could also have, at the time you started to fill the form for a
-new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the 
-combobox titled ``add relation`` would have showed up.
-
-
-.. image:: images/cbw-add-relation-entryof.en.png
-   :alt: editing a blog entry to add a relation to a blog
-
-Validate the changes by clicking ``Validate``. The entity BlogEntry
-that is displayed now includes a link to the entity Blog named
-``MyLife``.
-
-.. image:: images/cbw-detail-one-blogentry.en.png
-   :alt: displaying the detailed view of a blogentry
-
-Please notice that so far, `CubicWeb` franework managed all aspects of 
-the web application based in the schema provided at first.
-Also if you wish to get a graphical view of the schema, visit
-the link `Application schema`` which will direct you to :
-http://localhost:8080/view?vid=schema
-
-.. image:: images/cbw-schema.en.png
-   :alt: graphical view of the schema (aka data-model)
-
-
-Define your entities views
---------------------------
-
-The views selection principle
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-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 resulsets it can be applied to
-
-
-`CubicWeb` provides a lot of standard views for the type
-`EntityView`, for a complete list, you
-will have to 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
-mecanism which computes a score used to identify which view
-is the best to apply for the `result set` we are trying to 
-display. 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. We will see more details
-on this in :ref:`DefinitionVues`.
-
-For example, the view named ``primary`` is the one used to display
-a single entity. We will now show you hos to customize this view.
-
-
-View customization
-~~~~~~~~~~~~~~~~~~
-
-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``.
-
-We can by example add in front of the pulication date a prefix specifying
-the date we see is the publication date.
-
-To do so, please apply the following changes:
-
-:: 
-
-  from cubicweb.web.views import baseviews
-
-
-  class BlogEntryPrimaryView(baseviews.PrimaryView):
-
-    accepts = ('BlogEntry',)
-
-    def render_entity_title(self, entity):
-        self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title()))
-
-    def content_format(self, entity):
-        return entity.view('reledit', rtype='content_format')
-
-    def cell_call(self, row, col):
-        entity = self.entity(row, col)
-
-        # display entity attributes with prefixes
-        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:
-            self.render_entity_relations(entity, siderelations)
-
-.. note::
-  When a view is modified, it is not required to restart the application
-  server. Save the Python file and reload the page in your web browser
-  to view the changes.
-
-You can now see that the publication date has a prefix.
-
-.. image:: images/cbw-update-primary-view.en.png
-   :alt: modified primary view
-
-
-The above source code defines a new primary view for
-``BlogEntry``. 
-
-Since views are applied to resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates. We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. In our
-example we use it to output HTML tags and values of the entity's attributes.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/02-00-foundation.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,34 @@
+.. -*- 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), etc.
+
+In 2008, `CubicWeb` was ported for a new type of source : the datastore 
+from GoogleAppEngine_.
+
+.. include:: 02-01-concepts.en.txt
+.. include:: 02-02-registry.en.txt
+.. include:: 02-03-configuration.en.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/02-01-concepts.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,411 @@
+.. -*- coding: utf-8 -*-
+
+Concepts
+--------
+
+Global architecture
+~~~~~~~~~~~~~~~~~~~
+.. image:: images/archi_globale.png
+
+.. note::
+  For real, the client and server sides are integrated in the same
+  process and interact directly, without the needs for distants
+  calls using Pyro. It is important to note down that those two
+  sides, client/server, are disjointed and it is possible to execute
+  a couple of calls in distincts processes to balance the load of
+  your web site on one or more machines.
+
+.. _TermsVocabulary:
+
+Terms and vocabulary
+~~~~~~~~~~~~~~~~~~~~~
+
+*schema*
+  The schema defines the data model of an application based on entities
+  and relations, modeled with a comprehensive language made of Python
+  classes based on `yams`_ library. This is the core piece
+  of an application. It is initially defined in the file system and is
+  stored in the database at the time an instance is created. `CubicWeb`
+  provides a certain number of system entities included automatically as
+  it is necessarry for the core of `CubicWeb` and a library of
+  cubes that can be explicitely included if necessary.
+
+
+*entity type*
+  An entity is a set of attributes; the essential attribute of
+  an entity is its key, named eid
+
+*relation type*
+  Entities are linked to each others by relations. In `CubicWeb`
+  relations are binary: by convention we name the first item of
+  a relation the `subject` and the second the `object`.
+
+*final entity type*
+  Final types corresponds to the basic types such as string of characters,
+  integers... Those types have a main property which is that they can
+  only be used as `object` of a relation. The attributes of an entity
+  (non final) are entities (finals).
+
+*final relation type*
+  A relation is said final if its `object` is a final type. This is equivalent
+  to an entity attribute.
+
+*relation definition*
+  a relation definition is a 3-uple (subject entity type, relation type, object entity type),
+  with an associated set of property such as cardinality, constraints...
+  
+*repository*
+  This is the RQL server side of `CubicWeb`. Be carefull not to get
+  confused with a Mercurial repository or a debian repository.
+
+*source*
+  A data source is a container of data (SGBD, LDAP directory, `Google
+  App Engine`'s datastore ...) integrated in the
+  `CubicWeb` repository. This repository has at least one source, `system` which 
+  contains the schema of the application, plain-text index and others
+  vital informations for the system.
+
+*configuration*
+  It is possible to create differents configurations for an instance:
+
+  - ``repository`` : repository only, accessible for clients using Pyro
+  - ``twisted`` : web interface only, access the repository using Pyro
+  - ``all-in-one`` : web interface and repository in a single process. 
+     The repository could be or not accessible using Pyro.
+
+*cube*
+  A cube is a model grouping one or multiple data types and/or views
+  to provide a specific functionnality or a complete `CubicWeb` application
+  potentially using other cubes. The available subes are located in the file
+  system at `/path/to/forest/cubicweb/cubes`.
+  Larger applications can be built faster by importing cubes,
+  adding entities and relationships and overriding the
+  views that need to display or edit informations not provided by
+  cubes.
+
+*instance*
+  An instance is a specific installation of a cube. All the required 
+  configuration files necessarry 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.
+  By example logilab.org and our intranet are two instances of a single
+  cube jpl, developped internally.
+  The instances are defined in the directory `~/etc/cubicweb.d`.
+
+*application*
+  The term application is sometime 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.
+
+*result set*
+  This object contains the results of an RQL query sent to the source
+  and information on the query.
+
+*Pyro*
+  `Python Remote Object`_, distributed objects system similar to Java's RMI
+  (Remote Method Invocation), which can be used for the dialog between the web
+  side of the framework and the RQL repository.
+
+*query language*
+  A full-blown query language named RQL is used to formulate requests
+  to the database or any sources such as LDAP or `Google App Engine`'s 
+  datastore.
+
+*views*
+  A view is applied to a `result set` to present it as HTML, XML,
+  JSON, CSV, etc. Views are implemented as Python classes. There is no
+  templating language.
+
+*generated user interface*
+  A user interface is generated on-the-fly from the schema definition:
+  entities can be created, displayed, updated and deleted. As display
+  views are not very fancy, it is usually necessary to develop your
+  own. Any generated view can be overridden by defining a new one with
+  the same identifier.
+
+*rql*
+ XXX
+ 
+.. _`Python Remote Object`: http://pyro.sourceforge.net/
+.. _`yams`: http://www.logilab.org/project/yams/
+
+
+`CubicWeb` engine
+~~~~~~~~~~~~~~~~~
+
+The engine in `CubicWeb` is a set of classes managing a set of objects loaded
+dynamically at the startup of `CubicWeb` (*appobjects*). Those dynamics objects, based on the schema
+or the library, are building the final application. The differents dymanic components are
+by example:
+
+* client and server side
+
+  - entities definition, containing the logic which enables application data manipulation
+
+* client side
+
+  - *views*, or more specifically
+
+    - boxes
+    - header and footer
+    - forms
+    - page templates
+
+  - *actions*
+  - *controllers*
+
+* server side
+
+  - notification hooks
+  - notification views
+
+The components of the engine are:
+
+* a frontal web (only twisted is available so far), transparent for dynamic objects
+* an object that encapsulates the configuration
+* a `registry` (`cubicweb.cwvreg`) containing the dynamic objects loaded automatically
+
+Every *appobject* may access to the instance configuration using its *config* attribute
+and to the registry using its *vreg* attribute.
+
+API Python/RQL
+~~~~~~~~~~~~~~
+
+Inspired from the standard db-api, with a Connection object having the methods
+cursor, rollback and commit essentially. The most important method is
+the `execute` method of a cursor :
+
+`execute(rqlstring, args=None, eid_key=None, build_descr=True)`
+
+:rqlstring: the RQL query to execute (unicode)
+:args: if the query contains substitutions, a dictionnary containing the values to use
+:eid_key: 
+   an implementation detail of the RQL queries cache implies that if a substitution
+   is used to introduce an eid *susceptible to raise the ambiguities in the query
+   type resolution*, then we have to specify the correponding key in the dictionnary
+   through this argument
+
+
+The `Connection` object owns the methods `commit` and `rollback`. You *should
+never need to use them* during the development of the web interface based on
+the `CubicWeb` framework as it determines the end of the transaction depending 
+on the query execution success.
+
+.. note::
+  While executing updates queries (SET, INSERT, DELETE), if a query generates
+  an error related to security, a rollback is automatically done on the current
+  transaction.
+  
+
+The `Request` class (`cubicweb.web`)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A request instance is created when an HTPP request is sent to the web server.
+It contains informations such as forms parameters, user authenticated, etc.
+
+**Globally, a request represents a user query, either through HTTP or not
+(we also talk about RQL queries on the server side by example)**
+
+An instance of `Request` has the following attributes:
+
+* `user`, instance of `cubicweb.common.utils.User` corresponding to the authenticated
+  user
+* `form`, dictionnary containing the values of a web form
+* `encoding`, characters encoding to use in the response
+
+But also:
+
+:Session data handling:
+  * `session_data()`, returns a dictinnary containing all the session data
+  * `get_session_data(key, default=None)`, returns a value associated to the given
+    key or the value `default` if the key is not defined
+  * `set_session_data(key, value)`, assign a value to a key
+  * `del_session_data(key)`,  suppress the value associated to a key
+    
+
+:Cookies handling:
+  * `get_cookie()`, returns a dictionnary containing the value of the header
+    HTTP 'Cookie'
+  * `set_cookie(cookie, key, maxage=300)`, adds a header HTTP `Set-Cookie`,
+    with a minimal 5 minutes length of duration by default (`maxage` = None
+    returns a *session* cookie which will expire when the user closes the browser
+    window
+  * `remove_cookie(cookie, key)`, forces a value to expire
+
+:URL handling:
+  * `url()`, returns the full URL of the HTTP request
+  * `base_url()`, returns the root URL of the web application
+  * `relative_path()`, returns the relative path of the request
+
+:And more...:
+  * `set_content_type(content_type, filename=None)`, adds the header HTTP
+    'Content-Type'
+  * `get_header(header)`, returns the value associated to an arbitrary header
+    of the HTTP request
+  * `set_header(header, value)`, adds an arbitrary header in the response
+  * `cursor()` returns a RQL cursor on the session
+  * `execute(*args, **kwargs)`, shortcut to ``.cursor().execute()``
+  * `property_value(key)`, properties management (`EProperty`)
+  * dictionnary `data` to store data to share informations between components
+    *while a request is executed*
+
+Please note down that this class is abstract and that a concrete implementation
+will be provided by the *frontend* web used (in particular *twisted* as of
+today). For the views or others that are executed on the server side,
+most of the interface of `Request` is defined in the session associated
+to the client.
+
+The `AppObject` class
+~~~~~~~~~~~~~~~~~~~~~
+
+In general:
+
+* we do not inherit directly from this class but from a more specific
+  class such as `AnyEntity`, `EntityView`, `AnyRsetView`,
+  `Action`...
+
+* to be recordable, a subclass has to define its own register (attribute
+  `__registry__`) and its identifier (attribute `id`). Usually we do not have
+  to take care of the register, only the identifier `id`.
+
+We can find a certain number of attributes and methods defined in this class 
+and so common to all the application objects:
+
+At the recording, the following attributes are dynamically added to
+the *subclasses*:
+
+* `vreg`, the `vregistry` of the application
+* `schema`, the application schema
+* `config`, the application configuration
+
+We also find on instances, the following attributes:
+
+* `req`, `Request` instance
+* `rset`, the *result set* associated to the object if necessarry
+* `cursor`, rql cursor on the session
+
+
+:URL handling:
+  * `build_url(method=None, **kwargs)`, returns an absolute URL based on
+    the given arguments. The *controller* supposed to handle the response
+    can be specified through the special parameter `method` (the connection
+    is theoretically done automatically :).
+
+  * `datadir_url()`, returns the directory of the application data
+    (contains static files such as images, css, js...)
+
+  * `base_url()`, shortcut to `req.base_url()`
+
+  * `url_quote(value)`, version *unicode safe* of the function `urllib.quote`
+
+:Data manipulation:
+
+  * `etype_rset(etype, size=1)`, shortcut to `vreg.etype_rset()`
+
+  * `eid_rset(eid, rql=None, descr=True)`, returns a *result set* object for
+    the given eid
+  * `entity(row, col=0)`, returns the entity corresponding to the data position
+    in the *result set* associated to the object
+
+  * `complete_entity(row, col=0, skip_bytes=True)`, is equivalent to `entity` but
+    also call the method `complete()` on the entity before returning it
+
+:Data formatting:
+  * `format_date(date, date_format=None, time=False)`
+  * `format_time(time)`
+
+:And more...:
+
+  * `external_resource(rid, default=_MARKER)`, access to a value defined in the
+    configuration file `external_resource`
+    
+  * `tal_render(template, variables)`, 
+
+
+.. note::
+  When we inherit from `AppObject` (even not directly), you *always* have to use
+  **super()** to get the methods and attributes of the superclasses, and not
+  use the class identifier.
+  By example, instead of writting: ::
+
+      class Truc(PrimaryView):
+          def f(self, arg1):
+              PrimaryView.f(self, arg1)
+
+  You'd better write: ::
+  
+      class Truc(PrimaryView):
+          def f(self, arg1):
+              super(Truc, self).f(arg1)
+
+
+Standard structure for a cube
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A complex cube is structured as follows:
+
+::
+  
+  mycube/
+  |
+  |-- schema.py
+  |
+  |-- entities/
+  |
+  |-- sobjects/
+  |
+  |-- views/
+  |
+  |-- test/
+  |
+  |-- i18n/
+  |
+  |-- data/
+  |
+  |-- migration/
+  | |- postcreate.py
+  | \- depends.map
+  |
+  |-- debian/
+  |
+  \-- __pkginfo__.py
+    
+We can use simple Python module instead of packages, by example: 
+
+::
+  
+  mycube/
+  |
+  |-- entities.py
+  |-- hooks.py
+  \-- views.py
+    
+
+where :
+
+* ``schema`` contains the schema definition (server side only)
+* ``entities`` contains the entities definition (server side and web interface)
+* ``sobjects`` contains hooks and/or views notifications (server side only)
+* ``views`` contains the different components of the web interface (web interface only)
+* ``test`` contains tests specifics to the application (not installed)
+* ``i18n`` contains the messages catalog for supported languages (server side and 
+  web interface) 
+* ``data`` contains arbitrary data files served statically
+  (images, css, javascripts files)... (web interface only)
+* ``migration`` contains the initialization file for new instances
+  (``postcreate.py``) and in general a file containing the `CubicWeb` dependancies 
+  of the cube depending on its version (``depends.map``)
+* ``debian`` contains all the files that manages the debian packaging
+  (you would find there the classical structure with ``control``, ``rules``, 
+  ``changelog``... (not installed)
+* the file ``__pkginfo__.py`` provides meta-data on the cube, especially the 
+  distribution name and the current version (server side and web interface) or
+  also the sub-cubes used by this cube
+
+The only required files are:
+
+* the file ``__pkginfo__.py``
+* the schema definition
+  XXX false, we may want to have cubes which are only adding a service, no persistent data (eg embeding for instance)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/02-02-registry.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,147 @@
+.. -*- coding: utf-8 -*-
+
+The Registry
+------------
+
+[WRITE ME]
+
+* talk about the vreg singleton, appobjects, registration and selection
+
+
+Details of the recording process
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At startup, the `registry` or registers base, inspects a number of directories
+looking for compatible classes definition. After a recording process, the objects
+are assigned to registers so that they can be selected dynamically while the
+application is running.
+
+The base class of those objects is `AppRsetObject` (module `cubicweb.common.appobject`).
+
+XXX registers example
+XXX actual details of the recording process!
+
+Runtime objects selection
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+XXX tell why it's a cw foundation!
+
+Application objects are stored in the registry using a two level hierarchy :
+
+  object's `__registry__` : object's `id` : [list of app objects]
+
+The following rules are applied to select an object given a register and an id and an input context:
+* each object has a selector
+  - its selector may be derivated from a set of basic (or not :)
+    selectors using `chainall` or `chainfirst` combinators
+* a selector return a score >= 0
+* a score of 0 means the objects can't be applied to the input context
+* the object with the greatest score is selected. If multiple objects have an
+  identical score, one of them is selected randomly (this is usually a bug)
+
+The object's selector is the `__select__` class method on the object's class.
+
+The score is used to choose the most pertinent objects where there are more than
+one selectable object. For instance, if you're selecting the primary
+(eg `id = 'primary'`) view (eg `__registry__ = 'view'`) for a result set containing
+a `Card` entity, 2 objects will probably be selectable:
+
+* the default primary view (`accepts = 'Any'`)
+* the specific `Card` primary view (`accepts = 'Card'`)
+
+This is because primary views are using the `accept_selector` which is considering the
+`accepts` class attribute of the object's class. Other primary views specific to other
+entity types won't be selectable in this case. And among selectable objects, the
+accept selector will return a higher score the the second view since it's more
+specific, so it will be selected as expected.
+
+Usually, you won't define it directly but by defining the `__selectors__` tuple
+on the class, with ::
+
+  __selectors__ = (sel1, sel2)
+
+which is equivalent to ::
+
+  __select__ = classmethod(chainall(sel1, sel2))
+
+The former is prefered since it's shorter and it's ease overriding in
+subclasses (you have access to sub-selectors instead of the wrapping function).
+
+:chainall(selectors...): if one selector return 0, return 0, else return the sum of scores
+
+:chainfirst(selectors...): return the score of the first selector which has a non zero score
+
+XXX describe standard selector (link to generated api doc!)
+
+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.
+
+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
+qu'on veut.
+
+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)
+
+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é.
+
+Donc... On a déja dans web/views/boxes.py la classe RSSIconBox qui fonctionne. Son
+sélecteur ::
+
+  class RSSIconBox(ExtResourcesBoxTemplate):
+    """just display the RSS icon on uniform result set"""
+    __selectors__ = ExtResourcesBoxTemplate.__selectors__ + (nfentity_selector,)
+
+
+indique qu'il prend en compte :
+
+* les conditions d'apparition de la boite (faut remonter dans les classes parentes
+  pour voir le détail)
+* nfentity_selector, 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
+pour le 1er cas ::
+
+  class EntityRSSIconBox(RSSIconBox):
+    """just display the RSS icon on uniform result set for a single entity"""
+    __selectors__ = RSSIconBox.__selectors__ + (onelinerset_selector,)
+
+
+Ici, on ajoute onelinerset_selector, qui filtre sur des rset de taille 1. Il faut
+savoir que quand on chaine des selecteurs, le score final est la somme des scores
+renvoyés par chaque sélecteur (sauf si l'un renvoie zéro, auquel cas l'objet est
+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.
+
+Voili voilou, il reste donc pour finir tout ça :
+
+* à 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
+
+
+When to use selectors?
+```````````````````````
+
+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
+poser la question s'il ne vaut pas mieux avoir deux objets différent
+avec des sélecteurs approprié.
+
+If this is so fundamental, why don't I see them more often?
+```````````````````````````````````````````````````````````
+
+Because you're usually using base classes which are hiding the plumbing
+of __registry__ (almost always), id (often when using "standard" object),
+register and selector.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/02-03-configuration.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Configuration
+-------------
+
+[WRITE ME]
+
+* the config object. adding configuration option
+
--- a/doc/book/en/02-foundation.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,411 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-`CubicWeb` concepts
-===================
-
-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), etc.
-
-In 2008, `CubicWeb` was ported for a new type of source : the datastore 
-from GoogleAppEngine_.
-
-Global architecture
--------------------
-.. image:: images/archi_globale.png
-
-.. note::
-  For real, the client and server sides are integrated in the same
-  process and interact directly, without the needs for distants
-  calls using Pyro. It is important to note down that those two
-  sides, client/server, are disjointed and it is possible to execute
-  a couple of calls in distincts processes to balance the load of
-  your web site on one or more machines.
-
-
-Terms and vocabulary
---------------------
-
-*schema*
-  the schema defines the data model of an application based on entities
-  and relations, thanks to the `yams`_ library. This is the core piece
-  of an application. It is initially defined in the file system and is
-  stored in the database at the time an instance is created. `CubicWeb`
-  provides a certain number of system entities included automatically as
-  it is necessarry for the core of `CubicWeb` and a library of
-  cubes that can be explicitely included if necessarry.
-
-
-*entity type*
-  an entity is a set of attributes; the essential attribute of
-  an entity is its key, named eid
-
-*relation type*
-  entities are linked to each others by relations. In `CubicWeb`
-  relations are binary: by convention we name the first item of
-  a relation the `subject` and the second the `object`.
-
-*final entity type*
-  final types corresponds to the basic types such as string of characters,
-  integers... Those types have a main property which is that they can
-  only be used as `object` of a relation. The attributes of an entity
-  (non final) are entities (finals).
-
-*final relation type*
-  a relation is said final if its `object` is a final type. This is equivalent
-  to an entity attribute.
-
-*repository*
-  this is the RQL server side of `CubicWeb`. Be carefull not to get
-  confused with a Mercurial repository or a debian repository.
-
-*source*
-  a data source is a container of data (SGBD, LDAP directory...) integrated in the
-  `CubicWeb` repository. This repository has at least one source, `system` which 
-  contains the schema of the application, plain-text index and others
-  vital informations for the system.
-
-*configuration*
-  it is possible to create differents configurations for an instance:
-
-  - ``repository`` : repository only, accessible for clients using Pyro
-  - ``twisted`` : web interface only, access the repository using Pyro
-  - ``all-in-one`` : web interface and repository in a single process. 
-     The repository could be or not accessible using Pyro.
-
-*cube*
-  a cube is a model grouping one or multiple data types and/or views
-  to provide a specific functionnality or a complete `CubicWeb` application
-  potentially using other cubes. The available subes are located in the file
-  system at `/path/to/forest/cubicweb/cubes`
-
-*instance*
-  an instance is a specific installation of a cube. All the required 
-  configuration files necessarry 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.
-  By example logilab.org and our intranet are two instances of a single
-  cube jpl, developped internally.
-  The instances are defined in the directory `~/etc/cubicweb.d`.
-
-*application*
-  the term application is sometime 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.
-
-*result set*
-  this object contains the results of an RQL query and information on the query.
-
-*Pyro*
-  `Python Remote Object`_, distributed objects system similar to Java's RMI
-  (Remote Method Invocation), which can be used for the dialog between the web
-  side of the framework and the RQL repository.
-
-.. _`Python Remote Object`: http://pyro.sourceforge.net/
-.. _`yams`: http://www.logilab.org/project/name/yams/
-
-
-`CubicWeb` engine
------------------
-
-The web engine in `CubicWeb` is a set of classes managing a set of objects loaded
-dynamically at the startup of `CubicWeb`. Those dynamics objects, based on the schema
-or the library, are building the final web site. The differents dymanic components are
-by example:
-
-* client and server side
-
-  - entities definition, containing the logic which enables application data manipulation
-
-* client side
-
-  - *views*, or more specifically
-
-    - boxes
-    - header and footer
-    - forms
-    - page templates
-
-  - *actions*
-  - *controllers*
-
-* server side
-
-  - notification hooks
-  - notification views
-
-The components of the engine are:
-
-* a frontal web (only twisted is available so far), transparent for dynamic objects
-* an object that encapsulates the configuration
-* a `vregistry` (`cubicweb.cwvreg`) containing the dynamic objects loaded automatically
-
-
-Details of a recording process
-------------------------------
-
-At startup, the `vregistry` or registers base, inspects a number of directories
-looking for compatible classes definition. After a recording process, the objects
-are assigned to registers so that they can be selected dynamically while the
-application is running.
-
-The base class of those objects is `AppRsetObject` (module `cubicweb.common.appobject`).
-
-API Python/RQL
---------------
-
-Inspired from the standard db-api, with a Connection object having the methods
-cursor, rollback and commit essentially. The most important method is
-the `execute` method of a cursor :
-
-`execute(rqlstring, args=None, eid_key=None, build_descr=True)`
-
-:rqlstring: the RQL query to execute (unicode)
-:args: if the query contains substitutions, a dictionnary containing the values to use
-:eid_key: 
-   an implementation detail of the RQL queries cache implies that if a substitution
-   is used to introduce an eid *susceptible to raise the ambiguities in the query
-   type resolution*, then we have to specify the correponding key in the dictionnary
-   through this argument
-
-
-The `Connection` object owns the methods `commit` and `rollback`. You *should
-never need to use them* during the development of the web interface based on
-the `CubicWeb` framework as it determines the end of the transaction depending 
-on the query execution success.
-
-.. note::
-  While executing updates queries (SET, INSERT, DELETE), if a query generates
-  an error related to security, a rollback is automatically done on the current
-  transaction.
-  
-
-The `Request` class (`cubicweb.web`)
-------------------------------------
-
-A request instance is created when an HTPP request is sent to the web server.
-It contains informations such as forms parameters, user authenticated, etc.
-
-**Globally, a request represents a user query, either through HTTP or not
-(we also talk about RQL queries on the server side by example)**
-
-An instance of `Request` has the following attributes:
-
-* `user`, instance of `cubicweb.common.utils.User` corresponding to the authenticated
-  user
-* `form`, dictionnary containing the values of a web form
-* `encoding`, characters encoding to use in the response
-
-But also:
-
-:Session data handling:
-  * `session_data()`, returns a dictinnary containing all the session data
-  * `get_session_data(key, default=None)`, returns a value associated to the given
-    key or the value `default` if the key is not defined
-  * `set_session_data(key, value)`, assign a value to a key
-  * `del_session_data(key)`,  suppress the value associated to a key
-    
-
-:Cookies handling:
-  * `get_cookie()`, returns a dictionnary containing the value of the header
-    HTTP 'Cookie'
-  * `set_cookie(cookie, key, maxage=300)`, adds a header HTTP `Set-Cookie`,
-    with a minimal 5 minutes length of duration by default (`maxage` = None
-    returns a *session* cookie which will expire when the user closes the browser
-    window
-  * `remove_cookie(cookie, key)`, forces a value to expire
-
-:URL handling:
-  * `url()`, returns the full URL of the HTTP request
-  * `base_url()`, returns the root URL of the web application
-  * `relative_path()`, returns the relative path of the request
-
-:And more...:
-  * `set_content_type(content_type, filename=None)`, adds the header HTTP
-    'Content-Type'
-  * `get_header(header)`, returns the value associated to an arbitrary header
-    of the HTTP request
-  * `set_header(header, value)`, adds an arbitrary header in the response
-  * `cursor()` returns a RQL cursor on the session
-  * `execute(*args, **kwargs)`, shortcut to ``.cursor().execute()``
-  * `property_value(key)`, properties management (`EProperty`)
-  * dictionnary `data` to store data to share informations between components
-    *while a request is executed*
-
-Please note down that this class is abstract and that a concrete implementation
-will be provided by the *frontend* web used (in particular *twisted* as of
-today). For the views or others that are executed on the server side,
-most of the interface of `Request` is defined in the session associated
-to the client.
-
-The `AppObject` class
----------------------
-
-In general:
-
-* we do not inherit directly from this class but from a more specific
-  class such as `AnyEntity`, `EntityView`, `AnyRsetView`,
-  `Action`...
-
-* to be recordable, a subclass has to define its own register (attribute
-  `__registry__`) and its identifier (attribute `id`). Usually we do not have
-  to take care of the register, only the identifier `id`.
-
-We can find a certain number of attributes and methods defined in this class 
-and so common to all the application objects:
-
-At the recording, the following attributes are dynamically added to
-the *subclasses*:
-
-* `vreg`, the `vregistry` of the application
-* `schema`, the application schema
-* `config`, the application configuration
-
-We also find on instances, the following attributes:
-
-* `req`, `Request` instance
-* `rset`, the *result set* associated to the object if necessarry
-* `cursor`, rql cursor on the session
-
-
-:URL handling:
-  * `build_url(method=None, **kwargs)`, returns an absolute URL based on
-    the given arguments. The *controller* supposed to handle the response
-    can be specified through the special parameter `method` (the connection
-    is theoretically done automatically :).
-
-  * `datadir_url()`, returns the directory of the application data
-    (contains static files such as images, css, js...)
-
-  * `base_url()`, shortcut to `req.base_url()`
-
-  * `url_quote(value)`, version *unicode safe* of the function `urllib.quote`
-
-:Data manipulation:
-
-  * `etype_rset(etype, size=1)`, shortcut to `vreg.etype_rset()`
-
-  * `eid_rset(eid, rql=None, descr=True)`, returns a *result set* object for
-    the given eid
-  * `entity(row, col=0)`, returns the entity corresponding to the data position
-    in the *result set* associated to the object
-
-  * `complete_entity(row, col=0, skip_bytes=True)`, is equivalent to `entity` but
-    also call the method `complete()` on the entity before returning it
-
-:Data formatting:
-  * `format_date(date, date_format=None, time=False)`
-  * `format_time(time)`
-
-:And more...:
-
-  * `external_resource(rid, default=_MARKER)`, access to a value defined in the
-    configuration file `external_resource`
-    
-  * `tal_render(template, variables)`, 
-
-
-.. note::
-  When we inherit from `AppObject` (even not directly), you *always* have to use
-  **super()** to get the methods and attributes of the superclasses, and not
-  use the class identifier.
-  By example, instead of writting: ::
-
-      class Truc(PrimaryView):
-          def f(self, arg1):
-              PrimaryView.f(self, arg1)
-
-  You'd better write: ::
-  
-      class Truc(PrimaryView):
-          def f(self, arg1):
-              super(Truc, self).f(arg1)
-
-
-Standard structure for a cube
------------------------------
-
-A complex cube is structured as follows:
-
-::
-  
-  mycube/
-  |
-  |-- schema.py
-  |
-  |-- entities/
-  |
-  |-- sobjects/
-  |
-  |-- views/
-  |
-  |-- test/
-  |
-  |-- i18n/
-  |
-  |-- data/
-  |
-  |-- migration/
-  | |- postcreate.py
-  | \- depends.map
-  |
-  |-- debian/
-  |
-  \-- __pkginfo__.py
-    
-We can use simple Python module instead of packages, by example: 
-
-::
-  
-  mycube/
-  |
-  |-- entities.py
-  |-- hooks.py
-  \-- views.py
-    
-
-where :
-
-* ``schema`` contains the schema definition (server side only)
-* ``entities`` contains the entities definition (server side and web interface)
-* ``sobjects`` contains hooks and/or views notifications (server side only)
-* ``views`` contains the different components of the web interface (web interface only)
-* ``test`` contains tests specifics to the application (not installed)
-* ``i18n`` contains the messages catalog for supported languages (server side and 
-  web interface) 
-* ``data`` contains arbitrary data files served statically
-  (images, css, javascripts files)... (web interface only)
-* ``migration`` contains the initialization file for new instances
-  (``postcreate.py``) and in general a file containing the `CubicWeb` dependancies 
-  of the cube depending on its version (``depends.map``)
-* ``debian`` contains all the files that manages the debian packaging
-  (you would find there the classical structure with ``control``, ``rules``, 
-  ``changelog``... (not installed)
-* the file ``__pkginfo__.py`` provides meta-data on the cube, especially the 
-  distribution name and the current version (server side and web interface) or
-  also the sub-cubes used by this cube
-
-The only required files are:
-
-* the file ``__pkginfo__.py``
-* the schema definition
--- a/doc/book/en/02-install.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _installation:
-
-Installation
-============
-
-Download the source
--------------------
-
-- The `Google AppEngine SDK` can be downloaded from:
-  http://code.google.com/appengine/downloads.html
-
-- `LAX` is available as an extension of `CubicWeb` under the GPLv2
-  license which can be downloaded from : http://cubicweb.org/
-
-Please follow instructions on how to install `CubicWeb` framework. 
-
-Once ``cubicweb-ctl`` is installed, then you can create a Google
-App Engine extension of our framework by running the command ::
-
-   cubicweb-ctl newgapp <myapp>
-
-This will create a directory containing ::
- 
-   `-- myapp/
-       |-- app.conf
-       |-- app.yaml
-       |-- bin/
-       |    `-- laxctl
-       |-- boostrap_cubes
-       |-- cubes/
-       |    |-- addressbook/
-       |    ..
-       |    |-- comment
-       |    ..
-       |    `-- zone/
-       |-- cubicweb/
-       |-- custom.py
-       |-- cw-cubes/
-       |-- dateutil/
-       |-- docutils/
-       |-- fckeditor/
-       |-- i18n/
-       |-- index.yaml
-       |-- loader.py
-       |-- logilab/
-       |-- main.py
-       |-- migration.py
-       |-- mx/
-       |-- roman.py
-       |-- rql/
-       |-- schema.py
-       |-- simplejson/
-       |-- tools/
-       |-- views.py
-       |-- vobject/
-       |-- 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
-`LAX` framework and its third-party libraries. You will notice that 
-the directory ``cubes`` is a library of reusable components.
-
-The main directories that you should know about are:
-
-  - ``cubes`` : this is a library of reusable yams components. To use 
-    those components you will list them in the variable 
-    `included-yams-cubes` of ``app.conf``. See also :ref:`components`. 
-  - [WHICH OTHER ONES SHOULD BE LISTED HERE?]
-
-Dependencies
-------------
-
-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 
-    and using python-yaml:
-    yaml -> full/path/to/google_appengine/lib/yaml/lib/yaml/
-  - gettext
-
-Setup
------
-
-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`.
-
-You can have the details of available commands by running ::
-
-   $ python myapp/bin/laxctl --help
-
-
-Generating translation files
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-`LAX` 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 i18nupdate 
-  $ python myapp/bin/laxctl i18ncompile 
-
-Ignore the errors that print "No translation file found for domain
-'erudi'". They disappear after the first run of i18ncompile.
-
-.. note:: The command  myapp/bin/laxctl i18nupdate needs to be executed
-   only if your application is using components from ginco-apps.
-   Otherwise, please skip it.
-
-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. 
-While running ``laxctl i18nupdate``, new string will be added to the catalogs.
-
-Generating the data directory
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In order to generate the ``myapp/data`` directory that holds the static
-files like stylesheets and icons, you need to run the command::
-
-  $ python myapp/bin/laxctl populatedata
-
-Generating the schema diagram
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-There is a view named ``schema`` that displays a diagram of the
-entity-relationship graph defined by the schema. This diagram has to
-be generated from the command line::
-
-  $ python myapp/bin/laxctl genschema
-
-Application configuration
--------------------------
-
-Authentication
-~~~~~~~~~~~~~~
-
-You have the option of using or not google authentication for your application.
-This has to be define in ``app.conf`` and ``app.yaml``.
-
-In ``app.conf`` modify the following variable::

-  # 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: .*
-  script: main.py
-  # comment the line below to allow anonymous access or if you don't want to use
-  # google authentication service
-  #login: required
-
-
-
-
-Quickstart : launch the application
------------------------------------
-
-On Mac OS X platforms, drag that directory on the
-`GoogleAppEngineLauncher`.
-
-On Unix and Windows platforms, run it with the dev_appserver::
-
-  $ 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 
-the application and continue the installation.
-
-You should be redirected to a page displaying a message `content initialized`.
-
-Initialize the datastore
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-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 
-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``.
-
-If you choosed to use google authentication, then you will not need to set up
-and administrator login but you will get the cookie value as well.
-
-This cookie values needs to be provided to ``laxctl`` commands
-in order to handle datastore administration requests.
-
-.. image:: images/lax-book.02-cookie-values.en.png
-   :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  
-   `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>`_ 
-   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>`_ 
-as a normal user.
-
-Unless you did something to change it, http://MYAPP_URL should be
-http://localhost:8080/
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-00-definition-schema.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,20 @@
+.. -*- coding: utf-8 -*-
+
+Data Model definition (*schema*)
+================================
+
+The schema is the main concept of `LAX` applications as it defines the
+data model we will handle. It is based on entities types already defined
+in the library and others, more specific, we would expect to find in one or
+more Python files under the `schema` directory.
+
+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 relation definition of the
+schema.
+
+
+.. include:: 03-10-stdlib-schemas.en.txt
+.. include:: 03-11-definition-schema.en.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-00-setup.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,13 @@
+.. -*- coding: utf-8 -*-
+
+.. _MiseEnPlaceEnv:
+
+===================================================
+Installation and set-up of a `CubicWeb` environment
+===================================================
+.. contents::
+
+.. include:: 03-01-installation.en.txt
+.. include:: 03-02-create-instance.en.txt
+.. include:: 03-03-cubicweb-ctl.en.txt
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-10-stdlib-schemas.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,86 @@
+.. -*- coding: utf-8 -*-
+
+Pre-defined schemas in the library
+----------------------------------
+
+The library defines a set of entities schemas that are required by the system
+or commonly used in `LAX` applications.
+Of course, you can extend those schemas if necessarry.
+
+System schemas
+``````````````
+Those are defined in::
+
+  ./myapp/ginco/schemas/
+  ./myapp/ginco/entities/
+
+``schemas/`` defines the data model you will use in your application. 
+It allows you to describre the entities and the relations you will need.
+
+``entities/`` deifnes the methods you might need on the entities you 
+defined in your schema.
+
+The system entities available are:
+
+* `EUser`, system users
+* `EGroup`, users groups
+* `EEType`, entity type
+* `ERType`, relation type
+
+* `State`, workflow state
+* `Transition`, workflow transition
+* `TrInfo`, record of a transition trafic for an entity 
+
+* `EmailAddress`, email address, used by the system to send notifications
+  to the users and also used by others optionnals schemas
+
+* `EProperty`, used to configure the application
+* `EPermission`, used to configure the security of the application
+
+* `Card`, generic documenting card
+* `Bookmark`, an entity type used to allow a user to customize his links within
+  the application
+
+
+Components in the library
+`````````````````````````
+
+Those are defined in::
+
+  ./myapp/ginco-apps/
+
+An application is based on several basic components. In the set of available
+basic components we can find by example:
+
+* `ecomment`, provides an entity type for `Comment` allowing us to comment others
+  site's entities
+
+* `emailinglist`, provides an entity type for `Mailinglist` which groups informations
+  in a discussion list
+
+* `efile`, provides entity types for `File` et `Image` used to represent
+  files (text or binary) with additionnal informations such as MIME type or
+  encoding.
+  
+* `elink`, provides an entity type for hypertext link (`Link`)
+
+* `eblog`, provides an entity type weblog (`Blog`)
+
+* `eperson`, provides an entity type for a person (`Person`)
+
+* `eaddressbook`, provides an entity type used to represent phone 
+  numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
+  
+* `eclasstags`, categorization system based on tags (`Tag`)
+
+* `eclassfolders`, categorization system based on folders hierarchy in order 
+  to create navigation sections (`Folder`)
+
+* `eemail`, archiving management for emails (`Email`, `Emailpart`,
+  `Emailthread`)
+
+* `ebasket`, basket management (`Basket`) allowing to group entities
+
+To declare the use of a component, once installed, add the name of the component
+to the variable `__use__` in the file `__pkginfo__.py` of your own component.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-11-definition-schema.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,344 @@
+.. -*- coding: utf-8 -*-
+
+Entity type definition
+----------------------
+
+An entity type is defined by a Python class which inherits `EntityType`. The
+class name correponds to the type name. Then the content of the class contains
+the description of attributes and relations for the defined entity type,
+by example ::
+
+  class Personne(EntityType):
+    """A person with the properties and the relations necessarry for my
+    application"""
+
+    last_name = String(required=True, fulltextindexed=True)
+    first_name = String(required=True, fulltextindexed=True)
+    title = String(vocabulary=('M', 'Mme', 'Mlle'))
+    date_of_birth = Date()
+    works_for = SubjectRelation('Company', cardinality='?*')
+
+* the name of the Python attribute corresponds to the name of the attribute
+  or the relation in `LAX` application.
+
+* all built-in types are available: `String`, `Int`, `Float`,
+  `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
+
+* each entity has at least the following meta-relations:
+
+  - `eid` (`Int`)
+  
+  - `creation_date` (`Datetime`)
+  
+  - `modification_date` (`Datetime`)
+  
+  - `created_by` (`EUser`) (which user created the entity)
+  
+  - `owned_by` (`EUser`) (who does the entity belongs to, by default the 
+     creator but not necessarry and it could have multiple owners)
+     
+  - `is` (`EEType`)
+
+  
+* it is also possible to define relations of type object by using `ObjectRelation`
+  instead of `SubjectRelation`
+
+* the first argument of `SubjectRelation` and `ObjectRelation` gives respectively
+  the object/subject entity type of the relation. This could be:  
+
+  * a string corresponding to an entity type
+
+  * a tuple of string correponding to multiple entities types
+
+  * special string such as follows:
+
+    - "**" : all types of entities
+    - "*" : all types of entities non meta
+    - "@" : all types of meta entities but not system entities (e.g. used for
+      the basis schema description)
+
+* it is possible to use the attribute `meta` to flag an entity type as a `meta`
+  (e.g. used to describe/categorize other entities)
+
+* optional properties for attributes and relations: 
+
+  - `description` : string describing an attribute or a relation. By default
+    this string will be used in the editing form of the entity, which means
+    that it is supposed to help the end-user and should be flagged by the
+    function `_` to be properly internationalized.
+
+  - `constraints` : list of conditions/constraints that the relation needs to
+    satisfy (c.f. `Contraints`_)
+
+  - `cardinality` : two characters string which specify the cardinality of the
+    relation. The first character defines the cardinality of the relation on
+    the subject, the second on the object of the relation. When a relation
+    has multiple possible subjects or objects, the cardinality applies to all
+    and not on a one to one basis (so it must be consistent...). The possible
+    values are inspired from regular expressions syntax:
+
+    * `1`: 1..1
+    * `?`: 0..1
+    * `+`: 1..n
+    * `*`: 0..n
+
+  - `meta` : boolean indicating that the relation is a meta-relation (false by
+    default)
+
+* optionnal 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 
+    attribute in the database (false by default). This is usefull 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 correpond to the RQL keywords `TODAY` and `NOW`.
+  
+  - `vocabulary` : specify static possible values of an attribute
+
+* optionnal 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`
+    as well*)
+
+  - `internationalizable` : boolean indicating if the value of the attribute
+    is internationalizable (false by default)
+
+  - `maxsize` : integer providing the maximum size of the string (no limit by default)
+
+* optionnal 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 need
+    to set 'object' as the value. The composition implies that when the relation
+    is deleted (so when the composite is deleted), the composed are also deleted.
+    [PAS CLAIR]
+  
+Contraints
+``````````
+By default, the available constraints types are:
+
+* `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 
+  numeric types
+
+* `UniqueConstraint` : identical to "unique=True"
+
+* `StaticVocabularyConstraint` : identical to "vocabulary=(...)"
+
+* `RQLConstraint` : allows to specify a RQL query that needs 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 
+  relation.
+
+* `RQLVocabularyConstraint` : similar to the previous type of constraint except
+  that it does not express a "strong" constraint, which means it is only used to
+  restrict the values listed in the drop-down menu of editing form, but it does
+  not prevent another entity to be selected
+  [PAS CLAIR]
+
+
+Relation type definition
+------------------------
+
+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, as well as 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 
+definition properties from the relation)[PAS CLAIR] by example ::
+
+  class locked_by(RelationType):
+    """relation on all entities indicating that they are locked"""
+    inlined = True
+    cardinality = '?*'
+    subject = '*'
+    object = 'EUser'
+
+In addition to the permissions, the own properties of the relation types
+(shared also by all definition of relation of this type) are:
+
+
+* `inlined` : boolean handling the physical optimization for archiving
+  the relation in the subject entity table, instead of creating a specific
+  table for the relation. This applies to the relation when the cardinality
+  of subject->relation->object is 0..1 ('?') or 1..1 ('1')
+
+* `symetric` : boolean indication that the relation is symetrical, which
+  means `X relation Y` implies `Y relation X`
+
+In the case of simultaneous relations definitions, `subject` and `object`
+can both be equal to the value of the first argument of `SubjectRelation`
+and `ObjectRelation`.
+
+When a relation is not inlined and not symetrical, and it does not require
+specific permissions, its definition (by using `SubjectRelation` and
+`ObjectRelation`) is all we need.
+
+Permissions definition
+----------------------
+
+Define permissions is set through to the attribute `permissions` of entities and
+relations types. It defines a dictionnary where the keys are the access types
+(action), and the values are the authorized groups or expressions.
+
+For an entity type, the possible actions are `read`, `add`, `update` and
+`delete`.
+
+For a relation type, the possible actions are `read`, `add`, and `delete`.
+
+For each access type, a tuple indicates the name of the authorized groups and/or
+one or multiple RQL expressions to satisfy to grant access. The access is
+provided once the user is in the listed groups or one of the RQL condition is
+satisfied.
+
+The standard groups are:
+
+* `guests`
+
+* `users`
+
+* `managers`
+
+* `owners` : virtual group corresponding to the entity's owner.
+  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 define in the precreate 
+of the application (``migration/precreate.py``).
+
+Use of RQL expression for writing rights
+````````````````````````````````````````
+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:
+
+* you have to use the class `ERQLExpression`
+
+* the used expression corresponds to the WHERE statement of an RQL query
+
+* in this expression, the variables X and U are pre-defined references
+  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 
+  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 
+
+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
+  [WHAT IS A NON FINALE RELATION]
+
+* in the expression, the variables S, O and U are pre-defined references
+  to respectively the subject and the object of the current relation (on
+  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: 
+
+  - to defines RQL expression, we have to use the class `ERQLExpression`
+    in which X represents the entity the attribute belongs to
+
+  - the permissions `add` and `delete` are equivalent. Only `add`/`read`
+    are actually taken in consideration.
+
+
+
+In addition to thatm the entity type `EPermission` from the standard library
+allow to build very complex and dynamic security architecture. The schema of
+this entity type is as follow: ::
+
+    class EPermission(MetaEntityType):
+	"""entity type that may be used to construct some advanced security configuration
+	"""
+	name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
+	require_group = SubjectRelation('EGroup', cardinality='+*',
+					description=_('groups to which the permission is granted'))
+	require_state = SubjectRelation('State',
+				    description=_("entity'state in which the permission is applyable"))
+	# can be used on any entity
+	require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
+					    description=_("link a permission to the entity. This "
+							  "permission should be used in the security "
+							  "definition of the entity's type to be useful."))
+
+
+Example of configuration ::
+
+    ...
+
+    class Version(EntityType):
+	"""a version is defining the content of a particular project's release"""
+
+	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'),)}
+
+    ...
+
+    class version_of(RelationType):
+	"""link a version to its project. A version is necessarily linked to one and only one project.
+	"""
+	permissions = {'read':   ('managers', 'users', 'guests',),
+		       'delete': ('managers', ),
+		       'add':    ('managers', 'logilab',
+				  RRQLExpression('O require_permission P, P name "add_version",'
+						 'U in_group G, P require_group G'),)
+		       }
+	inlined = True
+
+This configuration assumes/indicates [???] that an entity `EPermission` named
+"add_version" can be associated to a project and provides rights to create
+new versions on this project to specific groups. It is important to notice that:
+
+* in such case, we have to protect both the entity type "Version" and the relation
+  associating a version to a project ("version_of")
+
+* because of the genricity of the entity type `EPermission`, we have to execute
+  a unification with the groups and/or the states if necessary in the expression
+  ("U in_group G, P require_group G" in the above example)
+
+
+Use of RQL expression for reading rights
+````````````````````````````````````````
+
+The principles are the same but with the following restrictions:
+
+* we can not [??] `RRQLExpression` on relation types for reading
+
+* special relations "has_<ACTION>_permission" can not be used
+
+
+Note on the use of RQL expression for `add` permission
+``````````````````````````````````````````````````````
+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 
+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 checks 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.
+[PAS CLAIR]
--- a/doc/book/en/03-create-app.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Creating your first application
-===============================
-
-This tutorial will guide you step by step to build a blog application 
-and discover the unique features of `LAX`. It assumes that you followed
-the installation guidelines and that both the `AppEngine SDK` and the
-`LAX` framework are setup on your computer.
-
-Creating a new application
---------------------------
-
-When you installed `LAX`, you saw a directory named ``skel``. Make a copy of
-this directory and call it ``BlogDemo``.
-
-Defining a schema
------------------
-
-With `LAX`, the schema/datamodel is the core of the application.
-
-Let us start with something simple and improve on it iteratively. 
-
-In schema.py, we define two entities : ``Blog`` and ``BlogEntry``.
-
-::
-
-  class Blog(EntityType):
-      title = String(maxsize=50, required=True)
-      description = String()
-
-  class BlogEntry(EntityType):
-      title = String(maxsize=100, required=True)
-      publish_date = Date(default='TODAY')
-      text = String(fulltextindexed=True)
-      category = String(vocabulary=('important','business'))
-      entry_of = SubjectRelation('Blog', cardinality='?*')
-
-A Blog has a title and a description. The title is a string that is
-required and must be less than 50 characters. The description is a
-string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a text. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The text is a string that will be indexed in
-the full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that link it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-Using the application
----------------------
-
-Defining this simple schema is enough to get us started. Make sure you
-followed the setup steps described in detail in the installation
-chapter (especially visiting http://localhost:8080/_load as an
-administrator), then launch the application with the command::
-
-   python dev_appserver.py BlogDemo
-
-and point your browser at http://localhost:8080/ (if it is easier for
-you, use the on-line demo at http://lax.appspot.com/).
-
-.. image:: images/lax-book.00-login.en.png
-   :alt: login screen
-
-After you log in, you will see the home page of your application. It
-lists the entity types: Blog and BlogEntry. If these links read
-``blog_plural`` and ``blogentry_plural`` it is because
-internationalization (i18n) is not working for you yet. Please ignore
-this for now.
-
-.. image:: images/lax-book.01-start.en.png
-   :alt: home page
-
-Let us create a few of these entities. Click on the [+] at the right
-of the link Blog.  Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the
-form by clicking on ``button_ok``.
-
-.. image:: images/lax-book.02-create-blog.en.png
-   :alt: from to create blog
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link.  You should be seeing a list with a single item
-``Tech-blog``.
-
-.. image:: images/lax-book.03-list-one-blog.en.png
-   :alt: displaying a list of a single blog
-
-Clicking on this item will get you to its detailed description except
-that in this case, there is not much to display besides the name and
-the phrase ``everything about technology``.
-
-.. image:: images/lax-book.04-detail-one-blog.en.png
-   :alt: displaying the detailed view of a blog
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-.. image:: images/lax-book.05-list-two-blog.en.png
-   :alt: displaying a list of two blogs
-
-Get back to the home page and click on [+] at the right of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``button_ok``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``. 
-
-.. image:: images/lax-book.06-add-relation-entryof.en.png
-   :alt: editing a blog entry to add a relation to a blog
-
-Validate the changes by clicking ``button_ok``. The entity BlogEntry
-that is displayed now includes a link to the entity Blog named
-``MyLife``.
-
-.. image:: images/lax-book.07-detail-one-blogentry.en.png
-   :alt: displaying the detailed view of a blogentry
-
-Remember that all of this was handled by the framework and that the
-only input that was provided so far is the schema. To get a graphical
-view of the schema, run the ``laxctl genschema BlogDemo`` command as
-explained in the installation section and point your browser to the
-URL http://localhost:8080/schema
-
-.. image:: images/lax-book.08-schema.en.png
-   :alt: graphical view of the schema (aka data-model)
-
-Set-up a workflow
------------------
-
-Before starting, make sure you refresh your mind by reading [link to
-definition_workflow chapter].
-
-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 needs to
-be in the state `published`. To move from `submitted` to `published`
-we need a transition that we can name `approve_blogentry`.
-
-We do not want every user to be allowed to change the state of a 
-BlogEntry. We need to define a group of user, `moderators`, and 
-this group will have appropriate permissions to approve BlogEntry
-to be published and visible to all.
-
-Create states and transitions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Let us create a state `submitted`. Click on the [+] at the right
-of the link States.  Call this new Blog ``submitted`` and type in
-``Initial State of a BlogEntry`` as the description, then validate the
-form by clicking on ``Apply``. This will leave us in the editing form
-with an additional section to create the relations related to the
-entity State we juste created. Select the relation ``initial_state_of``
-and select the entity type ``BlogEntry``.
-
-.. image:: images/lax-book.03-state-submitted.en.png
-
-
-
-
-Create group and set permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-
-Change view permission
-~~~~~~~~~~~~~~~~~~~~~~
-
-
-Conclusion
-----------
-
-Exercise
-~~~~~~~~
-
-Create new blog entries in ``Tech-blog``.
-
-What we learned
-~~~~~~~~~~~~~~~
-
-Creating a simple schema was enough to set up a new application that
-can store blogs and blog entries. 
-
-What is next ?
-~~~~~~~~~~~~~~
-
-Although the application is fully functionnal, its look is very
-basic. In the following section we will learn to create views to
-customize how data is displayed.
--- a/doc/book/en/03-definition-schema.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Data Model definition (*schema*)
-================================
-
-The schema is the main concept of `LAX` applications as it defines the
-data model we will handle. It is based on entities types already defined
-in the library and others, more specific, we would expect to find in one or
-more Python files under the `schema` directory.
-
-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 relation definition of the
-schema.
-
-
-.. include:: 03-sect-stdlib-schemas.en.txt
-.. include:: 03-sect-definition-schema.en.txt
--- a/doc/book/en/03-sect-definition-schema.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Entity type definition
-----------------------
-
-An entity type is defined by a Python class which inherits `EntityType`. The
-class name correponds to the type name. Then the content of the class contains
-the description of attributes and relations for the defined entity type,
-by example ::
-
-  class Personne(EntityType):
-    """A person with the properties and the relations necessarry for my
-    application"""
-
-    last_name = String(required=True, fulltextindexed=True)
-    first_name = String(required=True, fulltextindexed=True)
-    title = String(vocabulary=('M', 'Mme', 'Mlle'))
-    date_of_birth = Date()
-    works_for = SubjectRelation('Company', cardinality='?*')
-
-* the name of the Python attribute corresponds to the name of the attribute
-  or the relation in `LAX` application.
-
-* all built-in types are available: `String`, `Int`, `Float`,
-  `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
-
-* each entity has at least the following meta-relations:
-
-  - `eid` (`Int`)
-  
-  - `creation_date` (`Datetime`)
-  
-  - `modification_date` (`Datetime`)
-  
-  - `created_by` (`EUser`) (which user created the entity)
-  
-  - `owned_by` (`EUser`) (who does the entity belongs to, by default the 
-     creator but not necessarry and it could have multiple owners)
-     
-  - `is` (`EEType`)
-
-  
-* it is also possible to define relations of type object by using `ObjectRelation`
-  instead of `SubjectRelation`
-
-* the first argument of `SubjectRelation` and `ObjectRelation` gives respectively
-  the object/subject entity type of the relation. This could be:  
-
-  * a string corresponding to an entity type
-
-  * a tuple of string correponding to multiple entities types
-
-  * special string such as follows:
-
-    - "**" : all types of entities
-    - "*" : all types of entities non meta
-    - "@" : all types of meta entities but not system entities (e.g. used for
-      the basis schema description)
-
-* it is possible to use the attribute `meta` to flag an entity type as a `meta`
-  (e.g. used to describe/categorize other entities)
-
-* optional properties for attributes and relations: 
-
-  - `description` : string describing an attribute or a relation. By default
-    this string will be used in the editing form of the entity, which means
-    that it is supposed to help the end-user and should be flagged by the
-    function `_` to be properly internationalized.
-
-  - `constraints` : list of conditions/constraints that the relation needs to
-    satisfy (c.f. `Contraints`_)
-
-  - `cardinality` : two characters string which specify the cardinality of the
-    relation. The first character defines the cardinality of the relation on
-    the subject, the second on the object of the relation. When a relation
-    has multiple possible subjects or objects, the cardinality applies to all
-    and not on a one to one basis (so it must be consistent...). The possible
-    values are inspired from regular expressions syntax:
-
-    * `1`: 1..1
-    * `?`: 0..1
-    * `+`: 1..n
-    * `*`: 0..n
-
-  - `meta` : boolean indicating that the relation is a meta-relation (false by
-    default)
-
-* optionnal 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 
-    attribute in the database (false by default). This is usefull 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 correpond to the RQL keywords `TODAY` and `NOW`.
-  
-  - `vocabulary` : specify static possible values of an attribute
-
-* optionnal 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`
-    as well*)
-
-  - `internationalizable` : boolean indicating if the value of the attribute
-    is internationalizable (false by default)
-
-  - `maxsize` : integer providing the maximum size of the string (no limit by default)
-
-* optionnal 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 need
-    to set 'object' as the value. The composition implies that when the relation
-    is deleted (so when the composite is deleted), the composed are also deleted.
-    [PAS CLAIR]
-  
-Contraints
-``````````
-By default, the available constraints types are:
-
-* `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 
-  numeric types
-
-* `UniqueConstraint` : identical to "unique=True"
-
-* `StaticVocabularyConstraint` : identical to "vocabulary=(...)"
-
-* `RQLConstraint` : allows to specify a RQL query that needs 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 
-  relation.
-
-* `RQLVocabularyConstraint` : similar to the previous type of constraint except
-  that it does not express a "strong" constraint, which means it is only used to
-  restrict the values listed in the drop-down menu of editing form, but it does
-  not prevent another entity to be selected
-  [PAS CLAIR]
-
-
-Relation type definition
-------------------------
-
-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, as well as 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 
-definition properties from the relation)[PAS CLAIR] by example ::
-
-  class locked_by(RelationType):
-    """relation on all entities indicating that they are locked"""
-    inlined = True
-    cardinality = '?*'
-    subject = '*'
-    object = 'EUser'
-
-In addition to the permissions, the own properties of the relation types
-(shared also by all definition of relation of this type) are:
-
-
-* `inlined` : boolean handling the physical optimization for archiving
-  the relation in the subject entity table, instead of creating a specific
-  table for the relation. This applies to the relation when the cardinality
-  of subject->relation->object is 0..1 ('?') or 1..1 ('1')
-
-* `symetric` : boolean indication that the relation is symetrical, which
-  means `X relation Y` implies `Y relation X`
-
-In the case of simultaneous relations definitions, `subject` and `object`
-can both be equal to the value of the first argument of `SubjectRelation`
-and `ObjectRelation`.
-
-When a relation is not inlined and not symetrical, and it does not require
-specific permissions, its definition (by using `SubjectRelation` and
-`ObjectRelation`) is all we need.
-
-Permissions definition
-----------------------
-
-Define permissions is set through to the attribute `permissions` of entities and
-relations types. It defines a dictionnary where the keys are the access types
-(action), and the values are the authorized groups or expressions.
-
-For an entity type, the possible actions are `read`, `add`, `update` and
-`delete`.
-
-For a relation type, the possible actions are `read`, `add`, and `delete`.
-
-For each access type, a tuple indicates the name of the authorized groups and/or
-one or multiple RQL expressions to satisfy to grant access. The access is
-provided once the user is in the listed groups or one of the RQL condition is
-satisfied.
-
-The standard groups are:
-
-* `guests`
-
-* `users`
-
-* `managers`
-
-* `owners` : virtual group corresponding to the entity's owner.
-  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 define in the precreate 
-of the application (``migration/precreate.py``).
-
-Use of RQL expression for writing rights
-````````````````````````````````````````
-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:
-
-* you have to use the class `ERQLExpression`
-
-* the used expression corresponds to the WHERE statement of an RQL query
-
-* in this expression, the variables X and U are pre-defined references
-  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 
-  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 
-
-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
-  [WHAT IS A NON FINALE RELATION]
-
-* in the expression, the variables S, O and U are pre-defined references
-  to respectively the subject and the object of the current relation (on
-  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: 
-
-  - to defines RQL expression, we have to use the class `ERQLExpression`
-    in which X represents the entity the attribute belongs to
-
-  - the permissions `add` and `delete` are equivalent. Only `add`/`read`
-    are actually taken in consideration.
-
-
-
-In addition to thatm the entity type `EPermission` from the standard library
-allow to build very complex and dynamic security architecture. The schema of
-this entity type is as follow: ::
-
-    class EPermission(MetaEntityType):
-	"""entity type that may be used to construct some advanced security configuration
-	"""
-	name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
-	require_group = SubjectRelation('EGroup', cardinality='+*',
-					description=_('groups to which the permission is granted'))
-	require_state = SubjectRelation('State',
-				    description=_("entity'state in which the permission is applyable"))
-	# can be used on any entity
-	require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
-					    description=_("link a permission to the entity. This "
-							  "permission should be used in the security "
-							  "definition of the entity's type to be useful."))
-
-
-Example of configuration ::
-
-    ...
-
-    class Version(EntityType):
-	"""a version is defining the content of a particular project's release"""
-
-	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'),)}
-
-    ...
-
-    class version_of(RelationType):
-	"""link a version to its project. A version is necessarily linked to one and only one project.
-	"""
-	permissions = {'read':   ('managers', 'users', 'guests',),
-		       'delete': ('managers', ),
-		       'add':    ('managers', 'logilab',
-				  RRQLExpression('O require_permission P, P name "add_version",'
-						 'U in_group G, P require_group G'),)
-		       }
-	inlined = True
-
-This configuration assumes/indicates [???] that an entity `EPermission` named
-"add_version" can be associated to a project and provides rights to create
-new versions on this project to specific groups. It is important to notice that:
-
-* in such case, we have to protect both the entity type "Version" and the relation
-  associating a version to a project ("version_of")
-
-* because of the genricity of the entity type `EPermission`, we have to execute
-  a unification with the groups and/or the states if necessary in the expression
-  ("U in_group G, P require_group G" in the above example)
-
-
-Use of RQL expression for reading rights
-````````````````````````````````````````
-
-The principles are the same but with the following restrictions:
-
-* we can not [??] `RRQLExpression` on relation types for reading
-
-* special relations "has_<ACTION>_permission" can not be used
-
-
-Note on the use of RQL expression for `add` permission
-``````````````````````````````````````````````````````
-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 
-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 checks 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.
-[PAS CLAIR]
--- a/doc/book/en/03-sect-stdlib-schemas.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Pre-defined schemas in the library
-----------------------------------
-
-The library defines a set of entities schemas that are required by the system
-or commonly used in `LAX` applications.
-Of course, you can extend those schemas if necessarry.
-
-System schemas
-``````````````
-Those are defined in::
-
-  ./myapp/ginco/schemas/
-  ./myapp/ginco/entities/
-
-``schemas/`` defines the data model you will use in your application. 
-It allows you to describre the entities and the relations you will need.
-
-``entities/`` deifnes the methods you might need on the entities you 
-defined in your schema.
-
-The system entities available are:
-
-* `EUser`, system users
-* `EGroup`, users groups
-* `EEType`, entity type
-* `ERType`, relation type
-
-* `State`, workflow state
-* `Transition`, workflow transition
-* `TrInfo`, record of a transition trafic for an entity 
-
-* `EmailAddress`, email address, used by the system to send notifications
-  to the users and also used by others optionnals schemas
-
-* `EProperty`, used to configure the application
-* `EPermission`, used to configure the security of the application
-
-* `Card`, generic documenting card
-* `Bookmark`, an entity type used to allow a user to customize his links within
-  the application
-
-
-Components in the library
-`````````````````````````
-
-Those are defined in::
-
-  ./myapp/ginco-apps/
-
-An application is based on several basic components. In the set of available
-basic components we can find by example:
-
-* `ecomment`, provides an entity type for `Comment` allowing us to comment others
-  site's entities
-
-* `emailinglist`, provides an entity type for `Mailinglist` which groups informations
-  in a discussion list
-
-* `efile`, provides entity types for `File` et `Image` used to represent
-  files (text or binary) with additionnal informations such as MIME type or
-  encoding.
-  
-* `elink`, provides an entity type for hypertext link (`Link`)
-
-* `eblog`, provides an entity type weblog (`Blog`)
-
-* `eperson`, provides an entity type for a person (`Person`)
-
-* `eaddressbook`, provides an entity type used to represent phone 
-  numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
-  
-* `eclasstags`, categorization system based on tags (`Tag`)
-
-* `eclassfolders`, categorization system based on folders hierarchy in order 
-  to create navigation sections (`Folder`)
-
-* `eemail`, archiving management for emails (`Email`, `Emailpart`,
-  `Emailthread`)
-
-* `ebasket`, basket management (`Basket`) allowing to group entities
-
-To declare the use of a component, once installed, add the name of the component
-to the variable `__use__` in the file `__pkginfo__.py` of your own component.
-
--- a/doc/book/en/03-setup.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _MiseEnPlaceEnv:
-
-===================================================
-Installation and set-up of a `CubicWeb` environment
-===================================================
-.. contents::
-
-.. include:: 03-01-installation.en.txt
-.. include:: 03-02-create-instance.en.txt
-.. include:: 03-03-cubicweb-ctl.en.txt
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/04-00-define-schema.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,22 @@
+.. -*- coding: utf-8 -*-
+
+Data model definition (*schema*)
+================================
+
+The schema is the core piece of a `CubicWeb` application as it defines
+the data model handled. It is based on entities types already defined
+in the `CubicWeb` standard library and others, more specific, we would 
+expect to find in one or more Python files under the `schema` directory.
+
+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 
+relation definition of the schema.
+
+
+.. include:: 04-01-schema-stdlib.en.txt
+.. include:: 04-02-schema-definition.en.txt
+
--- a/doc/book/en/04-02-schema-definition.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ b/doc/book/en/04-02-schema-definition.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -146,8 +146,10 @@
   not prevent another entity to be selected
 
 
-Relation type definition
-------------------------
+Relation definition
+-------------------
+
+XXX add note about defining relation type / definition
 
 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
@@ -183,8 +185,46 @@
 specific permissions, its definition (by using `SubjectRelation` and
 `ObjectRelation`) is all we need.
 
+
+The security model
+------------------
+
+Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
+Control List`. Les notions sont les suivantes :
+
+* utilisateurs et groupes d'utilisateurs
+* un utilisateur appartient à au moins un groupe
+* droits (lire, modifier, créer, supprimer) 
+* les droits sont attribués aux groupes (et non aux utilisateurs)
+
+Pour CubicWeb plus spécifiquement :
+
+* on associe les droits au niveau des schemas d'entites / relations
+
+* pour chaque type d'entité, on distingue les droits de lecture,
+  ajout, modification et suppression
+  
+* pour chaque type de relation, on distingue les droits de lecture,
+  ajout et suppression (on ne peut pas modifer une relation)
+  
+* les groupes de base sont : Administrateurs, Utilisateurs, Invités
+
+* les utilisateurs font par défaut parti du groupe Utilisateurs
+
+* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
+  associer uniquement les droits de suppression et de modification
+  
+* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
+  ajoutés implicitement dans le contexte des objets dont ils sont
+  propriétaires
+  
+* les droits de ce groupe ne sont vérifiés que sur
+  modification / suppression si tous les autres groupes auxquels
+  l'utilisateur appartient se sont vu interdir l'accès
+
+  
 Permissions definition
-----------------------
+``````````````````````
 
 Define permissions is set through to the attribute `permissions` of entities and
 relations types. It defines a dictionnary where the keys are the access types
@@ -212,11 +252,12 @@
   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 define in the precreate 
-of the application (``migration/precreate.py``).
+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 
 (`add`, `delete` and `update`) on relation and entity types.
 
@@ -314,7 +355,7 @@
   ("U in_group G, P require_group G" in the above example)
 
 Use of RQL expression for reading rights
-````````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The principles are the same but with the following restrictions :
 
@@ -324,7 +365,7 @@
 
 
 Note on the use of RQL expression for `add` permission
-``````````````````````````````````````````````````````
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 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 
--- a/doc/book/en/04-define-schema.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Data model definition (*schema*)
-================================
-
-The schema is the core piece of a `CubicWeb` application as it defines
-the data model handled. It is based on entities types already defined
-in the `CubicWeb` standard library and others, more specific, we would 
-expect to find in one or more Python files under the `schema` directory.
-
-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 
-relation definition of the schema.
-
-
-.. include:: 04-01-schema-stdlib.en.txt
-.. include:: 04-02-schema-definition.en.txt
-
--- a/doc/book/en/04-develop-views.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Developing the user interface with Views
-========================================
-
-Before moving to this section, make sure you read the `Essentials`
-section in the Introduction.
-
-Tip: when modifying views, you do not need to restart the local 
-server. Just save the file in your editor and reload the page in your
-browser to see the changes.
-
-The selection/view principle
-----------------------------
-
-With `LAX`, views are defined by Python classes. A view includes:
-
-- an identifier (all objects in `LAX` are entered in a registry
-  and this identifier will be used as a key)
-  
-- a filter to select the resulsets it can be applied to
-
-`LAX` provides a lot of standard views, for a complete list, you
-will have to read the code in directory ``ginco/web/views/`` (XXX
-improve doc).
-
-For example, the view named ``primary`` is the one used to display
-a single entity.
-
-If you want to change the way a ``BlogEntry`` is displayed, just
-override the view ``primary`` in ``BlogDemo/views.py`` ::
-
-  01. from ginco.web.views import baseviews
-  02.
-  03. class BlogEntryPrimaryView(baseviews.PrimaryView):
-  04.
-  05.     accepts = ('BlogEntry',)
-  06.
-  07.     def cell_call(self, row, col):
-  08.         entity = self.entity(row, col)
-  09.         self.w(u'<h1>%s</h1>' % entity.title)
-  10.         self.w(u'<p>published on %s in category %s</p>' % \
-  11.                (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
-  12.         self.w(u'<p>%s</p>' % entity.text)
-
-The above source code defines a new primary view (`line 03`) for
-``BlogEntry`` (`line 05`). 
-
-Since views are applied to resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates (`line 08`). We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. Here `lines
-09-12` output HTML tags and values of the entity's attributes.
-
-When displaying same blog entries as before, you will notice that the
-page is now looking much nicer.
-
-.. image:: images/lax-book.09-new-view-blogentry.en.png
-   :alt: blog entries now look much nicer
-
-Let us now improve the primary view of a blog ::
-
-  01. class BlogPrimaryView(baseviews.PrimaryView):
-  02. 
-  03.     accepts = ('Blog',)
-  04.
-  05.     def cell_call(self, row, col):
-  06.         entity = self.entity(row, col)
-  07.         self.w(u'<h1>%s</h1>' % entity.title)
-  08.         self.w(u'<p>%s</p>' % entity.description)
-  09.         rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
-  10.         self.wview('primary', rset)
-
-In the above source code, `lines 01-08` are similar to the previous
-view we defined.
-
-At `line 09`, a simple request in made to build a resultset with all
-the entities linked to the current ``Blog`` entity by the relationship
-``entry_of``. The part of the framework handling the request knows
-about the schema and infer that such entities have to be of the
-``BlogEntry`` kind and retrieves them.
-
-The request returns a selection of data called a resultset. At 
-`line 10` the view 'primary' is applied to this resultset to output
-HTML. 
-
-**This is to be compared to interfaces and protocols in object-oriented
-languages. Applying a given view to all the entities of a resultset only
-requires the availability, for each entity of this resultset, of a
-view with that name that can accepts the entity.**
-
-Assuming we added entries to the blog titled `MyLife`, displaying it
-now allows to read its description and all its entries.
-
-.. image:: images/lax-book.10-blog-with-two-entries.en.png
-   :alt: a blog and all its entries
-
-**Before we move forward, remember that the selection/view principle is
-at the core of `LAX`. Everywhere in the engine, data is requested
-using the RQL language, then HTML/XML/text/PNG is output by applying a
-view to the resultset returned by the query. That is where most of the
-flexibility comes from.**
-
-[WRITE ME]
-
-* implementing interfaces, calendar for blog entries
-* show that a calendar view can export data to ical
-
-We will implement the ginco.interfaces.ICalendarable interfaces on
-entities.BloEntry and apply the OneMonthCalendar and iCalendar views
-to resultsets like "Any E WHERE E is BlogEntry"
-
-* create view "blogentry table" with title, publish_date, category
-
-We will show that by default the view that displays 
-"Any E,D,C WHERE E publish_date D, E category C" is the table view.
-Of course, the same can be obtained by calling
-self.wview('table',rset)
-
-* in view blog, select blogentries and apply view "blogentry table"
-* demo ajax by filtering blogentry table on category
-
-we did the same with 'primary', but with tables we can turn on filters
-and show that ajax comes for free.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/05-00-define-views.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,238 @@
+.. -*- coding: utf-8 -*-
+
+.. _DefinitionVues:
+
+Views definition
+================
+
+Basic class for views
+---------------------
+
+Class `View` (`cubicweb.common.view`)
+`````````````````````````````````````
+
+A view writes in its output exit thanks to its attribute `w` (`UStreamIO`).
+
+The basic interface for views is as follows:
+
+* `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
+* `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 
+  `__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`
+
+* `creator(eid)`, returns the eid and the login of the entity creator of the entity
+  having the eid given in the parameter 
+
+Other basic classes:
+
+* `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 
+
+
+The selection view principle
+----------------------------
+
+A view includes :
+
+- an identifier (all objects in `LAX` are entered in a registry
+  and this identifier will be used as a key)
+  
+- a filter to select the resulsets it can be applied to
+
+
+For a given identifier, multiple views can be defined. `CubicWeb` uses
+a selector which computes scores so that it can identify and select the
+best view to apply in context. The selector library is in 
+``cubicweb.common.selector`` and a library of the methods used to
+compute scores is in ``cubicweb.vregistry.vreq``.
+
+
+`CubicWeb` provides a lot of standard views, for a complete list, you
+will have to read the code in directory ``cubicweb/web/views/`` (XXX
+improve doc).
+
+For example, the view named ``primary`` is the one used to display
+a single entity.
+
+If you want to change the way a ``BlogEntry`` is displayed, just
+override the view ``primary`` in ``BlogDemo/views.py`` ::
+
+  01. from ginco.web.views import baseviews
+  02.
+  03. class BlogEntryPrimaryView(baseviews.PrimaryView):
+  04.
+  05.     accepts = ('BlogEntry',)
+  06.
+  07.     def cell_call(self, row, col):
+  08.         entity = self.entity(row, col)
+  09.         self.w(u'<h1>%s</h1>' % entity.title)
+  10.         self.w(u'<p>published on %s in category %s</p>' % \
+  11.                (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
+  12.         self.w(u'<p>%s</p>' % entity.text)
+
+The above source code defines a new primary view (`line 03`) for
+``BlogEntry`` (`line 05`). 
+
+Since views are applied to resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates (`line 08`). We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. Here `lines
+09-12` output HTML tags and values of the entity's attributes.
+
+When displaying same blog entry as before, you will notice that the
+page is now looking much nicer.
+
+.. image:: images/lax-book.09-new-view-blogentry.en.png
+   :alt: blog entries now look much nicer
+
+Let us now improve the primary view of a blog ::
+
+  01. class BlogPrimaryView(baseviews.PrimaryView):
+  02. 
+  03.     accepts = ('Blog',)
+  04.
+  05.     def cell_call(self, row, col):
+  06.         entity = self.entity(row, col)
+  07.         self.w(u'<h1>%s</h1>' % entity.title)
+  08.         self.w(u'<p>%s</p>' % entity.description)
+  09.         rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
+  10.         self.wview('primary', rset)
+
+In the above source code, `lines 01-08` are similar to the previous
+view we defined.
+
+At `line 09`, a simple request in made to build a resultset with all
+the entities linked to the current ``Blog`` entity by the relationship
+``entry_of``. The part of the framework handling the request knows
+about the schema and infer that such entities have to be of the
+``BlogEntry`` kind and retrieves them.
+
+The request returns a selection of data called a resultset. At 
+`line 10` the view 'primary' is applied to this resultset to output
+HTML. 
+
+**This is to be compared to interfaces and protocols in object-oriented
+languages. Applying a given view to all the entities of a resultset only
+requires the availability, for each entity of this resultset, of a
+view with that name that can accepts the entity.**
+
+Assuming we added entries to the blog titled `MyLife`, displaying it
+now allows to read its description and all its entries.
+
+.. image:: images/lax-book.10-blog-with-two-entries.en.png
+   :alt: a blog and all its entries
+
+**Before we move forward, remember that the selection/view principle is
+at the core of `CubicWeb`. Everywhere in the engine, data is requested
+using the RQL language, then HTML/XML/text/PNG is output by applying a
+view to the resultset returned by the query. That is where most of the
+flexibility comes from.**
+
+[WRITE ME]
+
+* implementing interfaces, calendar for blog entries
+* show that a calendar view can export data to ical
+
+We will implement the cubicwweb.interfaces.ICalendarable interfaces on
+entities.BloEntry and apply the OneMonthCalendar and iCalendar views
+to resultsets like "Any E WHERE E is BlogEntry"
+
+* create view "blogentry table" with title, publish_date, category
+
+We will show that by default the view that displays 
+"Any E,D,C WHERE E publish_date D, E category C" is the table view.
+Of course, the same can be obtained by calling
+self.wview('table',rset)
+
+* in view blog, select blogentries and apply view "blogentry table"
+* demo ajax by filtering blogentry table on category
+
+we did the same with 'primary', but with tables we can turn on filters
+and show that ajax comes for free.
+[FILLME]
+
+
+Templates
+---------
+
+*Templates* are specific view that does not depend on a result set. The basic
+class `Template` (`cubicweb.common.view`) is derived from the class `View`.
+
+To build a HTML page, a *main template* is used. In general, the template of
+identifier `main` is the one (it is not used in case an error is raised or for
+the login form by example). This template uses other templates in addition
+to the views which depends on the content to generate the HTML page to return.
+
+A *template* is responsible for:
+
+1. executing RQL query of data to render if necessarry
+2. identifying the view to use to render data if it is not specified
+3. composing the HTML page to return
+
+
+The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
+------------------------------------------------------------------------------
+
+The default main template build the page based on the following pattern:
+
+.. image:: images/main_template_layout.png
+
+The rectangle containing `view.dispathc()` represents the area where the content
+view has to be displayed. The others represents sub-templates called to complete
+the page. A default implementation of those is provided in 
+`cubicweb.views.basetemplates`. You can, of course, overload those sub-templates
+to implement your own customization of the HTML page.
+
+We can also control certain aspects of the main template thanks to the following
+forms parameters:
+
+* `__notemplate`, if present (whatever the value assigned), only the content view
+  is returned
+* `__force_display`, if present and its value is not null, no navigation 
+  whatever the number of entities to display
+* `__method`, if the result set to render contains only one entity and this 
+  parameter is set, it refers to a method to call on the entity by passing it
+  the dictionnary of the forms parameters, before going the classic way (through
+  step 1 and 2 described juste above)
+
+.. include:: 05-01-views-stdlib.en.txt
+
+
+XML views, binaries...
+----------------------
+For the views generating other formats that HTML (an image generated dynamically
+by example), and which can not usually be included in the HTML page generated
+by the main template (see above), you have to:
+
+* set the atribute `templatable` of the class to `False`
+* set, through the attribute `content_type` of the class, the MIME type generated
+  by the view to `application/octet-stream`
+
+For the views dedicated to binary content creation (an image dynamically generated
+by example), we have to set the attribute `binary` of the class to `True` (which
+implies that `templateable == False`, so that the attribute `w` of the view could be
+replaced by a binary flow instead of unicode).
+
+(X)HTML tricks to apply
+-----------------------
+
+Some web browser (Firefox by example) are not happy with empty `<div>`
+(by empty we mean that there is no content in the tag, but there
+could be attributes), so we should always use `<div></div>` even if
+it is empty and not use `<div/>`.
+
--- a/doc/book/en/05-components.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _components:
-
-Components
-===========
-
-What is a component
--------------------
-
-A component is a model grouping one or more entity types and/or views associated
-in order to provide a specific feature or even a complete application using
-others components.
-You can decide to write your own set of components if you wish to re-use the 
-entity types you develop. By default, LAX comes with its owns set of components
-that you can start using right away.
-
-
-Standard library
-----------------
-
-A library of standard components is part of the `LAX` release (look at
-``lax/skel/ginco-apps``). Components provide entities and views. With
-``lax-0.4``, you should get a set of application entities and system
-entities you can re-use.
-
-The available application entities are:
-
-* addressbook: PhoneNumber and PostalAddress
-
-* ebasket: Basket (like a shopping cart)
-
-* eblog: Blog (a *very* basic blog)
-
-* eclassfolder: Folder (to organize things but grouping them in folders)
-
-* eclasstags: Tag (to tag anything)
-
-
-* efile: File (to allow users to upload and store binary or text files)
-
-* elink: Link (to collect links to web resources)
-
-* emailinglist: MailingList (to reference a mailing-list and the URLs
-  for its archives and its admin interface)
-
-* eperson: Person (easily mixed with addressbook)
-
-* etask: Task (something to be done between start and stop date)
-
-* ezone: Zone (to define places within larger places, for example a
-  city in a state in a country)
-
-The available system entities are:
-
-* ecomment: Comment (to attach comment threads to entities)
-
-
-
-Adding comments to BlogDemo
----------------------------
-
-To import a component in your application just change the line in the
-``app.conf`` file. For example::
-
-    included-yams-components=ecomment
-
-will make the ``Comment`` entity available in your ``BlogDemo``
-application.
-
-Change the schema to add a relationship between ``BlogEntry`` and
-``Comment`` and you are done. Since the ecomment component defines the
-``comments`` relationship, adding the line::
-
-    comments = ObjectRelation('Comment', cardinality='1*', composite='object')
-
-to the definition of a ``BlogEntry`` will be enough.
-
-Clear the datastore and restart.
-
-Component structure
--------------------
-
-A complex component is structured as follows:
-::
-
-  mycomponent/
-  |
-  |-- schema.py
-  |
-  |-- entities/
-  |
-  |-- sobjects/
-  |
-  |-- views/
-  |
-  |-- test/
-  |
-  |-- i18n/
-  |
-  |-- data/
-  |
-  |-- migration/
-  | |- postcreate.py
-  | \- depends.map
-  |
-  |-- debian/
-  |
-  \-- __pkginfo__.py
-
-We can also define simple Python module instead of directories (packages), for example:
-::
-
-  mycomponent/
-  |
-  |-- entities.py
-  |-- hooks.py
-  \-- views.py
-
-
-where:
-
-* ``schema`` contains the definition of the schema (server side only)
-* ``entities`` contains entities definition (server side and web interface)
-* ``sobjects`` contains hooks and/or notification views (server side only)
-* ``views`` contains the web interface components (web interface only)
-* ``test`` contains tests related to the application (not installed)
-* ``i18n`` contains messages catalogs for supported languages (server side and
-  web interface)
-* ``data`` contains data files for static content (images, css, javascripts)
-  ...(web interface only)
-* ``migration`` contains initialization file for new instances (``postcreate.py``)
-  and a file containing dependencies of the component depending on the version
-  (``depends.map``)
-* ``debian`` contains all the files managing debian packaging (you will find
-  the usual files ``control``, ``rules``, ``changelog``... not installed)
-* file ``__pkginfo__.py`` provides component meta-data, especially the distribution
-  and the current version(server side and web interface) or sub-components used by
-  the component.
- 
-At least you should have:
-
-* the file ``__pkginfo__.py``
-* schema definition
-
-[WRITE ME]
-
-* explain the component architecture
-
-* add comments to the blog by importing the comments component
--- a/doc/book/en/05-define-views.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _DefinitionVues:
-
-Views definition
-================
-
-Basic class for views
----------------------
-
-Class `View` (`cubicweb.common.view`)
-`````````````````````````````````````
-
-A view writes in its output exit thanks to its attribute `w` (`UStreamIO`).
-
-The basic interface for views is as follows:
-
-* `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
-* `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 
-  `__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`
-
-* `creator(eid)`, returns the eid and the login of the entity creator of the entity
-  having the eid given in the parameter 
-
-Other basic classes:
-
-* `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 
-
-
-The selection view principle
-----------------------------
-
-A view includes :
-
-- an identifier (all objects in `LAX` are entered in a registry
-  and this identifier will be used as a key)
-  
-- a filter to select the resulsets it can be applied to
-
-
-For a given identifier, multiple views can be defined. `CubicWeb` uses
-a selector which computes scores so that it can identify and select the
-best view to apply in context. The selector library is in 
-``cubicweb.common.selector`` and a library of the methods used to
-compute scores is in ``cubicweb.vregistry.vreq``.
-
-
-`CubicWeb` provides a lot of standard views, for a complete list, you
-will have to read the code in directory ``cubicweb/web/views/`` (XXX
-improve doc).
-
-For example, the view named ``primary`` is the one used to display
-a single entity.
-
-If you want to change the way a ``BlogEntry`` is displayed, just
-override the view ``primary`` in ``BlogDemo/views.py`` ::
-
-  01. from ginco.web.views import baseviews
-  02.
-  03. class BlogEntryPrimaryView(baseviews.PrimaryView):
-  04.
-  05.     accepts = ('BlogEntry',)
-  06.
-  07.     def cell_call(self, row, col):
-  08.         entity = self.entity(row, col)
-  09.         self.w(u'<h1>%s</h1>' % entity.title)
-  10.         self.w(u'<p>published on %s in category %s</p>' % \
-  11.                (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
-  12.         self.w(u'<p>%s</p>' % entity.text)
-
-The above source code defines a new primary view (`line 03`) for
-``BlogEntry`` (`line 05`). 
-
-Since views are applied to resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates (`line 08`). We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. Here `lines
-09-12` output HTML tags and values of the entity's attributes.
-
-When displaying same blog entry as before, you will notice that the
-page is now looking much nicer.
-
-.. image:: images/lax-book.09-new-view-blogentry.en.png
-   :alt: blog entries now look much nicer
-
-Let us now improve the primary view of a blog ::
-
-  01. class BlogPrimaryView(baseviews.PrimaryView):
-  02. 
-  03.     accepts = ('Blog',)
-  04.
-  05.     def cell_call(self, row, col):
-  06.         entity = self.entity(row, col)
-  07.         self.w(u'<h1>%s</h1>' % entity.title)
-  08.         self.w(u'<p>%s</p>' % entity.description)
-  09.         rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
-  10.         self.wview('primary', rset)
-
-In the above source code, `lines 01-08` are similar to the previous
-view we defined.
-
-At `line 09`, a simple request in made to build a resultset with all
-the entities linked to the current ``Blog`` entity by the relationship
-``entry_of``. The part of the framework handling the request knows
-about the schema and infer that such entities have to be of the
-``BlogEntry`` kind and retrieves them.
-
-The request returns a selection of data called a resultset. At 
-`line 10` the view 'primary' is applied to this resultset to output
-HTML. 
-
-**This is to be compared to interfaces and protocols in object-oriented
-languages. Applying a given view to all the entities of a resultset only
-requires the availability, for each entity of this resultset, of a
-view with that name that can accepts the entity.**
-
-Assuming we added entries to the blog titled `MyLife`, displaying it
-now allows to read its description and all its entries.
-
-.. image:: images/lax-book.10-blog-with-two-entries.en.png
-   :alt: a blog and all its entries
-
-**Before we move forward, remember that the selection/view principle is
-at the core of `CubicWeb`. Everywhere in the engine, data is requested
-using the RQL language, then HTML/XML/text/PNG is output by applying a
-view to the resultset returned by the query. That is where most of the
-flexibility comes from.**
-
-[WRITE ME]
-
-* implementing interfaces, calendar for blog entries
-* show that a calendar view can export data to ical
-
-We will implement the cubicwweb.interfaces.ICalendarable interfaces on
-entities.BloEntry and apply the OneMonthCalendar and iCalendar views
-to resultsets like "Any E WHERE E is BlogEntry"
-
-* create view "blogentry table" with title, publish_date, category
-
-We will show that by default the view that displays 
-"Any E,D,C WHERE E publish_date D, E category C" is the table view.
-Of course, the same can be obtained by calling
-self.wview('table',rset)
-
-* in view blog, select blogentries and apply view "blogentry table"
-* demo ajax by filtering blogentry table on category
-
-we did the same with 'primary', but with tables we can turn on filters
-and show that ajax comes for free.
-[FILLME]
-
-
-Templates
----------
-
-*Templates* are specific view that does not depend on a result set. The basic
-class `Template` (`cubicweb.common.view`) is derived from the class `View`.
-
-To build a HTML page, a *main template* is used. In general, the template of
-identifier `main` is the one (it is not used in case an error is raised or for
-the login form by example). This template uses other templates in addition
-to the views which depends on the content to generate the HTML page to return.
-
-A *template* is responsible for:
-
-1. executing RQL query of data to render if necessarry
-2. identifying the view to use to render data if it is not specified
-3. composing the HTML page to return
-
-
-The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
-------------------------------------------------------------------------------
-
-The default main template build the page based on the following pattern:
-
-.. image:: images/main_template_layout.png
-
-The rectangle containing `view.dispathc()` represents the area where the content
-view has to be displayed. The others represents sub-templates called to complete
-the page. A default implementation of those is provided in 
-`cubicweb.views.basetemplates`. You can, of course, overload those sub-templates
-to implement your own customization of the HTML page.
-
-We can also control certain aspects of the main template thanks to the following
-forms parameters:
-
-* `__notemplate`, if present (whatever the value assigned), only the content view
-  is returned
-* `__force_display`, if present and its value is not null, no navigation 
-  whatever the number of entities to display
-* `__method`, if the result set to render contains only one entity and this 
-  parameter is set, it refers to a method to call on the entity by passing it
-  the dictionnary of the forms parameters, before going the classic way (through
-  step 1 and 2 described juste above)
-
-.. include:: 05-01-views-stdlib.en.txt
-
-
-XML views, binaries...
-----------------------
-For the views generating other formats that HTML (an image generated dynamically
-by example), and which can not usually be included in the HTML page generated
-by the main template (see above), you have to:
-
-* set the atribute `templatable` of the class to `False`
-* set, through the attribute `content_type` of the class, the MIME type generated
-  by the view to `application/octet-stream`
-
-For the views dedicated to binary content creation (an image dynamically generated
-by example), we have to set the attribute `binary` of the class to `True` (which
-implies that `templateable == False`, so that the attribute `w` of the view could be
-replaced by a binary flow instead of unicode).
-
-(X)HTML tricks to apply
------------------------
-
-Some web browser (Firefox by example) are not happy with empty `<div>`
-(by empty we mean that there is no content in the tag, but there
-could be attributes), so we should always use `<div></div>` even if
-it is empty and not use `<div/>`.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/06-00-define-workflows.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,155 @@
+.. -*- coding: utf-8 -*-
+
+Workflow definition
+======================
+
+On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
+
+Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
+
+Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
+
+Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
+
+* `%(eid)s`, eid de l'objet
+* `%(ueid)s`, eid de l'utilisateur qui fait la requête
+* `%(seid)s`, eid de l'état courant de l'objet
+
+Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
+pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
+
+General
+-------
+
+A workflow can be defined in a `LAX` application thanks to the system 
+entities ``State`` and ``Transition``. Those are defined within all 
+LAX application and can be set-up through the main administrator interface.
+
+Once your schema is defined, you can start creating the set of states and
+the required transitions for your applications entities.
+
+You first need to define the states and then the transitions between those
+to complete your workflow.
+
+A ``State`` defines the status of an entity. While creating a new state, 
+you will be first given the option to select the entity type the state
+can be applied to. By choosing ``Apply``, a new section will be displayed
+in the editing screen to enable you to add relation to the state you are
+creating.
+
+A ``Transition`` is also based on an entity type it can be applied to.
+By choosing ``Apply``, a new section will be displayed in the editing 
+screen to enable you to add relation to the transition you are
+creating.
+
+At the transition level you will also define the group of user which can
+aplly this transition to an object.
+
+
+Example of a simple workflow
+----------------------------
+
+Please see the tutorial to view and example of a simple workflow.
+
+
+[Create a simple workflow for BlogDemo, to have a moderator approve new blog 
+entry to be published. This implies, specify a dedicated group of blog
+moderator as well as hide the view of a blog entry to the user until
+it reaches the state published]
+
+Set-up a workflow
+-----------------
+
+Before starting, make sure you refresh your mind by reading [link to
+definition_workflow chapter].
+
+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 needs to
+be in the state `published`. To move from `submitted` to `published`
+we need a transition that we can name `approve_blogentry`.
+
+We do not want every user to be allowed to change the state of a 
+BlogEntry. We need to define a group of user, `moderators`, and 
+this group will have appropriate permissions to approve BlogEntry
+to be published and visible to all.
+
+There are two ways to create a workflow, form the user interface,
+and also by defining it in ``migration/postcreate.py``. This script
+is executed each time a new ``./bin/laxctl db-init`` is done. 
+If you create the states and transitions through the user interface
+this means that next time you will need to initialize the database
+you will have to re-create all the entities. 
+We strongly recommand you create the workflow in ``migration\postcreate.py``
+and we will now show you how.
+The user interface would only be a reference for you to view the states 
+and transitions but is not the appropriate interface to define your
+application workflow.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+To enable a BlogEntry to have a State, we have to define a relation
+``in_state`` in the schema of BlogEntry. Please do as follows, add
+the line ``in_state (...)``::
+
+  class BlogEntry(EntityType):
+      title = String(maxsize=100, required=True)
+      publish_date = Date(default='TODAY')
+      text_format = String(meta=True, internationalizable=True, maxsize=50,
+                           default='text/rest', constraints=[format_constraint])
+      text = String(fulltextindexed=True)
+      category = String(vocabulary=('important','business'))
+      entry_of = SubjectRelation('Blog', cardinality='?*')
+      in_state = SubjectRelation('State', cardinality='1*')
+
+As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
+to initialize the database and migrate your existing entities.
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time the ``postcreate.py`` script is executed, several methods
+can be used. They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the method we use to create a wrokflow here.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+  
+  _ = unicode
+
+  moderators      = add_entity('EGroup', name=u"moderators")
+
+  submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+  published = add_state(_('published'), 'BlogEntry')
+
+  add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+  checkpoint()
+
+``add_entity`` is used here to define the new group of users that we
+need to define the transitions, `moderators`.
+If this group required by the transition is not defined before the
+transition is created, it will not create the relation `transition 
+require the group moderator`.
+
+``add_state`` expects as the first argument the name of the state you are
+willing to create, then the entity type on which the state can be applied, 
+and an optionnal argument to set if the state is the initial state
+of the entity type or not.
+
+``add_transition`` expects as the first argument the name of the 
+transition, then the entity type on which we can apply the transition,
+then the list of possible initial states from which the transition
+can be applied, the target state of the transition, and the permissions
+(e.g. list of the groups of users who can apply the transition).
+
+.. image:: images/lax-book.03-transitions-view.en.png
+
+You can now notice that in the actions box of a BlogEntry, the state
+is now listed as well as the possible transitions from this state
+defined by the workflow. This transition, as defined in the workflow,
+will only being displayed for the users belonging to the group
+moderators of managers.
+
+
--- a/doc/book/en/06-define-workflows.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Définition de workflow
-======================
-On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
-
-Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
-
-Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
-
-Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
-
-* `%(eid)s`, eid de l'objet
-* `%(ueid)s`, eid de l'utilisateur qui fait la requête
-* `%(seid)s`, eid de l'état courant de l'objet
-
-Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
-pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
-
-General
--------
-
-A workflow can be defined in a `LAX` application thanks to the system 
-entities ``State`` and ``Transition``. Those are defined within all 
-LAX application and can be set-up through the main administrator interface.
-
-Once your schema is defined, you can start creating the set of states and
-the required transitions for your applications entities.
-
-You first need to define the states and then the transitions between those
-to complete your workflow.
-
-A ``State`` defines the status of an entity. While creating a new state, 
-you will be first given the option to select the entity type the state
-can be applied to. By choosing ``Apply``, a new section will be displayed
-in the editing screen to enable you to add relation to the state you are
-creating.
-
-A ``Transition`` is also based on an entity type it can be applied to.
-By choosing ``Apply``, a new section will be displayed in the editing 
-screen to enable you to add relation to the transition you are
-creating.
-
-At the transition level you will also define the group of user which can
-aplly this transition to an object.
-
-
-Example of a simple workflow
-----------------------------
-
-Please see the tutorial to view and example of a simple workflow.
-
-
-[Create a simple workflow for BlogDemo, to have a moderator approve new blog 
-entry to be published. This implies, specify a dedicated group of blog
-moderator as well as hide the view of a blog entry to the user until
-it reaches the state published]
-
-Set-up a workflow
------------------
-
-Before starting, make sure you refresh your mind by reading [link to
-definition_workflow chapter].
-
-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 needs to
-be in the state `published`. To move from `submitted` to `published`
-we need a transition that we can name `approve_blogentry`.
-
-We do not want every user to be allowed to change the state of a 
-BlogEntry. We need to define a group of user, `moderators`, and 
-this group will have appropriate permissions to approve BlogEntry
-to be published and visible to all.
-
-There are two ways to create a workflow, form the user interface,
-and also by defining it in ``migration/postcreate.py``. This script
-is executed each time a new ``./bin/laxctl db-init`` is done. 
-If you create the states and transitions through the user interface
-this means that next time you will need to initialize the database
-you will have to re-create all the entities. 
-We strongly recommand you create the workflow in ``migration\postcreate.py``
-and we will now show you how.
-The user interface would only be a reference for you to view the states 
-and transitions but is not the appropriate interface to define your
-application workflow.
-
-Update the schema
-~~~~~~~~~~~~~~~~~
-To enable a BlogEntry to have a State, we have to define a relation
-``in_state`` in the schema of BlogEntry. Please do as follows, add
-the line ``in_state (...)``::
-
-  class BlogEntry(EntityType):
-      title = String(maxsize=100, required=True)
-      publish_date = Date(default='TODAY')
-      text_format = String(meta=True, internationalizable=True, maxsize=50,
-                           default='text/rest', constraints=[format_constraint])
-      text = String(fulltextindexed=True)
-      category = String(vocabulary=('important','business'))
-      entry_of = SubjectRelation('Blog', cardinality='?*')
-      in_state = SubjectRelation('State', cardinality='1*')
-
-As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
-to initialize the database and migrate your existing entities.
-[WRITE ABOUT MIGRATION]
-
-Create states, transitions and group permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At the time the ``postcreate.py`` script is executed, several methods
-can be used. They are all defined in the ``class ServerMigrationHelper``.
-We will only discuss the method we use to create a wrokflow here.
-
-To define our workflow for BlogDemo, please add the following lines
-to ``migration/postcreate.py``::
-  
-  _ = unicode
-
-  moderators      = add_entity('EGroup', name=u"moderators")
-
-  submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
-  published = add_state(_('published'), 'BlogEntry')
-
-  add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
-
-  checkpoint()
-
-``add_entity`` is used here to define the new group of users that we
-need to define the transitions, `moderators`.
-If this group required by the transition is not defined before the
-transition is created, it will not create the relation `transition 
-require the group moderator`.
-
-``add_state`` expects as the first argument the name of the state you are
-willing to create, then the entity type on which the state can be applied, 
-and an optionnal argument to set if the state is the initial state
-of the entity type or not.
-
-``add_transition`` expects as the first argument the name of the 
-transition, then the entity type on which we can apply the transition,
-then the list of possible initial states from which the transition
-can be applied, the target state of the transition, and the permissions
-(e.g. list of the groups of users who can apply the transition).
-
-.. image:: images/lax-book.03-transitions-view.en.png
-
-You can now notice that in the actions box of a BlogEntry, the state
-is now listed as well as the possible transitions from this state
-defined by the workflow. This transition, as defined in the workflow,
-will only being displayed for the users belonging to the group
-moderators of managers.
-
-
--- a/doc/book/en/06-maintemplate.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Views & Templates
-=================
-
-
-Look at ``lax/skel/ginco/web/views/basetemplates.py`` and you will
-find the base templates used to generate HTML for your application.
-
-A page is composed as indicated on the schema below:
-
-.. image:: images/lax-book.06-main-template-layout.en.png
-
-In this section we will go through a couple of the primary templates
-you must be interested in, that is to say, the HTMLPageHeader,
-the HTMLPageFooter and the TheMainTemplate.
-
-
-HTMLPageHeader
---------------
-
-Let's use a different logo than the default one provided with LAX
-and customize our header.
-
-Change logo
-~~~~~~~~~~~
-
-The easiest way to use a different logo is to replace the existing
-``logo.png`` in ``myapp/data`` by your prefered icon and refresh.
-By default all application will look for a ``logo.png`` to be 
-rendered in the logo section.
-
-.. image:: images/lax-book.06-main-template-logo.en.png
-
-[ADD]
-customized external_resources in myapp/data cd crih for reference
-
-[WRITE ME]
-ADD how to use external_resources variables used in ginco/web/webconfig.py
-
-Customize header
-~~~~~~~~~~~~~~~~
-
-Let's now move the search box in the header and remove the login form
-from the header. We'll show how to move it to the left column of the application.
-
-Let's sat we do not want anymore the login menu to be in the header, but we 
-prefer it to be in the left column just below the logo. As the left column is
-rendered by ``TheMainTemplate``, we will show how to do it in TheMainTemplate_. 
-
-First, to remove the login menu, we just need to comment out the display of the
-login component such as follows: ::
-
-  class MyHTMLPageHeader(HTMLPageHeader):
-    
-      def main_header(self, view):
-          """build the top menu with authentification info and the rql box"""
-          self.w(u'<table id="header"><tr>\n')
-          self.w(u'<td id="firstcolumn">')
-          self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
-          self.w(u'</td>\n')
-          # appliname and breadcrumbs
-          self.w(u'<td id="headtext">')
-          comp = self.vreg.select_component('appliname', self.req, self.rset)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w)
-          comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w, view=view)
-          self.w(u'</td>')
-          # logged user and help
-          #self.w(u'<td>\n')
-          #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
-          #comp.dispatch(w=self.w)
-          #self.w(u'</td><td>')
-
-          self.w(u'<td>')
-          helpcomp = self.vreg.select_component('help', self.req, self.rset)
-          if helpcomp: # may not be available if Card is not defined in the schema
-              helpcomp.dispatch(w=self.w)
-          self.w(u'</td>')
-          # lastcolumn
-          self.w(u'<td id="lastcolumn">')
-          self.w(u'</td>\n')
-          self.w(u'</tr></table>\n')
-          self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden',
-                        title=False, message=False)
-
-
-
-.. image:: images/lax-book.06-header-no-login.en.png
-
-Let's now move the search box in the top-right header area. To do so, we will
-first create a method to get the search box display and insert it in the header
-table.
-
-::
-
- from ginco.web.views.basetemplates import HTMLPageHeader
- class MyHTMLPageHeader(HTMLPageHeader):
-    def main_header(self, view):
-        """build the top menu with authentification info and the rql box"""
-        self.w(u'<table id="header"><tr>\n')
-        self.w(u'<td id="firstcolumn">')
-        self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
-        self.w(u'</td>\n')
-        # appliname and breadcrumbs
-        self.w(u'<td id="headtext">')
-        comp = self.vreg.select_component('appliname', self.req, self.rset)
-        if comp and comp.propval('visible'):
-            comp.dispatch(w=self.w)
-        comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
-        if comp and comp.propval('visible'):
-            comp.dispatch(w=self.w, view=view)
-        self.w(u'</td>')
-        
-        # logged user and help
-        #self.w(u'<td>\n')
-        #comp = self.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')
-        self.w(u'</td>')
-
-        self.w(u'<td>')
-        helpcomp = self.vreg.select_component('help', self.req, self.rset)
-        if helpcomp: # may not be available if Card is not defined in the schema
-            helpcomp.dispatch(w=self.w)
-        self.w(u'</td>')
-        # lastcolumn
-        self.w(u'<td id="lastcolumn">')
-        self.w(u'</td>\n')
-        self.w(u'</tr></table>\n')
-        self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden',
-                      title=False, message=False)
-
-    def get_searchbox(self, view, context):
-        boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset,
-                                                 view=view, context=context))
-        if boxes:
-            for box in boxes:
-                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: 
-::
-
-  form ginco.web.views.basetemplates import HTMLPageFooter
-  class MyHTMLPageFooter(HTMLPageFooter):
-      def call(self, **kwargs):
-          self.w(u'<div class="footer">')
-          self.w(u'This website has been created with <a href="http://lax.logilab.org">LAX</a>.')
-          self.w(u'</div>')
-
-Updating a view does not require any restart of the server. By reloading
-the page you can see your new page footer.
-
-
-TheMainTemplate
----------------
-.. _TheMainTemplate:
-
-The MainTemplate is a bit complex as it tries to accomodate many
-different cases. We are now about to go through it and cutomize entirely
-our application.
-
-TheMainTemplate is responsible for the general layout of the entire application. 
-It defines the template of ``id = main`` that is used by the application. Is 
-also defined in ``ginco/web/views/basetemplates.py`` another template that can
-be used based on TheMainTemplate called SimpleMainTemplate which does not have 
-a top section.
-
-.. image:: images/lax-book.06-simple-main-template.en.png
-
-CSS changes
------------
-
-We cannot modify the order in which the application is reading the CSS. In
-the case we want to create new CSS style, the best is to define it a in a new
-CSS located under ``myapp/data/``.
-
-If you want to modify an existing CSS styling property, you will have to use
-``!important`` declaration to override the existing property. The application
-apply a higher priority on the default CSS and you can not change that. 
-Customized CSS will not be read first.
-
-1
-[TODO]
-Add login menu in left column
-
-
-[WRITE ME]
-
-* customize MainTemplate and show that everything in the user
-  interface can be changed
-
-[TODO]
-Rajouter une section pour definir la terminologie utilisee.
-Dans ginco-doc rajouter une section pour erudi-ctl shell ou
-on liste les commandes dispos.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/07-00-data-as-objects.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,142 @@
+.. -*- coding: utf-8 -*-
+
+
+Manipulation des données stockées
+=================================
+
+Les classes `Entity` et `AnyEntity`
+-----------------------------------
+Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
+une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
+définir ces classes dans un module du package `entities` d'une application pour 
+qu'elle soit disponible à la fois coté serveur et coté client.
+
+La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
+de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
+ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
+
+Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
+fonction du schéma :
+
+* on peut accéder aux attributs définis dans le schéma via les attributs de même
+  nom sur les instances (valeur typée)
+
+* on peut accéder aux relations définies dans le schéma via les attributs de même
+  nom sur les instances (liste d'instances d'entité)
+
+Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
+
+* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
+  création) 
+        
+* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
+  l'action demandée sur l'entité
+
+:Formattage et génération de la sortie:
+
+  * `view(vid, **kwargs)`, applique la vue donnée à l'entité
+
+  * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
+    vue primaire d'une entité
+
+  * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
+
+  * `format(attr)`, retourne le format (type MIME) du champ passé en argument
+
+  * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`, 
+    retourne une chaine permettant l'affichage dans un format donné de la valeur
+    d'un attribut (la valeur est automatiquement récupérée au besoin)
+
+  * `display_name(form='')`, retourne une chaîne pour afficher le type de
+    l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
+    forme plurielle)
+
+:Gestion de données:
+
+  * `as_rset()`, transforme l'entité en un resultset équivalent simulant
+     le résultat de la requête `Any X WHERE X eid _eid_`
+
+  * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
+    coup toutes les valeurs d'attributs manquant sur l'entité
+
+  * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
+
+  * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
+    des entités liées à l'entité courant par la relation donnée en argument
+
+  * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
+    des entités not liées à l'entité courante par la relation donnée en argument
+    et satisfaisants les contraintes de celle-ci
+
+  * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
+    les valeurs correspondantes passées sous forme d'arguments nommés
+
+  * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
+    argument sur l'entité courante
+
+  * `last_modified(view)`, retourne la date à laquelle on doit considérer
+    l'objet comme modifié (utiliser par la gestion de cache HTTP)
+
+  * `delete()` permet de supprimer l'entité représentée
+  
+:Meta-données standard (Dublin Core):
+
+  * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
+    'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
+    l'entité) 
+
+  * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
+
+  * `dc_description(format='text/plain')`, retourne une chaine unicode
+     correspondant à la méta-donnée 'Description' (cherche un attribut
+     'description' par défaut)
+
+  * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
+    'Authors' (propriétaires par défaut)
+
+  * `dc_date(date_format=None)`, retourne une chaine unicode
+     correspondant à la méta-donnée 'Date' (date de modification par défaut)
+            
+:Contrôle du vocabulaire pour les relations:
+
+  * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
+    par les vues d'édition d'erudi, elle renvoie une liste de couple
+    (label, eid) des entités qui pourraient être liées à l'entité
+    via la relation `rtype`
+  * `subject_relation_vocabulary(rtype, limit=None)`, appelée
+    en interne par `vocabulary` dans le cas d'une relation sujet
+  * `object_relation_vocabulary(rtype, limit=None)`, appelée
+    en interne par `vocabulary` dans le cas d'une relation objet
+  * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
+    en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
+
+
+Les *rtags*
+-----------
+Les *rtags* permettent de spécifier certains comportements propres aux relations
+d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe 
+d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un 
+triplet ::
+
+  <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
+
+et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés 
+s'appliquant à cette relation. 
+
+Il est possible de simplifier ce dictionnaire :
+
+* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
+  un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
+* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
+  position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
+  utiliser le nom du type de relation comme clé
+* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
+  faut utiliser la chaine `*` comme type d'entité cible
+
+A noter également que ce dictionnaire est *traité à la création de la classe*. 
+Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
+besoin de copier celui de la classe parent pour le modifier). De même modifier
+celui-ci après création de la classe n'aura aucun effet...
+
+
+.. include:: 07-01-define-entities.en.txt
--- a/doc/book/en/07-data-as-objects.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Manipulation des données stockées
-=================================
-
-Les classes `Entity` et `AnyEntity`
------------------------------------
-Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
-une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
-définir ces classes dans un module du package `entities` d'une application pour 
-qu'elle soit disponible à la fois coté serveur et coté client.
-
-La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
-de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
-ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
-
-Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
-fonction du schéma :
-
-* on peut accéder aux attributs définis dans le schéma via les attributs de même
-  nom sur les instances (valeur typée)
-
-* on peut accéder aux relations définies dans le schéma via les attributs de même
-  nom sur les instances (liste d'instances d'entité)
-
-Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
-
-* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
-  création) 
-        
-* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
-  l'action demandée sur l'entité
-
-:Formattage et génération de la sortie:
-
-  * `view(vid, **kwargs)`, applique la vue donnée à l'entité
-
-  * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
-    vue primaire d'une entité
-
-  * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
-
-  * `format(attr)`, retourne le format (type MIME) du champ passé en argument
-
-  * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`, 
-    retourne une chaine permettant l'affichage dans un format donné de la valeur
-    d'un attribut (la valeur est automatiquement récupérée au besoin)
-
-  * `display_name(form='')`, retourne une chaîne pour afficher le type de
-    l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
-    forme plurielle)
-
-:Gestion de données:
-
-  * `as_rset()`, transforme l'entité en un resultset équivalent simulant
-     le résultat de la requête `Any X WHERE X eid _eid_`
-
-  * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
-    coup toutes les valeurs d'attributs manquant sur l'entité
-
-  * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
-
-  * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
-    des entités liées à l'entité courant par la relation donnée en argument
-
-  * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
-    des entités not liées à l'entité courante par la relation donnée en argument
-    et satisfaisants les contraintes de celle-ci
-
-  * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
-    les valeurs correspondantes passées sous forme d'arguments nommés
-
-  * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
-    argument sur l'entité courante
-
-  * `last_modified(view)`, retourne la date à laquelle on doit considérer
-    l'objet comme modifié (utiliser par la gestion de cache HTTP)
-
-  * `delete()` permet de supprimer l'entité représentée
-  
-:Meta-données standard (Dublin Core):
-
-  * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
-    'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
-    l'entité) 
-
-  * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
-
-  * `dc_description(format='text/plain')`, retourne une chaine unicode
-     correspondant à la méta-donnée 'Description' (cherche un attribut
-     'description' par défaut)
-
-  * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
-    'Authors' (propriétaires par défaut)
-
-  * `dc_date(date_format=None)`, retourne une chaine unicode
-     correspondant à la méta-donnée 'Date' (date de modification par défaut)
-            
-:Contrôle du vocabulaire pour les relations:
-
-  * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
-    par les vues d'édition d'erudi, elle renvoie une liste de couple
-    (label, eid) des entités qui pourraient être liées à l'entité
-    via la relation `rtype`
-  * `subject_relation_vocabulary(rtype, limit=None)`, appelée
-    en interne par `vocabulary` dans le cas d'une relation sujet
-  * `object_relation_vocabulary(rtype, limit=None)`, appelée
-    en interne par `vocabulary` dans le cas d'une relation objet
-  * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
-    en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
-
-
-Les *rtags*
------------
-Les *rtags* permettent de spécifier certains comportements propres aux relations
-d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe 
-d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un 
-triplet ::
-
-  <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
-
-et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés 
-s'appliquant à cette relation. 
-
-Il est possible de simplifier ce dictionnaire :
-
-* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
-  un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
-* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
-  position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
-  utiliser le nom du type de relation comme clé
-* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
-  faut utiliser la chaine `*` comme type d'entité cible
-
-A noter également que ce dictionnaire est *traité à la création de la classe*. 
-Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
-besoin de copier celui de la classe parent pour le modifier). De même modifier
-celui-ci après création de la classe n'aura aucun effet...
-
-
-.. include:: 07-01-define-entities.en.txt
--- a/doc/book/en/07-rss-xml.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-RSS Channel
-===========
-
-Assuming you have several blog entries, click on the title of the
-search box in the left column. A larger search box should appear. Enter::
-
-   Any X ORDERBY D WHERE X is BlogEntry, X creation_date D
-
-and you get a list of blog entries.
-
-Click on your login at the top right corner. Chose "user preferences",
-then "boxes", then "possible views box" and check "visible = yes"
-before validating your changes.
-
-Enter the same query in the search box and you will see the same list,
-plus a box titled "possible views" in the left column. Click on
-"entityview", then "RSS". 
-
-You just applied the "RSS" view to the RQL selection you requested.
-
-That's it, you have a RSS channel for your blog.
-
-Try again with::
-
-    Any X ORDERBY D WHERE X is BlogEntry, X creation_date D, 
-    X entry_of B, B title "MyLife"
-
-Another RSS channel, but a bit more focused.
-
-A last one for the road::
-
-    Any C ORDERBY D WHERE C is Comment, C creation_date D LIMIT 15
-    
-displayed with the RSS view, that's a channel for the last fifteen
-comments posted.
-
-[WRITE ME]
-
-* show that the RSS view can be used to display an ordered selection
-  of blog entries, thus providing a RSS channel
-
-* show that a different selection (by category) means a different channel
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/08-00-site-config.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,94 @@
+.. -*- coding: utf-8 -*-
+
+Interface de configuration du site
+==================================
+
+.. image:: images/lax-book.03-site-config-panel.en.png
+
+This panel allows you to configure the appearance of your application site.
+Six menus are available and we will go through each of them to explain how
+to use them.
+
+Navigation
+~~~~~~~~~~
+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 
+  (sample format: 23)
+* 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)
+
+UI
+~~
+This menu provides you a way to customize the user interface settings such as
+date format or encoding in the produced html.
+Follows the detailled list of available options :
+
+* ui.date-format : how to format date in the ui ("man strftime" for format description)
+* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
+  description)
+* ui.default-text-format : default text format for rich text fields.
+* ui.encoding : user interface encoding
+* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
+  You should also select text/html as default text format to actually get fckeditor.
+* ui.float-format : how to format float numbers in the ui
+* ui.language : language of the user interface
+* ui.main-template : id of main template used to render pages
+* ui.site-title	: site title, which is displayed right next to the logo in the header
+* ui.time-format : how to format time in the ui ("man strftime" for format description)
+
+
+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. 
+
+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 
+  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
+* hidden : select this to hide the specific action
+
+Boxes
+~~~~~
+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. 
+
+The available boxes are :
+
+* actions box : box listing the applicable actions on the displayed data
+
+* boxes_blog_archives_box : box listing the blog archives 
+
+* possible views box : box listing the possible views for the displayed data
+
+* rss box : RSS icon to get displayed data as a RSS thread
+
+* search box : search box
+
+* startup views box : box listing the configuration options available for 
+  the application site, such as `Preferences` and `Site Configuration`
+
+Components
+~~~~~~~~~~
+[WRITE ME]
+
+Contextual components
+~~~~~~~~~~~~~~~~~~~~~
+[WRITE ME]
+
--- a/doc/book/en/08-rql.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-RQL language (Relation Query Language)
-======================================
-
-Introduction
-------------
-* RQL language focuses on browsing relations.
-* Attributes are considered as particular relations.
-* RQL is inspired from SQL but is a high level language.
-* A good knowledge of Erudi's schemas defining the application is required.
-
-
-Types of requests
------------------
-
-Search (`Any`)
-  query the repository to extract entities and/or attributes.
-
-Insertion (`INSERT`)
-  insert new entities in the database.
-
-Updates of entities, creation of relations (`SET`)
-  update existing entities in the database, or create relations between existing
-  entities
-
-Deletion of entities or relations (`DELETE`)
-  delete existing entities and relations from the database.
-
-
-Variables and typing
---------------------
-
-Entities and values to browse and/or select are set in the query through *variables*
-which should be written in capital letters.
-
-The possible types for each variable can be deducted from the schema depending on
-the conditions expressed in the query.
-
-You can force the possible types for a variable thanks to the special relation `is`.
-
-
-
-Built-in types
---------------
-* `String` (literal: between double or single quotes).
-* `Int`, `Float` (separator is '.').
-* `Date`, `Datetime`, `Time` (literal: pattern YYYY/MM/DD[ hh:mm] or keywords
-  `TODAY` and `NOW`).
-* `Boolean` (keywords `TRUE` et `FALSE`).
-* keyword `NULL`.
-
-Operators
-----------
-* Logical operators: `AND`, `OR`, `,`.
-* Mathematical operators: `+`, `-`, `*`, `/`.
-* Comparison operators: `=`, `<`, `<=`, `>=`, `>`, `~=`, `LIKE`, `IN`.
-
-  * The operator `=` is the default operator.
-
-  * The operator `LIKE` / `~=` allows the use of the character `%` in a string
-    to indicate that the string should start/end with a prefix/suffix::
-    
-      Any X WHERE X nom ~= 'Th%'
-      Any X WHERE X nom LIKE '%lt'
-
-  * The operator `IN` allows to provide a list of possible values::
-
-      Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
-
-Search query
-------------
-
-  [`DISTINCT`] <entity type> V1(, V2)\*
-  [`GROUPBY` V1(, V2)\*]  [`ORDERBY` <orderterms>]
-  [`WHERE` <condition>] 
-  [`LIMIT` <value>] [`OFFSET` <value>]
-
-:entity type:
-  Type of the selected variable
-  Special type `Any` is equivalent to not specify a type
-:condition:
-  list of relations to browse following the pattern 
-    `V1 relation V2|<static value>`
-:orderterms:
-  Setting of the selection order : variable or column number followed by the
-  sorting method (`ASC`, `DESC`), ASC being the default value.
-:note  for grouped queries:
-  For grouped queries (e.g. using function `GROUPBY`), all the selected 
-  variables must be grouped or aggregated.
-
-Examples - search
-~~~~~~~~~~~~~~~~~
-::
-
-      Any X WHERE X eid 53
-      Personne X
-      Personne X WHERE X travaille_pour S, S nom "logilab"
-      Any E,COUNT(X) GROUPBY E ORDERBY EN WHERE X is E, E name EN 
-      Any E,COUNT(X) GROUPBY E ORDERBY 2 WHERE X is E 
-
-
-Advanced features
-~~~~~~~~~~~~~~~~~
-* Aggregate functions: `COUNT`, `MIN`, `MAX`, `SUM`.
-* String functions:`UPPER`, `LOWER`.
-* Optional relations:
-
-  * They allow to select entities related to others or not.
-
-  * You should use `?` behind the variable to specify the relation to itself is
-    optional.
-
-    - Project anomalies related to a version or not::
-
-        Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
-
-    - All the cards and the project they document otherwise ::
-
-        Any C,P WHERE C is Card, P? documented_by C
-
-Negation
-~~~~~~~~
-* A query such as `Document X WHERE NOT X owned_by U` is equivalent to 
-  "the documents which do not have relation `owned_by`".
-* Whereas the query `Document X WHERE NOT X owned_by U, U login "syt"`
-  is equivalent to "the documents which do not have relation `owned_by`
-  with the user syt". They could have a relation with other users.
-
-
-Identity
-~~~~~~~~
-
-We could use the special relation `identity` in a query in order to add a
-condition of identity between two variables. This is equivalent to ``is``
-in Python.
-
-  Any A WHERE A comments B, A identity B
-
-returns the set of objects which comment themselves. The relation `identity`
-is very usefull while defining security rules with `RQLExpressions`.
-
-Insertion queries
------------------
-   `INSERT` <entity type> V1(, <entity type> V2)\* `:` <assignments>
-   [`WHERE` <condition>] 
-
-:assignments:
-  list of relations to assign such as `V1 relation V2|<static value>`
-
-The condition allow to define the variables we would use in assignments.
-
-Be careful, if a condition is specified, the insertion is done *for each result
-returned by the condition*.
- 
-Examples - insertion
-~~~~~~~~~~~~~~~~~~~~~
-* Insertion of a new person named 'bidule'::
-
-       INSERT Person X: X name 'bidule'
-
-* Insertion of a new person named 'bidule', another named
-  'chouette' and a relation 'friend' between them::
-
-       INSERT Person X, Person Y: X name 'bidule', Y name 'chouette', X friend Y
-
-* Insertion of a new person named 'bidule' and a relation 'friend'with an 
-  existing person 'chouette'::
-
-       INSERT Person X: X name 'bidule', X friend Y WHERE Y name 'chouette'
-
-
-Update queries
---------------
-   `SET` <assignments>
-   [`WHERE` <condition>] 
-
-Be careful, if a condition is specified, the update is done *for each result
-returned by the condition*.
-
-Examples - update 
-~~~~~~~~~~~~~~~~~
-* Renaming of the person named 'bidule' to 'toto', with change on the first name::
-
-       SET X name 'toto', X firstname 'original' WHERE X is 'Person', X name 'bidule'
-
-* Insertion of a relation of type 'know' between two objects linked with the relation
-  of type 'friend' ::
-
-       SET X know Y WHERE X friend Y
-
-Deletion queries
-----------------
-   `DELETE` (<entity type> V) | (V1 relation v2),...
-   [`WHERE` <condition>] 
-
-
-Be careful, if a condition is specified, the deletion is done *for each result
-returned by the condition*.
-
-
-Examples
-~~~~~~~~
-* Deletion of the person named 'toto'::
-
-       DELETE Person X WHERE X name 'toto'
-
-* Deletion of all the relations of type 'friend' linked to the person named 
-  'toto'::
-
-       DELETE X friend Y WHERE X is 'Person', X name 'toto'
--- a/doc/book/en/08-site-config.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Interface de configuration du site
-==================================
-
-.. image:: images/lax-book.03-site-config-panel.en.png
-
-This panel allows you to configure the appearance of your application site.
-Six menus are available and we will go through each of them to explain how
-to use them.
-
-Navigation
-~~~~~~~~~~
-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 
-  (sample format: 23)
-* 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)
-
-UI
-~~
-This menu provides you a way to customize the user interface settings such as
-date format or encoding in the produced html.
-Follows the detailled list of available options :
-
-* ui.date-format : how to format date in the ui ("man strftime" for format description)
-* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
-  description)
-* ui.default-text-format : default text format for rich text fields.
-* ui.encoding : user interface encoding
-* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
-  You should also select text/html as default text format to actually get fckeditor.
-* ui.float-format : how to format float numbers in the ui
-* ui.language : language of the user interface
-* ui.main-template : id of main template used to render pages
-* ui.site-title	: site title, which is displayed right next to the logo in the header
-* ui.time-format : how to format time in the ui ("man strftime" for format description)
-
-
-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. 
-
-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 
-  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
-* hidden : select this to hide the specific action
-
-Boxes
-~~~~~
-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. 
-
-The available boxes are :
-
-* actions box : box listing the applicable actions on the displayed data
-
-* boxes_blog_archives_box : box listing the blog archives 
-
-* possible views box : box listing the possible views for the displayed data
-
-* rss box : RSS icon to get displayed data as a RSS thread
-
-* search box : search box
-
-* startup views box : box listing the configuration options available for 
-  the application site, such as `Preferences` and `Site Configuration`
-
-Components
-~~~~~~~~~~
-[WRITE ME]
-
-Contextual components
-~~~~~~~~~~~~~~~~~~~~~
-[WRITE ME]
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/09-00-instance-config.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,162 @@
+.. -*- coding: utf-8 -*-
+
+Configuration d'une instance
+============================
+
+À la création d'une instance, un fichier de configuration est généré dans ::
+
+   $(CW_REGISTRY)/<instance>/<nom configuration>.conf
+
+par exemple ::
+
+   /etc/cubicweb.d/jpl/all-in-one.conf
+
+C'est un simple fichier texte au format INI. Dans la description suivante,
+chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
+le cas échéant, e.g. "`<section>.<option>` [valeur]".
+
+
+Configuration du serveur web
+----------------------------
+:`web.auth-mode` [cookie]: 
+   mode d'authentification, cookie ou http
+:`web.realm`: 
+   realm de l'application en mode d'authentification http
+:`web.http-session-time` [0]:
+   délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
+   en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
+   fermeture du navigateur du client)
+
+:`main.anonymous-user`, `main.anonymous-password`:
+   login et mot de passe à utiliser pour se connecter au serveur RQL lors des
+   connexions HTTP anonymes. Il faut que le compte EUser associé existe.
+
+:`main.base-url`:
+   url de base du site, à utiliser pour générer les urls des pages web
+
+Configuration https
+```````````````````
+Il est possible de rendre un site accessible en http pour les connections 
+anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
+utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
+fichier de configuration.
+
+:Exemple:
+
+  pour une redirection apache d'un site accessible via `http://localhost/demo`
+  et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il 
+  faut avoir pour la version http : ::
+
+    RewriteCond %{REQUEST_URI} ^/demo
+    RewriteRule ^/demo$ /demo/
+    RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
+  
+  et pour la version https : ::
+
+    RewriteCond %{REQUEST_URI} ^/demo
+    RewriteRule ^/demo$ /demo/
+    RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
+
+
+  et on aura dans le fichier all-in-one.conf de l'instance : ::
+
+    base-url = http://localhost/demo
+    https-url = `https://localhost/demo`
+
+Configuration de l'interface web
+--------------------------------
+:`web.embed-allowed`:
+   expression régulière correspondant aux sites pouvant être "incorporé" dans
+   le site (controleur 'embed')
+:`web.submit-url`:
+   url à laquelle les bugs rencontrés dans l'application peuvent être posté
+
+
+Configuration du serveur RQL
+----------------------------
+:`main.host`:
+   nom de l'hôte s'il ne peut être détecter correctement
+:`main.pid-file`:
+   fichier où sera écrit le pid du serveur
+:`main.uid`:
+   compte utilisateur à utiliser pour le lancement du serveur quand il est
+   lancé en root par init
+:`main.session-time [30*60]`:
+   temps d'expiration d'une session RQL
+:`main.query-log-file`:
+   fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
+
+
+Configuration Pyro pour l'instance
+-----------------------------------
+Coté serveur web :
+
+:`pyro-client.pyro-application-id`: 
+   identifiant pyro du serveur RQL (e.g. le nom de l'instance)
+
+Coté serveur RQL :
+
+:`pyro-server.pyro-port`:
+   numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
+   automatiquement.
+
+Coté serveur RQL et serveur web :
+
+:`pyro-name-server.pyro-ns-host`:
+   nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
+   spécifié, il est localisé par une requête de broadcast
+:`pyro-name-server.pyro-ns-group` [cubicweb]:
+   groupe pyro sous lequel enregistrer l'application
+
+
+Configuration courriel
+----------------------
+Coté serveur RQL et serveur web :
+
+:`email.mangle-emails [no]`:
+   indique si les adresses email doivent être affichées telle quelle ou
+   transformée
+
+Coté serveur RQL :
+
+:`email.smtp-host [mail]`:
+   nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
+:`email.smtp-port [25]`:
+   port du serveur SMTP à utiliser pour le courriel sortant
+:`email.sender-name`:
+   nom à utiliser pour les courriels sortant de l'application
+:`email.sender-addr`:
+   adresse à utiliser pour les courriels sortant de l'application
+:`email.default-dest-addrs`:
+   adresses de destination par défaut, si utilisé par la configuration de la 
+   diffusion du modèle (séparées par des virgules)
+:`email.supervising-addrs`:
+   addresses de destination des courriels de supervision (séparées par des 
+   virgules)
+
+
+Configuration journalisation
+----------------------------
+:`main.log-threshold`:
+   niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
+:`main.log-file`:
+   fichier dans lequel écrire les messages
+
+
+Configuration Eproperties
+-------------------------
+D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
+dans la base de données. Il faut donc les éditer via l'interface web ou par des
+requêtes rql.
+
+:`ui.encoding`:
+   encodage de caractères à utiliser pour l'interface web
+:`navigation.short-line-size`: # XXX should be in ui
+   nombre de caractères maximum pour les affichages "courts"
+:`navigation.page-size`:
+   nombre d'entités maximum à afficher par page de résultat
+:`navigation.related-limit`:
+   nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
+:`navigation.combobox-limit`:
+   nombre d'entités non liées maximum à afficher sur les listes déroulantes de
+   la vue d'édition d'une entité
--- a/doc/book/en/09-instance-config.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Configuration d'une instance
-============================
-
-À la création d'une instance, un fichier de configuration est généré dans ::
-
-   $(CW_REGISTRY)/<instance>/<nom configuration>.conf
-
-par exemple ::
-
-   /etc/cubicweb.d/jpl/all-in-one.conf
-
-C'est un simple fichier texte au format INI. Dans la description suivante,
-chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
-le cas échéant, e.g. "`<section>.<option>` [valeur]".
-
-
-Configuration du serveur web
-----------------------------
-:`web.auth-mode` [cookie]: 
-   mode d'authentification, cookie ou http
-:`web.realm`: 
-   realm de l'application en mode d'authentification http
-:`web.http-session-time` [0]:
-   délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
-   en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
-   fermeture du navigateur du client)
-
-:`main.anonymous-user`, `main.anonymous-password`:
-   login et mot de passe à utiliser pour se connecter au serveur RQL lors des
-   connexions HTTP anonymes. Il faut que le compte EUser associé existe.
-
-:`main.base-url`:
-   url de base du site, à utiliser pour générer les urls des pages web
-
-Configuration https
-```````````````````
-Il est possible de rendre un site accessible en http pour les connections 
-anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
-utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
-fichier de configuration.
-
-:Exemple:
-
-  pour une redirection apache d'un site accessible via `http://localhost/demo`
-  et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il 
-  faut avoir pour la version http : ::
-
-    RewriteCond %{REQUEST_URI} ^/demo
-    RewriteRule ^/demo$ /demo/
-    RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
-  
-  et pour la version https : ::
-
-    RewriteCond %{REQUEST_URI} ^/demo
-    RewriteRule ^/demo$ /demo/
-    RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
-
-
-  et on aura dans le fichier all-in-one.conf de l'instance : ::
-
-    base-url = http://localhost/demo
-    https-url = `https://localhost/demo`
-
-Configuration de l'interface web
---------------------------------
-:`web.embed-allowed`:
-   expression régulière correspondant aux sites pouvant être "incorporé" dans
-   le site (controleur 'embed')
-:`web.submit-url`:
-   url à laquelle les bugs rencontrés dans l'application peuvent être posté
-
-
-Configuration du serveur RQL
-----------------------------
-:`main.host`:
-   nom de l'hôte s'il ne peut être détecter correctement
-:`main.pid-file`:
-   fichier où sera écrit le pid du serveur
-:`main.uid`:
-   compte utilisateur à utiliser pour le lancement du serveur quand il est
-   lancé en root par init
-:`main.session-time [30*60]`:
-   temps d'expiration d'une session RQL
-:`main.query-log-file`:
-   fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
-
-
-Configuration Pyro pour l'instance
------------------------------------
-Coté serveur web :
-
-:`pyro-client.pyro-application-id`: 
-   identifiant pyro du serveur RQL (e.g. le nom de l'instance)
-
-Coté serveur RQL :
-
-:`pyro-server.pyro-port`:
-   numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
-   automatiquement.
-
-Coté serveur RQL et serveur web :
-
-:`pyro-name-server.pyro-ns-host`:
-   nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
-   spécifié, il est localisé par une requête de broadcast
-:`pyro-name-server.pyro-ns-group` [cubicweb]:
-   groupe pyro sous lequel enregistrer l'application
-
-
-Configuration courriel
-----------------------
-Coté serveur RQL et serveur web :
-
-:`email.mangle-emails [no]`:
-   indique si les adresses email doivent être affichées telle quelle ou
-   transformée
-
-Coté serveur RQL :
-
-:`email.smtp-host [mail]`:
-   nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
-:`email.smtp-port [25]`:
-   port du serveur SMTP à utiliser pour le courriel sortant
-:`email.sender-name`:
-   nom à utiliser pour les courriels sortant de l'application
-:`email.sender-addr`:
-   adresse à utiliser pour les courriels sortant de l'application
-:`email.default-dest-addrs`:
-   adresses de destination par défaut, si utilisé par la configuration de la 
-   diffusion du modèle (séparées par des virgules)
-:`email.supervising-addrs`:
-   addresses de destination des courriels de supervision (séparées par des 
-   virgules)
-
-
-Configuration journalisation
-----------------------------
-:`main.log-threshold`:
-   niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
-:`main.log-file`:
-   fichier dans lequel écrire les messages
-
-
-Configuration Eproperties
--------------------------
-D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
-dans la base de données. Il faut donc les éditer via l'interface web ou par des
-requêtes rql.
-
-:`ui.encoding`:
-   encodage de caractères à utiliser pour l'interface web
-:`navigation.short-line-size`: # XXX should be in ui
-   nombre de caractères maximum pour les affichages "courts"
-:`navigation.page-size`:
-   nombre d'entités maximum à afficher par page de résultat
-:`navigation.related-limit`:
-   nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
-:`navigation.combobox-limit`:
-   nombre d'entités non liées maximum à afficher sur les listes déroulantes de
-   la vue d'édition d'une entité
--- a/doc/book/en/09-urlrewrite.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-URL Rewriting
-=============
-
-[WRITE ME]
-
-* show how urls are mapped to selections and views and explain URLRewriting 
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/10-00-form-management.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,133 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de formulaires
+======================
+
+Contrôle de la génération automatique de formulaire pour les entités manipulée
+------------------------------------------------------------------------------
+XXX FILLME
+
+* les formulaires 'edition' et 'creation'
+
+Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
+obligé de le refaire à la main ! :)
+
+* rtags primary, secondary, generated, generic,
+  `Entity.relation_category(rtype, x='subject')`
+* inline_view (now a rtag?)
+* spécification widget
+
+
+Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
+--------------------------------------------------------------
+
+Contrôle de l'édition
+`````````````````````
+Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
+
+  <nom de champ>:<eid de l'entité>
+
+où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
+dénommera ces paramètres comme *qualifié*.
+
+1. récupération des entités à éditer en cherchant les paramètres de formulaire
+   commençant par 'eid:' ayant également un paramètre '__type' associé
+   (également *qualifié* par l'eid évidemment)
+
+2. pour tous les attributs et relations de chaque entité à éditer
+
+   1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
+      qualifié dans le cas d'une relation dont l'entité est objet
+   2. si trouvé, la valeur récupérée est considérée comme la valeur originale
+      pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
+      le paramètre <nom relation> (qualifié)
+   3. si la valeur est différente de l'originale, une requête de modification en
+      base est effectuée
+
+3. pour chaque entité à éditer
+
+   1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
+      chaine (ou une liste de chaine) de la forme : ::
+
+        <relation type>:<eids>:<target>
+
+      où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
+      autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
+      relation et chaque relation ainsi spécifiée sera insérée.
+
+   2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
+      relations de l'entité spécifiée en valeur de cette argument sont copiées sur
+      l'entité éditée
+
+
+   3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
+      chaine (ou une liste de chaine) de la forme : ::
+
+	<subject eids>:<relation type>:<object eids>
+
+      où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
+      relation ainsi spécifiée sera supprimée.
+
+   4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
+      même format que pour `__delete`, mais chaque relation ainsi spécifiée sera 
+      insérée.
+
+4. si les paramètres `__insert` et/ou  `__delete` sont trouvés non qualifiés,
+   ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
+   édité)
+
+5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
+   `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
+   par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
+   relations
+
+
+A noter que :
+
+* si le paramètre `__action_delete` est trouvé, toutes les entités comme
+  spécifiées à éditer seront supprimées
+
+* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
+
+* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
+  normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
+  de la redirection`_)
+
+* le paramètre `__method` est également supporté comme sur le template principal
+  (XXX not very consistent, maybe __method should be dealed in the view controller) 
+
+* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
+  `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
+  une erreur est levée
+
+* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
+  valeur de ce paramètre comme message d'information à l'utilisateur une fois
+  l'édition effectuée.
+
+
+Contrôle de la redirection
+``````````````````````````
+Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
+tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
+se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
+controller ça en utilisant les paramètres suivant :
+
+* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
+  de formulaire
+  
+* `__redirectparams`: paramètres de formulaires à ajouter au chemin
+  
+* `__redirectrql`: requête RQL de redirection
+
+* `__redirectvid`: identifiant de vue de redirection
+
+* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
+  d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
+  page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
+  cas échéant responsable d'afficher les erreurs)
+
+* `__form_id`: identifiant de vue du formulaire original, utilisée si
+  `__action_apply` est trouvé
+
+En général on utilise soit `__redirectpath et `__redirectparams` soit
+`__redirectrql` et `__redirectvid`.
--- a/doc/book/en/10-form-management.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de formulaires
-======================
-
-Contrôle de la génération automatique de formulaire pour les entités manipulée
-------------------------------------------------------------------------------
-XXX FILLME
-
-* les formulaires 'edition' et 'creation'
-
-Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
-obligé de le refaire à la main ! :)
-
-* rtags primary, secondary, generated, generic,
-  `Entity.relation_category(rtype, x='subject')`
-* inline_view (now a rtag?)
-* spécification widget
-
-
-Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
---------------------------------------------------------------
-
-Contrôle de l'édition
-`````````````````````
-Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
-
-  <nom de champ>:<eid de l'entité>
-
-où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
-dénommera ces paramètres comme *qualifié*.
-
-1. récupération des entités à éditer en cherchant les paramètres de formulaire
-   commençant par 'eid:' ayant également un paramètre '__type' associé
-   (également *qualifié* par l'eid évidemment)
-
-2. pour tous les attributs et relations de chaque entité à éditer
-
-   1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
-      qualifié dans le cas d'une relation dont l'entité est objet
-   2. si trouvé, la valeur récupérée est considérée comme la valeur originale
-      pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
-      le paramètre <nom relation> (qualifié)
-   3. si la valeur est différente de l'originale, une requête de modification en
-      base est effectuée
-
-3. pour chaque entité à éditer
-
-   1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
-      chaine (ou une liste de chaine) de la forme : ::
-
-        <relation type>:<eids>:<target>
-
-      où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
-      autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
-      relation et chaque relation ainsi spécifiée sera insérée.
-
-   2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
-      relations de l'entité spécifiée en valeur de cette argument sont copiées sur
-      l'entité éditée
-
-
-   3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
-      chaine (ou une liste de chaine) de la forme : ::
-
-	<subject eids>:<relation type>:<object eids>
-
-      où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
-      relation ainsi spécifiée sera supprimée.
-
-   4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
-      même format que pour `__delete`, mais chaque relation ainsi spécifiée sera 
-      insérée.
-
-4. si les paramètres `__insert` et/ou  `__delete` sont trouvés non qualifiés,
-   ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
-   édité)
-
-5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
-   `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
-   par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
-   relations
-
-
-A noter que :
-
-* si le paramètre `__action_delete` est trouvé, toutes les entités comme
-  spécifiées à éditer seront supprimées
-
-* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
-
-* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
-  normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
-  de la redirection`_)
-
-* le paramètre `__method` est également supporté comme sur le template principal
-  (XXX not very consistent, maybe __method should be dealed in the view controller) 
-
-* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
-  `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
-  une erreur est levée
-
-* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
-  valeur de ce paramètre comme message d'information à l'utilisateur une fois
-  l'édition effectuée.
-
-
-Contrôle de la redirection
-``````````````````````````
-Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
-tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
-se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
-controller ça en utilisant les paramètres suivant :
-
-* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
-  de formulaire
-  
-* `__redirectparams`: paramètres de formulaires à ajouter au chemin
-  
-* `__redirectrql`: requête RQL de redirection
-
-* `__redirectvid`: identifiant de vue de redirection
-
-* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
-  d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
-  page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
-  cas échéant responsable d'afficher les erreurs)
-
-* `__form_id`: identifiant de vue du formulaire original, utilisée si
-  `__action_apply` est trouvé
-
-En général on utilise soit `__redirectpath et `__redirectparams` soit
-`__redirectrql` et `__redirectvid`.
--- a/doc/book/en/10-security.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Security
-=========
-
-[WRITE ME]
-
-* talk about security access rights and show that security is defined
-  using RQL
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/11-00-ajax-json.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,16 @@
+.. -*- coding: utf-8 -*-
+
+AJAX
+====
+JSON bla  bla
+XXX FILLME
+
+
+Le contrôleur 'json'
+--------------------
+XXX FILLME
+
+
+API Javascript
+--------------
+XXX FILLME
--- a/doc/book/en/11-ajax-json.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-AJAX
-====
-JSON bla  bla
-XXX FILLME
-
-
-Le contrôleur 'json'
---------------------
-XXX FILLME
-
-
-API Javascript
---------------
-XXX FILLME
--- a/doc/book/en/11-definition-workflow.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Defining a Workflow
-===================
-
-General
--------
-
-A workflow can be defined in a `LAX` application thanks to the system 
-entities ``State`` and ``Transition``. Those are defined within all 
-LAX application and can be set-up through the main administrator interface.
-
-Once your schema is defined, you can start creating the set of states and
-the required transitions for your applications entities.
-
-You first need to define the states and then the transitions between those
-to complete your workflow.
-
-A ``State`` defines the status of an entity. While creating a new state, 
-you will be first given the option to select the entity type the state
-can be applied to. By choosing ``Apply``, a new section will be displayed
-in the editing screen to enable you to add relation to the state you are
-creating.
-
-A ``Transition`` is also based on an entity type it can be applied to.
-By choosing ``Apply``, a new section will be displayed in the editing 
-screen to enable you to add relation to the transition you are
-creating.
-
-At the transition level you will also define the group of user which can
-aplly this transition to an object.
-
-
-Example of a simple workflow
-----------------------------
-
-Please see the tutorial to view and example of a simple workflow.
-
-
-[Create a simple workflow for BlogDemo, to have a moderator approve new blog 
-entry to be published. This implies, specify a dedicated group of blog
-moderator as well as hide the view of a blog entry to the user until
-it reaches the published state.]
--- a/doc/book/en/11-faq.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Frequently Asked Questions
-==========================
-
-* Why does not LAX have a template language ?
-
-  It does. Actually, you can use your preferred template language if you
-  want. [explain how to use a template language]
-
-  The reason template languages are not used in this book is that
-  experience has proved us that using pure python was more efficient.
-
-* Why do you think using pure python is better than using a template language ?
-
-  [copy answer from forum]
-
-  code is easier to maintain, does not have to learn a new dialect
-  each time, real function/classes etc -> real development
-
-* Why do you use the GPL license to prevent me from doing X ?
-
-  [copy answer from forum]
-
-* LAX looks pretty recent. Is it stable ?
-
-  [answer that framework has evolved over the past seven years and that
-  data migrated from one schema to the other ever since]
-
-* Why is the RQL query language looking similar to X ?
-
-  [copy answer from forum, explain why similar to sparql and why better
-  than django and SQL]
-
-* which ajax library
-
-  [we use mochikit and things on top of that]
-
-* `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 :
-      2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
-      Traceback (most recent call last):
-      File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
-      File "/usr/lib/python2.5/codecs.py", line 817, in open
-      file = __builtin__.open(filename, mode, buffering)
-      TypeError: __init__() takes at most 3 arguments (4 given)
-
-  
-  This can be fixed by applying the patch described in :
-  http://code.google.com/p/googleappengine/issues/detail?id=48
-[ADD MORE FAQ]
-.. -*- coding: utf-8 -*-
-
-Frequently Asked Questions
-==========================
-
-* Why does not LAX have a template language ?
-
-  It does. Actually, you can use your preferred template language if you
-  want. [explain how to use a template language]
-
-  The reason template languages are not used in this book is that
-  experience has proved us that using pure python was more efficient.
-
-* Why do you think using pure python is better than using a template language ?
-
-  [copy answer from forum]
-
-  code is easier to maintain, does not have to learn a new dialect
-  each time, real function/classes etc -> real development
-
-* Why do you use the GPL license to prevent me from doing X ?
-
-  [copy answer from forum]
-
-* LAX looks pretty recent. Is it stable ?
-
-  [answer that framework has evolved over the past seven years and that
-  data migrated from one schema to the other ever since]
-
-* Why is the RQL query language looking similar to X ?
-
-  [copy answer from forum, explain why similar to sparql and why better
-  than django and SQL]
-
-* which ajax library
-
-  [we use mochikit and things on top of that]
-
-* `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 ::
-
-      2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
-      Traceback (most recent call last):
-      File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
-      (...)
-      File "/usr/lib/python2.5/codecs.py", line 817, in open
-      file = __builtin__.open(filename, mode, buffering)
-      TypeError: __init__() takes at most 3 arguments (4 given)
-
-  This can be fixed by applying the patch described in :
-  `Google group appengine <http://code.google.com/p/googleappengine/issues/detail?id=48>`_
-
-[ADD MORE FAQ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/12-00-internationalization.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,100 @@
+.. -*- coding: utf-8 -*-
+
+.. _internationalization:
+
+
+Internationalization
+====================
+
+Cubicweb fully supports the internalization of it's content and interface.
+
+Cubicweb's interface internationalization is based on the translation project `GNU gettext`_.
+
+.. _`GNU gettext`: http://www.gnu.org/software/gettext/
+
+Cubicweb' internalization involves two steps:
+
+* in your Python code and cubicweb-tal templates : mark translatable strings
+
+* in your application : handle the translation catalog
+ 
+String internalization
+----------------------
+
+In the Python code and cubicweb-tal templates translatable strings can be
+marked in one of the following ways :
+
+ * by using the *built-in* function `_` ::
+
+   class PrimaryView(EntityView):
+       """the full view of an non final entity"""
+       id = 'primary'
+       title = _('primary')
+
+  OR
+
+ * by using the equivalent request's method ::
+   
+   class NoResultView(EmptyRsetView):
+       """default view when no result has been found"""
+       id = 'noresult'
+    
+       def call(self, **kwargs):
+           self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
+               % self.req._('No result matching query'))
+
+The goal of the *built-in* function `_` is only **to mark the
+translatable strings**, it will only return the translation string
+it-self, but not it's translation.
+
+In the other hand the request's method `_` is ment to retrive the
+proper translation of translation strings in the requested language.
+
+Translations in cubicweb-tal template can also be done with TAL tags
+`i18n:content` and `i18n:replace`.
+
+Note ::
+
+   We dont need to mark the translation strings of entities/relations
+   used by a particular application's schema as they are generated
+   automatically.
+
+
+Handle the translation catalog 
+------------------------------
+
+Once the internalization is done in your application's code, you need
+to populate and update the translation catalog. Cubicweb provides the
+following commands for this purpose:
+
+
+* `i18nlibupdate` updates Cubicweb framework's translation
+  catalogs. Unless you work on the framework development, you dont
+  need to use this command.
+
+* `i18nupdate` updates the translation catalogs of *one particular
+  component* (or of all components). FIXME After this command is
+  executed you must update the translation files *.po* in the "i18n"
+  directory of your template. This command will of course not remove
+  existing translations still in use
+
+* `i18ncompile` recompile the transaltion catalogs of *one particular
+  instance* (or of all instances) after the translation catalogs of
+  its components have been updated. This command is automatically
+  called every time you create or update your instance. The compiled
+  catalogs (*.mo*) are stored in the i18n/<lang>/LC_MESSAGES of
+  application where `lang` is the language identifier ('en' or 'fr'
+  for exemple).
+
+
+Example 
+```````
+You have added and/or modified some translation strings in your application
+(after creating a new view or modifying the application's schema for exemple). 
+To update the translation catalogs you need to do:
+ 
+1. `cubicweb-ctl i18nupdate <component>`
+2. Edit the <component>/xxx.po  files and add missing translations (empty `msgstr`) 
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <myapplication>`
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/12-00-reference.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,33 @@
+.. -*- coding: utf-8 -*-
+
+API Reference
+=============
+
+Schema API
+----------
+
+Base Types
+~~~~~~~~~~
+
+Base types are defined as a set in yams.BASE_TYPES that includes:
+`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
+`Interval`, `Password`, `Bytes`.
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+
+Constraints
+~~~~~~~~~~~
+
+Constraints are defined in yams.constraints and include:
+`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
+`BoundConstraint`, `IntervalBoundConstraint`,
+`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+
+Views API
+---------
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+[WRITE ME]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/12-00-ui-components.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,14 @@
+Autres composants de l'interface web
+====================================
+
+Actions
+-------
+XXXFILLME
+
+Component, VComponent
+---------------------
+XXXFILLME
+
+EProperty
+---------
+XXXFILLME
--- a/doc/book/en/12-internationalization.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _internationalization:
-
-
-Internationalization
-====================
-
-Cubicweb fully supports the internalization of it's content and interface.
-
-Cubicweb's interface internationalization is based on the translation project `GNU gettext`_.
-
-.. _`GNU gettext`: http://www.gnu.org/software/gettext/
-
-Cubicweb' internalization involves two steps:
-
-* in your Python code and cubicweb-tal templates : mark translatable strings
-
-* in your application : handle the translation catalog
- 
-String internalization
-----------------------
-
-In the Python code and cubicweb-tal templates translatable strings can be
-marked in one of the following ways :
-
- * by using the *built-in* function `_` ::
-
-   class PrimaryView(EntityView):
-       """the full view of an non final entity"""
-       id = 'primary'
-       title = _('primary')
-
-  OR
-
- * by using the equivalent request's method ::
-   
-   class NoResultView(EmptyRsetView):
-       """default view when no result has been found"""
-       id = 'noresult'
-    
-       def call(self, **kwargs):
-           self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
-               % self.req._('No result matching query'))
-
-The goal of the *built-in* function `_` is only **to mark the
-translatable strings**, it will only return the translation string
-it-self, but not it's translation.
-
-In the other hand the request's method `_` is ment to retrive the
-proper translation of translation strings in the requested language.
-
-Translations in cubicweb-tal template can also be done with TAL tags
-`i18n:content` and `i18n:replace`.
-
-Note ::
-
-   We dont need to mark the translation strings of entities/relations
-   used by a particular application's schema as they are generated
-   automatically.
-
-
-Handle the translation catalog 
-------------------------------
-
-Once the internalization is done in your application's code, you need
-to populate and update the translation catalog. Cubicweb provides the
-following commands for this purpose:
-
-
-* `i18nlibupdate` updates Cubicweb framework's translation
-  catalogs. Unless you work on the framework development, you dont
-  need to use this command.
-
-* `i18nupdate` updates the translation catalogs of *one particular
-  component* (or of all components). FIXME After this command is
-  executed you must update the translation files *.po* in the "i18n"
-  directory of your template. This command will of course not remove
-  existing translations still in use
-
-* `i18ncompile` recompile the transaltion catalogs of *one particular
-  instance* (or of all instances) after the translation catalogs of
-  its components have been updated. This command is automatically
-  called every time you create or update your instance. The compiled
-  catalogs (*.mo*) are stored in the i18n/<lang>/LC_MESSAGES of
-  application where `lang` is the language identifier ('en' or 'fr'
-  for exemple).
-
-
-Example 
-```````
-You have added and/or modified some translation strings in your application
-(after creating a new view or modifying the application's schema for exemple). 
-To update the translation catalogs you need to do:
- 
-1. `cubicweb-ctl i18nupdate <component>`
-2. Edit the <component>/xxx.po  files and add missing translations (empty `msgstr`) 
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18n compile <myapplication>`
-
--- a/doc/book/en/12-reference.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-API Reference
-=============
-
-Schema API
-----------
-
-Base Types
-~~~~~~~~~~
-
-Base types are defined as a set in yams.BASE_TYPES that includes:
-`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
-`Interval`, `Password`, `Bytes`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Constraints
-~~~~~~~~~~~
-
-Constraints are defined in yams.constraints and include:
-`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
-`BoundConstraint`, `IntervalBoundConstraint`,
-`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Views API
----------
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-[WRITE ME]
-
--- a/doc/book/en/12-ui-components.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Autres composants de l'interface web
-====================================
-
-Actions
--------
-XXXFILLME
-
-Component, VComponent
----------------------
-XXXFILLME
-
-EProperty
----------
-XXXFILLME
--- a/doc/book/en/13-security.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Utilisateurs de l'application : Le contrôle d'accès
-===================================================
-
-
-Vocabulaire
------------
-* Personne, Societe définissent deux *types* d'entité 
-* "Personne travaille_pour Societé" déclare qu'une relation
-  travaille_pour peut exister entre une entité de type Personne et une
-  entité de type Societe. L'ensemble des règles de ce type appliqué
-  à la relation "travaille_pour" définit le schéma de la relation
-  "travaille_pour"
-
-
-Description du modèle de sécurité
----------------------------------
-
-Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
-Control List`. Les notions sont les suivantes :
-
-* utilisateurs et groupes d'utilisateurs
-* un utilisateur appartient à au moins un groupe
-* droits (lire, modifier, créer, supprimer) 
-* les droits sont attribués aux groupes (et non aux utilisateurs)
-
-Pour CubicWeb plus spécifiquement :
-
-* on associe les droits au niveau des schemas d'entites / relations
-* pour chaque type d'entité, on distingue les droits de lecture,
-  ajout, modification et suppression
-* pour chaque type de relation, on distingue les droits de lecture,
-  ajout et suppression (on ne peut pas modifer une relation)
-* les groupes de base sont : Administrateurs, Utilisateurs, Invités
-* les utilisateurs font par défaut parti du groupe Utilisateurs
-* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
-  associer uniquement les droits de suppression et de modification
-* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
-  ajoutés implicitement dans le contexte des objets dont ils sont
-  propriétaires 
-* les droits de ce groupe ne sont vérifiés que sur
-  modification / suppression si tous les autres groupes auxquels
-  l'utilisateur appartient se sont vu interdir l'accès
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/14-00-hooks.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,31 @@
+.. -*- coding: utf-8 -*-
+
+Les crochets (*hooks*)
+======================
+
+XXX FILLME
+
+Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
+relations dans le dépot
+
+Leur prototypes sont les suivants
+
+
+    * after_add_entity     (session, entity)
+    * after_update_entity  (session, entity)
+    * after_delete_entity  (session, eid)
+    * before_add_entity    (session, entity)
+    * before_update_entity (session, entity)
+    * before_delete_entity (session, eid)
+
+    * after_add_relation     (session, fromeid, rtype, toeid)
+    * 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/14-hooks.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Les crochets (*hooks*)
-======================
-
-XXX FILLME
-
-Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
-relations dans le dépot
-
-Leur prototypes sont les suivants
-
-
-    * after_add_entity     (session, entity)
-    * after_update_entity  (session, entity)
-    * after_delete_entity  (session, eid)
-    * before_add_entity    (session, entity)
-    * before_update_entity (session, entity)
-    * before_delete_entity (session, eid)
-
-    * after_add_relation     (session, fromeid, rtype, toeid)
-    * 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
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/15-00-notifications.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de notifications
+========================
+
+XXX FILLME
--- a/doc/book/en/15-notifications.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de notifications
-========================
-
-XXX FILLME
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/16-00-rql.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,216 @@
+.. -*- coding: utf-8 -*-
+
+RQL language (Relation Query Language)
+======================================
+
+XXX see also RQL documentation in source rql/doc.
+
+
+Introduction
+------------
+* RQL language focuses on browsing relations.
+* Attributes are considered as particular relations.
+* RQL is inspired from SQL but is a high level language.
+* A good knowledge of Erudi's schemas defining the application is required.
+
+
+Types of requests
+-----------------
+
+Search (`Any`)
+  query the repository to extract entities and/or attributes.
+
+Insertion (`INSERT`)
+  insert new entities in the database.
+
+Updates of entities, creation of relations (`SET`)
+  update existing entities in the database, or create relations between existing
+  entities
+
+Deletion of entities or relations (`DELETE`)
+  delete existing entities and relations from the database.
+
+
+Variables and typing
+--------------------
+
+Entities and values to browse and/or select are set in the query through *variables*
+which should be written in capital letters.
+
+The possible types for each variable can be deducted from the schema depending on
+the conditions expressed in the query.
+
+You can force the possible types for a variable thanks to the special relation `is`.
+
+
+
+Built-in types
+--------------
+* `String` (literal: between double or single quotes).
+* `Int`, `Float` (separator is '.').
+* `Date`, `Datetime`, `Time` (literal: pattern YYYY/MM/DD[ hh:mm] or keywords
+  `TODAY` and `NOW`).
+* `Boolean` (keywords `TRUE` et `FALSE`).
+* keyword `NULL`.
+
+Operators
+----------
+* Logical operators: `AND`, `OR`, `,`.
+* Mathematical operators: `+`, `-`, `*`, `/`.
+* Comparison operators: `=`, `<`, `<=`, `>=`, `>`, `~=`, `LIKE`, `IN`.
+
+  * The operator `=` is the default operator.
+
+  * The operator `LIKE` / `~=` allows the use of the character `%` in a string
+    to indicate that the string should start/end with a prefix/suffix::
+    
+      Any X WHERE X nom ~= 'Th%'
+      Any X WHERE X nom LIKE '%lt'
+
+  * The operator `IN` allows to provide a list of possible values::
+
+      Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
+
+Search query
+------------
+
+  [`DISTINCT`] <entity type> V1(, V2)\*
+  [`GROUPBY` V1(, V2)\*]  [`ORDERBY` <orderterms>]
+  [`WHERE` <condition>] 
+  [`LIMIT` <value>] [`OFFSET` <value>]
+
+:entity type:
+  Type of the selected variable
+  Special type `Any` is equivalent to not specify a type
+:condition:
+  list of relations to browse following the pattern 
+    `V1 relation V2|<static value>`
+:orderterms:
+  Setting of the selection order : variable or column number followed by the
+  sorting method (`ASC`, `DESC`), ASC being the default value.
+:note  for grouped queries:
+  For grouped queries (e.g. using function `GROUPBY`), all the selected 
+  variables must be grouped or aggregated.
+
+Examples - search
+~~~~~~~~~~~~~~~~~
+::
+
+      Any X WHERE X eid 53
+      Personne X
+      Personne X WHERE X travaille_pour S, S nom "logilab"
+      Any E,COUNT(X) GROUPBY E ORDERBY EN WHERE X is E, E name EN 
+      Any E,COUNT(X) GROUPBY E ORDERBY 2 WHERE X is E 
+
+
+Advanced features
+~~~~~~~~~~~~~~~~~
+* Aggregate functions: `COUNT`, `MIN`, `MAX`, `SUM`.
+* String functions:`UPPER`, `LOWER`.
+* Optional relations:
+
+  * They allow to select entities related to others or not.
+
+  * You should use `?` behind the variable to specify the relation to itself is
+    optional.
+
+    - Project anomalies related to a version or not::
+
+        Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
+
+    - All the cards and the project they document otherwise ::
+
+        Any C,P WHERE C is Card, P? documented_by C
+
+Negation
+~~~~~~~~
+* A query such as `Document X WHERE NOT X owned_by U` is equivalent to 
+  "the documents which do not have relation `owned_by`".
+* Whereas the query `Document X WHERE NOT X owned_by U, U login "syt"`
+  is equivalent to "the documents which do not have relation `owned_by`
+  with the user syt". They could have a relation with other users.
+
+
+Identity
+~~~~~~~~
+
+We could use the special relation `identity` in a query in order to add a
+condition of identity between two variables. This is equivalent to ``is``
+in Python.
+
+  Any A WHERE A comments B, A identity B
+
+returns the set of objects which comment themselves. The relation `identity`
+is very usefull while defining security rules with `RQLExpressions`.
+
+Insertion queries
+-----------------
+   `INSERT` <entity type> V1(, <entity type> V2)\* `:` <assignments>
+   [`WHERE` <condition>] 
+
+:assignments:
+  list of relations to assign such as `V1 relation V2|<static value>`
+
+The condition allow to define the variables we would use in assignments.
+
+Be careful, if a condition is specified, the insertion is done *for each result
+returned by the condition*.
+ 
+Examples - insertion
+~~~~~~~~~~~~~~~~~~~~~
+* Insertion of a new person named 'bidule'::
+
+       INSERT Person X: X name 'bidule'
+
+* Insertion of a new person named 'bidule', another named
+  'chouette' and a relation 'friend' between them::
+
+       INSERT Person X, Person Y: X name 'bidule', Y name 'chouette', X friend Y
+
+* Insertion of a new person named 'bidule' and a relation 'friend'with an 
+  existing person 'chouette'::
+
+       INSERT Person X: X name 'bidule', X friend Y WHERE Y name 'chouette'
+
+
+Update queries
+--------------
+   `SET` <assignments>
+   [`WHERE` <condition>] 
+
+Be careful, if a condition is specified, the update is done *for each result
+returned by the condition*.
+
+Examples - update 
+~~~~~~~~~~~~~~~~~
+* Renaming of the person named 'bidule' to 'toto', with change on the first name::
+
+       SET X name 'toto', X firstname 'original' WHERE X is 'Person', X name 'bidule'
+
+* Insertion of a relation of type 'know' between two objects linked with the relation
+  of type 'friend' ::
+
+       SET X know Y WHERE X friend Y
+
+Deletion queries
+----------------
+   `DELETE` (<entity type> V) | (V1 relation v2),...
+   [`WHERE` <condition>] 
+
+
+Be careful, if a condition is specified, the deletion is done *for each result
+returned by the condition*.
+
+
+Examples
+~~~~~~~~
+* Deletion of the person named 'toto'::
+
+       DELETE Person X WHERE X name 'toto'
+
+* Deletion of all the relations of type 'friend' linked to the person named 
+  'toto'::
+
+       DELETE X friend Y WHERE X is 'Person', X name 'toto'
+
+
--- a/doc/book/en/16-rql.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Le langage RQL (Relation Query Language)
-========================================
-
-Voir la `documentation de RQL <file:///home/sandrine/src/fcubicweb/rql/doc/build/html/index.html>`_ .
-
-
-[TODO]
-Specific link to RQL complete documentation to remove duplicated content.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/17-00-migration.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+
+Migration
+=========
+
+Une des idées de base d'Erudi est la création incrémentale d'application, et
+pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
+une application et tout particulièrement le modèle de données manipulé sans
+perdre les données des instances existantes.
+
+La version courante d'un modèle d'application est données dans le fichier
+`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
+
+
+Gestion des scripts de migrations
+---------------------------------
+Les scripts des migrations doivent être placés dans le répertoire `migration` de
+l'application, et nommé de la manière suivante :
+
+::
+
+  <n° de version X.Y.Z>[_<description>]_<mode>.py
+
+dans lequel : 
+
+* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
+  migrer,
+
+* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
+  de l'application (serveur RQL, serveur web) le script s'applique en cas
+  d'installation distribuée. Il peut valoir : 
+
+  * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
+    et met à jour des fichiers sur le disque (migration de fichier de
+    configuration par exemple).
+
+  * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
+    sur le disque 
+
+  * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
+    fichiers sur le disque 
+
+  * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
+    données en base (migrations de schéma et de données par ex.)
+
+
+Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
+d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
+d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
+des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
+une ligne de la manière suivante : ::
+
+  <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
+
+Par exemple ::
+
+  0.12.0: 2.26.0
+  0.13.0: 2.27.0
+  # 0.14 works with 2.27 <= erudi <= 2.28 at least
+  0.15.0: 2.28.0
+
+
+Contexte de base
+----------------
+Les identifiants suivants sont préféfinis dans les scripts de migration : 
+
+* `config`, configuration de l'instance
+
+* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
+  interactif ou non
+
+* `appltemplversion`, version du modèle d'application de l'instance
+
+* `applerudiversion`, version erudi de l'instance
+
+* `templversion`, version du modéle d'application installée
+
+* `erudiversion`, version erudi installée
+
+* `confirm(question)`, fonction posant une question et retournant vrai si
+  l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
+  interactif) 
+
+* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
+  internationaliser dans les scripts de migration
+
+Dans les scripts "repository", les identifiants suivant sont également définis :
+
+* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
+
+* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
+  cours de migration)
+
+* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
+  version à jour du modèle et de erudi)
+
+* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
+  nécessaire ou avantageux de passer par du sql
+
+* `repo`, l'objet repository
+
+                        
+Migration de schéma
+-------------------
+Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
+"repository" : 
+
+* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
+  nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
+  spécifié il est extrait du schéma à jour.
+        
+* `drop_attribute(etype, attrname, commit=True)`, supprime un
+  attribut à un type d'entité existante.
+
+* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
+            
+* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
+  d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
+  et ayant un type d'entité connu à l'autre extrémité vont également être
+  ajoutées.
+
+* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
+  les relations l'utilisant.
+
+* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
+            
+* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
+  de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
+  type seront également ajoutées.
+
+* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
+  toutes les définitions de ce type.
+
+* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
+
+* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
+  définition de relation.
+
+* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
+  une définition de relation.
+
+* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
+  d'un type d'entité ou de relation
+        
+* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
+  permissions d'un type de relation.
+                
+* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
+  permissions d'un type d'entité.
+    
+* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
+  schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
+  de relations ni de définitions de relation).
+        
+* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
+  les propriétés d'une definition de relation en utilisant les arguments nommés
+  pour les propriétés à changer.
+
+* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
+  pour la relation <rtype> du type d'entité <etype>
+
+* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
+  de taille pour la relation <rtype> du type d'entité <etype>
+
+
+Migration de données
+--------------------
+Les fonctions de migration de données suivantes sont disponibles dans les scripts
+"repository" : 
+
+* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
+  requête rql arbitraire, d'interrogation ou de modification. Un objet result
+  set est retourné.
+
+* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
+  données. La valeur des attributs et relations est spécifiée en utilisant les
+  arguments nommés et positionnels.
+
+  
+Création de workflow
+--------------------
+Les fonctions de création de workflow suivantes sont disponibles dans les scripts
+"repository" : 
+
+* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
+  nouvel état de workflow
+    
+* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`, 
+  ajoute une nouvelle transtion de workflow
+
+Migration de configuration
+--------------------------
+Les fonctions de migration de configuration suivantes sont disponibles dans tout
+les scripts : 
+
+* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
+
+* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
+  changé de groupe
+
+* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
+
+* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
+
+
+Autres fonctions de migration
+-----------------------------
+Ces fonctions ne sont utilisés que pour des opérations de bas niveau
+irréalisables autrement ou pour réparer des bases cassées lors de session
+interactive. Elles sont disponibles dans les scripts "repository".
+
+* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
+  arbitraire, à n'utiliser 
+
+* `add_entity_type_table(etype, commit=True)`
+* `add_relation_type_table(rtype, commit=True)`
+* `uninline_relation(rtype, commit=True)`
--- a/doc/book/en/17-migration.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Migration
-=========
-
-Une des idées de base d'Erudi est la création incrémentale d'application, et
-pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
-une application et tout particulièrement le modèle de données manipulé sans
-perdre les données des instances existantes.
-
-La version courante d'un modèle d'application est données dans le fichier
-`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
-
-
-Gestion des scripts de migrations
----------------------------------
-Les scripts des migrations doivent être placés dans le répertoire `migration` de
-l'application, et nommé de la manière suivante :
-
-::
-
-  <n° de version X.Y.Z>[_<description>]_<mode>.py
-
-dans lequel : 
-
-* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
-  migrer,
-
-* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
-  de l'application (serveur RQL, serveur web) le script s'applique en cas
-  d'installation distribuée. Il peut valoir : 
-
-  * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
-    et met à jour des fichiers sur le disque (migration de fichier de
-    configuration par exemple).
-
-  * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
-    sur le disque 
-
-  * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
-    fichiers sur le disque 
-
-  * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
-    données en base (migrations de schéma et de données par ex.)
-
-
-Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
-d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
-d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
-des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
-une ligne de la manière suivante : ::
-
-  <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
-
-Par exemple ::
-
-  0.12.0: 2.26.0
-  0.13.0: 2.27.0
-  # 0.14 works with 2.27 <= erudi <= 2.28 at least
-  0.15.0: 2.28.0
-
-
-Contexte de base
-----------------
-Les identifiants suivants sont préféfinis dans les scripts de migration : 
-
-* `config`, configuration de l'instance
-
-* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
-  interactif ou non
-
-* `appltemplversion`, version du modèle d'application de l'instance
-
-* `applerudiversion`, version erudi de l'instance
-
-* `templversion`, version du modéle d'application installée
-
-* `erudiversion`, version erudi installée
-
-* `confirm(question)`, fonction posant une question et retournant vrai si
-  l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
-  interactif) 
-
-* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
-  internationaliser dans les scripts de migration
-
-Dans les scripts "repository", les identifiants suivant sont également définis :
-
-* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
-
-* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
-  cours de migration)
-
-* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
-  version à jour du modèle et de erudi)
-
-* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
-  nécessaire ou avantageux de passer par du sql
-
-* `repo`, l'objet repository
-
-                        
-Migration de schéma
--------------------
-Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
-"repository" : 
-
-* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
-  nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
-  spécifié il est extrait du schéma à jour.
-        
-* `drop_attribute(etype, attrname, commit=True)`, supprime un
-  attribut à un type d'entité existante.
-
-* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
-            
-* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
-  d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
-  et ayant un type d'entité connu à l'autre extrémité vont également être
-  ajoutées.
-
-* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
-  les relations l'utilisant.
-
-* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
-            
-* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
-  de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
-  type seront également ajoutées.
-
-* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
-  toutes les définitions de ce type.
-
-* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
-
-* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
-  définition de relation.
-
-* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
-  une définition de relation.
-
-* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
-  d'un type d'entité ou de relation
-        
-* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
-  permissions d'un type de relation.
-                
-* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
-  permissions d'un type d'entité.
-    
-* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
-  schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
-  de relations ni de définitions de relation).
-        
-* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
-  les propriétés d'une definition de relation en utilisant les arguments nommés
-  pour les propriétés à changer.
-
-* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
-  pour la relation <rtype> du type d'entité <etype>
-
-* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
-  de taille pour la relation <rtype> du type d'entité <etype>
-
-
-Migration de données
---------------------
-Les fonctions de migration de données suivantes sont disponibles dans les scripts
-"repository" : 
-
-* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
-  requête rql arbitraire, d'interrogation ou de modification. Un objet result
-  set est retourné.
-
-* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
-  données. La valeur des attributs et relations est spécifiée en utilisant les
-  arguments nommés et positionnels.
-
-  
-Création de workflow
---------------------
-Les fonctions de création de workflow suivantes sont disponibles dans les scripts
-"repository" : 
-
-* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
-  nouvel état de workflow
-    
-* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`, 
-  ajoute une nouvelle transtion de workflow
-
-Migration de configuration
---------------------------
-Les fonctions de migration de configuration suivantes sont disponibles dans tout
-les scripts : 
-
-* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
-
-* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
-  changé de groupe
-
-* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
-
-* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
-
-
-Autres fonctions de migration
------------------------------
-Ces fonctions ne sont utilisés que pour des opérations de bas niveau
-irréalisables autrement ou pour réparer des bases cassées lors de session
-interactive. Elles sont disponibles dans les scripts "repository".
-
-* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
-  arbitraire, à n'utiliser 
-
-* `add_entity_type_table(etype, commit=True)`
-* `add_relation_type_table(rtype, commit=True)`
-* `uninline_relation(rtype, commit=True)`
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/18-00-tests.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,38 @@
+.. -*- coding: utf-8 -*-
+
+Tests
+=====
+
+Écriture de tests unitaires
+---------------------------
+Le framework de test fournit principalement deux classes de tests dans le module
+`ginco.devtools.apptest`:
+
+* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
+* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
+
+Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
+rendant l'écriture de test puissante et rapide.
+
+XXXFILLME describe API
+
+Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
+unitaires ou fonctionnels pour vos entités, vues, crochets...
+
+
+Test des courriels de notifications
+```````````````````````````````````
+Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
+envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
+liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
+et `RepositoryBasedTC`).
+
+Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
+contient des objets ayant deux attributs :
+* `recipients`, la liste des destinataires
+* `msg`, l'objet email.Message
+
+
+Tests automatiques
+------------------
+XXXFILLME
--- a/doc/book/en/18-tests.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Tests
-=====
-
-Écriture de tests unitaires
----------------------------
-Le framework de test fournit principalement deux classes de tests dans le module
-`ginco.devtools.apptest`:
-
-* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
-* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
-
-Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
-rendant l'écriture de test puissante et rapide.
-
-XXXFILLME describe API
-
-Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
-unitaires ou fonctionnels pour vos entités, vues, crochets...
-
-
-Test des courriels de notifications
-```````````````````````````````````
-Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
-envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
-liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
-et `RepositoryBasedTC`).
-
-Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
-contient des objets ayant deux attributs :
-* `recipients`, la liste des destinataires
-* `msg`, l'objet email.Message
-
-
-Tests automatiques
-------------------
-XXXFILLME
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/19-00-i18n.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,71 @@
+.. -*- coding: utf-8 -*-
+
+.. _Internationalisation:
+
+
+Internationalisation
+====================
+
+Le système d'internationalisation de l'interface web de CubicWeb est basé sur le
+système `GNU gettext`_.
+
+.. _`GNU gettext`: http://www.gnu.org/software/gettext/
+
+Messages à internationaliser
+----------------------------
+
+Marquage des messages à internaliser
+````````````````````````````````````
+Les chaines de caractères à internationaliser sont marqués par l'appel à la
+fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
+dans les expressions python de template TAL. 
+
+Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
+traduire via les balises `i18n:content` et  `i18n:replace`.
+
+De plus des messages correspondant aux entités/relations utilisés par le schéma
+de l'application seront automatiquement ajoutés.
+
+Renvoi d'un message internationalisé lors de la construction d'une page
+```````````````````````````````````````````````````````````````````````
+La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
+traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
+méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
+message au lieu de sa traduction dans la langue propre à la requête.1
+
+
+Gestion des catalogues de traduction
+------------------------------------
+Une fois l'application rendu internationalisable coté code, reste à gérer les
+catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes : 
+
+* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie
+  cubicweb*. Sauf si vous développez sur le framework (et non votre propre
+  application), vous ne devriez pas avoir à utiliser cette commande
+
+* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous
+  les composants). A la suite de cette commande, vous devez mettre à jour les
+  fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
+  template. Évidemment les traductions précédentes toujours utilisées ont été
+  conservées.
+
+* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de
+  toutes les instances) après mise à jour des catalogues de son composant. Cela
+  est effectué automatiquement lors d'une création ou d'une mise à jour. Les
+  catalogues de messages compilés se trouvent dans le répertoire
+  "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
+  l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
+
+
+Le cas classique
+````````````````
+Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
+application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
+exemple) :
+
+1. `cubicweb-ctl i18nupdate <composant>`
+2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
+   manquantes (`msgstr` vide) 
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <monapplication>`
+
--- a/doc/book/en/19-i18n.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Internationalisation:
-
-
-Internationalisation
-====================
-
-Le système d'internationalisation de l'interface web de CubicWeb est basé sur le
-système `GNU gettext`_.
-
-.. _`GNU gettext`: http://www.gnu.org/software/gettext/
-
-Messages à internationaliser
-----------------------------
-
-Marquage des messages à internaliser
-````````````````````````````````````
-Les chaines de caractères à internationaliser sont marqués par l'appel à la
-fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
-dans les expressions python de template TAL. 
-
-Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
-traduire via les balises `i18n:content` et  `i18n:replace`.
-
-De plus des messages correspondant aux entités/relations utilisés par le schéma
-de l'application seront automatiquement ajoutés.
-
-Renvoi d'un message internationalisé lors de la construction d'une page
-```````````````````````````````````````````````````````````````````````
-La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
-traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
-méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
-message au lieu de sa traduction dans la langue propre à la requête.1
-
-
-Gestion des catalogues de traduction
-------------------------------------
-Une fois l'application rendu internationalisable coté code, reste à gérer les
-catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes : 
-
-* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie
-  cubicweb*. Sauf si vous développez sur le framework (et non votre propre
-  application), vous ne devriez pas avoir à utiliser cette commande
-
-* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous
-  les composants). A la suite de cette commande, vous devez mettre à jour les
-  fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
-  template. Évidemment les traductions précédentes toujours utilisées ont été
-  conservées.
-
-* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de
-  toutes les instances) après mise à jour des catalogues de son composant. Cela
-  est effectué automatiquement lors d'une création ou d'une mise à jour. Les
-  catalogues de messages compilés se trouvent dans le répertoire
-  "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
-  l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
-
-
-Le cas classique
-````````````````
-Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
-application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
-exemple) :
-
-1. `cubicweb-ctl i18nupdate <composant>`
-2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
-   manquantes (`msgstr` vide) 
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18n compile <monapplication>`
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-00-google-appengine.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,11 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+==========================
+Google AppEngine Datastore
+==========================
+
+
+.. include:: 20-01-intro.en.txt
+.. include:: 20-02-install.en.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-01-intro.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,44 @@
+.. -*- coding: utf-8 -*-
+
+Introduction
+============
+
+What is  `Google AppEngine` ?
+------------------------------
+
+`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]_. 
+
+Therefore `Logilab`_ ported `CubicWeb` to run on top of `Google AppEngine`'s
+datastore.
+
+.. _`Google AppEngine`: http://code.google.com/appengine/docs/whatisgoogleappengine.html
+.. _Logilab: http://www.logilab.fr/
+.. [1] for more on this matter, read our blog at http://www.logilab.org/blogentry/5216
+
+
+Essentials
+----------
+
+To build a web application for `Google App Engine`'s datastore, you
+need to have a good understanding of the main concepts of our 
+`CubicWeb` framework.
+
+The main concepts are:
+
+  - *schema*
+
+  - *query language*
+
+  - *result set*
+
+  - *views*
+
+  - *generated user interface*
+
+  - *cube*
+
+You can find detailled explanation of those concepts in :ref:`TermsVocabulary`.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-02-install.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,220 @@
+.. -*- coding: utf-8 -*-
+
+.. _installation:
+
+Installation
+============
+
+Download the source
+-------------------
+
+- The `Google AppEngine SDK` can be downloaded from:
+  http://code.google.com/appengine/downloads.html
+
+- `LAX` is available as an extension of `CubicWeb` under the GPLv2
+  license which can be downloaded from : http://cubicweb.org/
+
+Please follow instructions on how to install `CubicWeb` framework. 
+
+Once ``cubicweb-ctl`` is installed, then you can create a Google
+App Engine extension of our framework by running the command ::
+
+   cubicweb-ctl newgapp <myapp>
+
+This will create a directory containing ::
+ 
+   `-- myapp/
+       |-- app.conf
+       |-- app.yaml
+       |-- bin/
+       |    `-- laxctl
+       |-- boostrap_cubes
+       |-- cubes/
+       |    |-- addressbook/
+       |    ..
+       |    |-- comment
+       |    ..
+       |    `-- zone/
+       |-- cubicweb/
+       |-- custom.py
+       |-- cw-cubes/
+       |-- dateutil/
+       |-- docutils/
+       |-- fckeditor/
+       |-- i18n/
+       |-- index.yaml
+       |-- loader.py
+       |-- logilab/
+       |-- main.py
+       |-- migration.py
+       |-- mx/
+       |-- roman.py
+       |-- rql/
+       |-- schema.py
+       |-- simplejson/
+       |-- tools/
+       |-- views.py
+       |-- vobject/
+       |-- 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
+`LAX` framework and its third-party libraries. You will notice that 
+the directory ``cubes`` is a library of reusable components.
+
+The main directories that you should know about are:
+
+  - ``cubes`` : this is a library of reusable yams components. To use 
+    those components you will list them in the variable 
+    `included-yams-cubes` of ``app.conf``. See also :ref:`components`. 
+  - [WHICH OTHER ONES SHOULD BE LISTED HERE?]
+
+Dependencies
+------------
+
+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 
+    and using python-yaml:
+    yaml -> full/path/to/google_appengine/lib/yaml/lib/yaml/
+  - gettext
+
+Setup
+-----
+
+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`.
+
+You can have the details of available commands by running ::
+
+   $ python myapp/bin/laxctl --help
+
+
+Generating translation files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`LAX` 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 i18nupdate 
+  $ python myapp/bin/laxctl i18ncompile 
+
+Ignore the errors that print "No translation file found for domain
+'erudi'". They disappear after the first run of i18ncompile.
+
+.. note:: The command  myapp/bin/laxctl i18nupdate needs to be executed
+   only if your application is using components from ginco-apps.
+   Otherwise, please skip it.
+
+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. 
+While running ``laxctl i18nupdate``, new string will be added to the catalogs.
+
+Generating the data directory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In order to generate the ``myapp/data`` directory that holds the static
+files like stylesheets and icons, you need to run the command::
+
+  $ python myapp/bin/laxctl populatedata
+
+Generating the schema diagram
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There is a view named ``schema`` that displays a diagram of the
+entity-relationship graph defined by the schema. This diagram has to
+be generated from the command line::
+
+  $ python myapp/bin/laxctl genschema
+
+Application configuration
+-------------------------
+
+Authentication
+~~~~~~~~~~~~~~
+
+You have the option of using or not google authentication for your application.
+This has to be define in ``app.conf`` and ``app.yaml``.
+
+In ``app.conf`` modify the following variable::

+  # 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: .*
+  script: main.py
+  # comment the line below to allow anonymous access or if you don't want to use
+  # google authentication service
+  #login: required
+
+
+
+
+Quickstart : launch the application
+-----------------------------------
+
+On Mac OS X platforms, drag that directory on the
+`GoogleAppEngineLauncher`.
+
+On Unix and Windows platforms, run it with the dev_appserver::
+
+  $ 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 
+the application and continue the installation.
+
+You should be redirected to a page displaying a message `content initialized`.
+
+Initialize the datastore
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+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 
+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``.
+
+If you choosed to use google authentication, then you will not need to set up
+and administrator login but you will get the cookie value as well.
+
+This cookie values needs to be provided to ``laxctl`` commands
+in order to handle datastore administration requests.
+
+.. image:: images/lax-book.02-cookie-values.en.png
+   :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  
+   `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>`_ 
+   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>`_ 
+as a normal user.
+
+Unless you did something to change it, http://MYAPP_URL should be
+http://localhost:8080/
+
+
--- a/doc/book/en/20-gae.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-==========================
-Google AppEngine Datastore
-==========================
-
-
-.. include:: 01-intro.en.txt
-.. include:: 02-install.en.txt
-.. include:: 03-create-app.en.txt
-.. include:: 04-develop-views.en.txt
-.. include:: 05-components.en.txt
-.. include:: 06-maintemplate.en.txt
-.. include:: 07-rss-xml.en.txt
-.. include:: 08-rql.en.txt
-.. include:: 09-urlrewrite.en.txt
-.. include:: 10-security.en.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/21-00-appendix.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,17 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+Appendix
+========
+
+.. toctree::
+   :maxdepth: 1
+
+   21-01-architecture.en.txt
+   21-02-querier.en.txt
+   21-03-modules-stdlib.en.txt
+   21-04-modules-cbw-api.en.txt
+   21-05-mercurial.en.txt
+   21-06-mercurial-forest.en.txt
+   
--- a/doc/book/en/21-02-querier.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Déroulement de l'éxecution d'une requête en multi-source avec insertion de sécurité
-```````````````````````````````````````````````````````````````````````````````````
-
-* 3 sources (system, ldap (Euser) et rql (Card)
-* permission en lecture Card is elle appartient à l'utilisateur
-
-Soit la requête de départ: ::
-
-  Any X,T WHERE X owned_by U, U login "syt", X title T
-
-1. récupération arbre de syntaxe et solution (+cache) ::
-
-     -> {X: Card, U: Euser}, {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
-
-2. insertion sécurité ::
-
-     -> Any X,T WHERE X owned_by U, U login "syt", X title T, EXISTS(X owned_by UEID) / {X: Card, U: Euser}
-        Any X,T WHERE X owned_by U, U login "syt", X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
-   
-3. construction plan
-   0. preprocessing (annotation des arbres de syntaxe)
-   
-   1. Any U WHERE U login "syt" / {U: Euser}
-      [system+ldap] => table1/varmap1{U:U2}
-      
-   2. Any X,T WHERE X owned_by U2, X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
-      [varmap1|system] => TABLE2
-      
-   3 Deux alernatives:
-   
-     1. Any X,T WHERE X is Card, X title T {X: Card} ::
-
-          [system+rql] => table3/varmap3{X:X3, T:T3}
-	   
-        Any X3,T3 WHERE X3 owned_by U2, X3 title T3, EXISTS(X owned_by UEID) / {X3: Card, U2: Euser} ::
-
-          [(varmap1, varmap3)|system] => TABLE2
-       
-     2 Any X WHERE X is Card X owned_by U2, EXISTS(X owned_by UEID) / {X: Card, U2: Euser} ::
-
-          [varmap1|system] => EIDS
-	   
-       Any X,T WHERE X title T, X eid IN(EIDS) {X: Card} ::
-	 
-          [system+rql] => TABLE2
-   
-   4. renvoie contenu TABLE2.
-      Note : si aggrégat / tri / distinct TABLE2 est nécessairement une table temporaire et besoin d'une
-      étape AggrStep supplémentaire
-      
-4. éxécution du plan
-
-5. [construction description]
-
-6. renvoie ResultSet
-
-Notes sur UNION
-```````````````
-
-* en multi-sources, les résultats des unions peuvent être mélangés
--- a/doc/book/en/21-appendix.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-Appendix
-========
-
-.. toctree::
-   :maxdepth: 1
-
-   21-01-architecture.en.txt
-   21-02-querier.en.txt
-   21-03-modules-stdlib.en.txt
-   21-04-modules-cbw-api.en.txt
-   21-05-mercurial.en.txt
-   21-06-mercurial-forest.en.txt
-   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/22-00-faq.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,104 @@
+.. -*- coding: utf-8 -*-
+
+Frequently Asked Questions
+==========================
+
+* Why does not LAX have a template language ?
+
+  It does. Actually, you can use your preferred template language if you
+  want. [explain how to use a template language]
+
+  The reason template languages are not used in this book is that
+  experience has proved us that using pure python was more efficient.
+
+* Why do you think using pure python is better than using a template language ?
+
+  [copy answer from forum]
+
+  code is easier to maintain, does not have to learn a new dialect
+  each time, real function/classes etc -> real development
+
+* Why do you use the GPL license to prevent me from doing X ?
+
+  [copy answer from forum]
+
+* LAX looks pretty recent. Is it stable ?
+
+  [answer that framework has evolved over the past seven years and that
+  data migrated from one schema to the other ever since]
+
+* Why is the RQL query language looking similar to X ?
+
+  [copy answer from forum, explain why similar to sparql and why better
+  than django and SQL]
+
+* which ajax library
+
+  [we use mochikit and things on top of that]
+
+* `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 ::
+
+      2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
+      Traceback (most recent call last):
+      File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
+      File "/usr/lib/python2.5/codecs.py", line 817, in open
+      file = __builtin__.open(filename, mode, buffering)
+      TypeError: __init__() takes at most 3 arguments (4 given)
+
+  
+  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?
+  
+  Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
+  permet d'executer des actions specifiques lors d'un acces a la base
+  de donnees, ce qui donne un controle de la base de donnees afin de
+  prevenir l'insertion de `mauvaises` entites dans la base.
+
+* When should you define an HTML template rather than define a graphical component?
+
+  Un template HTML ne peut contenir de logique, il ne permettra donc
+  que de definir une vue statique. Un composant permet lui de gerer
+  plus de logique et d'operations sur le contexte dans lequel il 
+  s'applique. Il faut donc bien reflechir avant de decider de l'un ou
+  de l'autre, mais vous avez la possibilite de choisir.
+
+* How to update a database after a schema modification?
+  
+  Cela dépend de ce qui a été modifié dans le schéma. 
+  
+  * Modification d'une relation non finale
+
+  * Modification d'une relation finale 
+
+[TO COMPLETE]
+
+* How to create an anonymous user?
+  
+  Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
+  Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
+  anonyme en initilisant les valeurs des variables suivantes ::
+  
+    # login of the Erudi user account to use for anonymous user (if you want to
+    # allow anonymous)
+    anonymous-user=anon
+
+    # password of the Erudi user account matching login
+    anonymous-password=anon
+
+  Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
+  de données, le plus simple étant de s'identifier sur votre application en
+  administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
+
+* What is the difference between `AppRsetObject` and `AppObject` ?
+
+  La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
+  les instances de la premières sont séléctionnées pour une requête et un "result
+  set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
+  identifiant.
+
--- a/doc/book/en/22-faq.en.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Foire Aux Questions
-===================
-
-[FILL ME]
-
-* A quoi servent les crochets?
-  
-  Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
-  permet d'executer des actions specifiques lors d'un acces a la base
-  de donnees, ce qui donne un controle de la base de donnees afin de
-  prevenir l'insertion de `mauvaises` entites dans la base.
-
-* Quand utiliser un template HTML plutot qu'un composant graphique?
-
-  Un template HTML ne peut contenir de logique, il ne permettra donc
-  que de definir une vue statique. Un composant permet lui de gerer
-  plus de logique et d'operations sur le contexte dans lequel il 
-  s'applique. Il faut donc bien reflechir avant de decider de l'un ou
-  de l'autre, mais vous avez la possibilite de choisir.
-
-* Comment mettre à jour une base de données après avoir modifié le schéma?
-  
-  Cela dépend de ce qui a été modifié dans le schéma. 
-  
-  * Modification d'une relation non finale
-
-  * Modification d'une relation finale 
-
-[TO COMPLETE]
-
-* Comment créer un utilisateur anonyme?
-  
-  Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
-  Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
-  anonyme en initilisant les valeurs des variables suivantes ::
-  
-    # login of the Erudi user account to use for anonymous user (if you want to
-    # allow anonymous)
-    anonymous-user=anon
-
-    # password of the Erudi user account matching login
-    anonymous-password=anon
-
-  Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
-  de données, le plus simple étant de s'identifier sur votre application en
-  administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
-
-* Quelle est la différence entre `AppRsetObject` et `AppObject` ?
-
-  La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
-  les instances de la premières sont séléctionnées pour une requête et un "result
-  set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
-  identifiant.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-actions.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Actions
+=========
+
+[WRITE ME]
+
+* talk about actions that appear in the action box
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-boxes.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Boxes
+=========
+
+[WRITE ME]
+
+* boxes in the web interface
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-dbapi.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+DB-API
+=========
+
+[WRITE ME]
+
+* direct connection to the repository
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-embedding-external-page.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Embedding external pages
+========================
+
+[WRITE ME]
+
+* including external content
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-repository-operations.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Repository operations
+======================
+
+[WRITE ME]
+
+* repository operations
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-repository-session.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Repository sessions
+===================
+
+[WRITE ME]
+
+* repository sessions
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-repository-tasks.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Tasks
+=========
+
+[WRITE ME]
+
+* repository tasks
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-request.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+request
+=======
+
+[WRITE ME]
+
+* the request object
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-sessions.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+sessions
+========
+
+[WRITE ME]
+
+* authentication and management of sessions
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-templates.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Templates
+=========
+
+[WRITE ME]
+
+* talk about main templates, etc.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/XX-XX-urlrewrite.en.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,11 @@
+.. -*- coding: utf-8 -*-
+
+URL Rewriting
+=============
+
+XXX FIXME this should be a chapter
+
+[WRITE ME]
+
+* show how urls are mapped to selections and views and explain URLRewriting 
+
--- a/doc/book/en/index.txt	Fri Nov 21 17:36:42 2008 +0100
+++ b/doc/book/en/index.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -36,30 +36,41 @@
 
 
 .. toctree::
-   :maxdepth: 1
+   :maxdepth: 2
 
-   01-introduction.en.txt
-   02-foundation.en.txt
-   03-setup.en.txt
-   04-define-schema.en.txt
-   05-define-views.en.txt
-   06-define-workflows.en.txt
-   07-data-as-objects.en.txt
-   08-site-config.en.txt
-   09-instance-config.en.txt
-   10-form-management.en.txt
-   11-ajax-json.en.txt
-   12-ui-components.en.txt
-   13-security.en.txt
-   14-hooks.en.txt
-   15-notifications.en.txt
-   16-rql.en.txt
-   17-migration.en.txt
-   18-tests.en.txt
-   19-i18n.en.txt
-   20-gae.en.txt
-   21-appendix.en.txt
-   22-faq.en.txt
+   01-08-book-map.en.txt
+   01-00-introduction.en.txt
+   02-00-foundation.en.txt
+   03-00-setup.en.txt
+   04-00-define-schema.en.txt
+   05-00-define-views.en.txt
+   06-00-define-workflows.en.txt
+   07-00-data-as-objects.en.txt
+   08-00-site-config.en.txt
+   09-00-instance-config.en.txt
+   10-00-form-management.en.txt
+   11-00-ajax-json.en.txt
+   12-00-ui-components.en.txt
+   14-00-hooks.en.txt
+   15-00-notifications.en.txt
+   16-00-rql.en.txt
+   17-00-migration.en.txt
+   18-00-tests.en.txt
+   19-00-i18n.en.txt
+   20-00-google-appengine.en.txt
+   21-00-appendix.en.txt
+   22-00-faq.en.txt
+   XX-XX-actions.en.txt
+   XX-XX-repository-operations.en.txt
+   XX-XX-sessions.en.txt
+   XX-XX-boxes.en.txt
+   XX-XX-repository-session.en.txt     
+   XX-XX-templates.en.txt
+   XX-XX-dbapi.en.txt                    
+   XX-XX-repository-tasks.en.txt       
+   XX-XX-urlrewrite.en.txt
+   XX-XX-embedding-external-page.en.txt  
+   XX-XX-request.en.txt
 
 
 Indices and tables
--- a/doc/book/fr/01-intro.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Introduction à `LAX`
-====================
-
-
-Concepts et vocabulaire
------------------------
-
-*schéma*
-  le schéma définit le modèle de données d'une application sous forme
-  d'entités et de relations. C'est l'élément central d'une
-  application.
-
-*result set*
-  objet encaspulant les résultats d'une requête à l'entrepôt de données
-  et des informations sur cette requête.
-
-*vue*
-  une vue est une manière de représenter les données d'un `result set`
-  sous forme HTML, CSV, JSON, etc.
-
-
-
-Définition d'une application de Blog
-====================================
-
-La première chose à faire est de copier le répertoire ``lax``
-vers un nouveau répertoire qui sera votre application ``Google AppEngine``::
-
-  $ cp -r lax myapp
-
-Définition du schéma
---------------------
-
-Ouvrir le fichier ``myapp/schema.py`` afin de définir le schéma des
-données manipulées. La syntaxe de la définition est la même que celle
-proposée par `Google AppEngine` mais il faut remplacer la ligne
-d'import::
-  
-  from google.appengine.ext import db
-
-par celle-ci::
-
-  from ginco.goa import db
-
-
-Un exemple de schéma de données pour un ``Blog`` pourrait être::
-
-  from ginco.goa import db
-  
-  class BlogEntry(db.Model):
-      # un titre à donner à l'entrée
-      title = db.StringProperty(required=True)
-      # la date à laquelle le blog est créé
-      diem = db.DateProperty(required=True, auto_now_add=True)
-      # le contenu de l'entrée
-      content = db.TextProperty()
-      # une entrée peut en citer une autre
-      cites = db.SelfReferenceProperty() 
-      
-
-Personnalisation des vues
--------------------------
-
-`LAX` permet d'obtenir directement, à partir de la définition
-du schéma, de générer des vues de consultation, d'ajout et
-de modification pour tous les types de donées manipulés.
-Il est toutefois généralement souhaitable de personnaliser
-les vues de consultations.
-
-Dans `LAX`, les vues sont représentées par des classes Python.
-Une vue se caractèrise par :
-
-- un identifiant (tous les objets dans `LAX` sont enregistrés
-  dans un registre et cet identifiant sert de clé pour y retrouver
-  la vue)
-  
-- une description des types de données auxquels elle s'applique
-
-Il existe dans `LAX` des vues prédéfinies et utilisées par le moteur
-d'affichage. Pour avoir une liste exhaustive de ces vues prédéfinies,
-vous pouvez consulter cette page. (XXX mettre le lien vers la liste).
-Par exemple, la vue ``primary`` est la vue utilisée pour générer la
-page principale de consultation d'un objet.
-
-Par exemple, si on souhaite modifier la page principale d'une entrée de
-blog, il faut surcharger la vue ``primary`` des objets ``BlogEntry`` dans
-le fichier ``myapp/views.py``::
-  
-  from ginco.web.views import baseviews
-  
-  class BlogEntryPrimaryView(baseviews.PrimaryView):
-      accepts = ('BlogEntry',)
-      
-      def cell_call(self, row, col):
-          entity = self.entity(row, col)
-          self.w(u'<h1>%s</h1>' % entity.title)
-          self.w(u'<div>%s</div>' entity.content)
-    
-
-Génération du graphique de schéma
----------------------------------
-
-Il existe une vue ``schema`` qui permet d'afficher un graphique
-représantant les différents types d'entités définis dans le schéma
-ainsi que les relations entre ces types. Ce graphique doit être généré
-statiquement. Le script à utiliser pour générer ce schéma est 
-dans ``myapp/tools``. Ce script nécessite d'avoir accès aux
-bibliothèques fournies par le SDK de ``Google AppEngine``. Il faut
-donc modifier son PYTHONPATH::
-
-  $ export PYTHONPATH=GAE_ROOT/google:GAE_ROOT/lib/yaml
-  $ python tools/generate_schema_img.py 
-
-
-Génération des fichiers de traduction
--------------------------------------
-
-Des catalogues de traduction se trouvent dans `myapp/i18n`. Il faut
-pour l'instant les mettre à jour à la main (et/ou avec les outils
-``GNU`` comme ``xgettext``) et ensuite les compiler grâce au script
-``myapp/tools/i18ncompile.py``::
-
-  $ export PYTHONPATH=GAE_ROOT/google:GAE_ROOT/lib/yaml
-  $ python tools/i18ncompile.py
-
--- a/doc/book/fr/02-install.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _installationGAE:
-
-Installation de `CubicWeb` pour GoogleAppEngine
-===============================================
-
-Qu'est-ce que `LAX` ?
-=======================
-
-`LAX` (Logilab Appengine eXtension) est un framework d'application
-web basé sur `Google AppEngine`.
-
-`LAX` est un portage de la partie web de la plate-forme applicative
-développée par Logilab depuis 2001.  Cette plate-forme publie des
-données tirées de bases SQL, d'annuaires LDAP et de systèmes de
-gestion de version. En avril 2008, elle a été portée pour fonctionner
-sur le "datastore" de `Google AppEngine`.
-
-XXX: faire un parallèle entre Django/GAE et LAX/GAE
-
-
-Téléchargement des sources
-==========================
-
-- Les sources de `Google AppEngine` peuvent être récupérées à l'adresse
-  suivante : http://code.google.com/appengine/downloads.html
-
-- Les sources de `LAX` se trouvent à l'adresse suivante :
-  http://lax.logilab.org/
-
-
-Installation
-============
-
-Une fois décompactée, l'archive `lax-0.1.0-alpha.tar.gz`, on obtient
-l'arborescence suivante::
-  
-  .
-  |-- app.yaml
-  |-- custom.py
-  |-- data
-  |-- ginco/
-  |-- i18n/
-  |-- logilab/
-  |-- main.py
-  |-- mx/
-  |-- rql/
-  |-- schema.py
-  |-- simplejson/
-  |-- tools/
-  |   |-- generate_schema_img.py
-  |   `-- i18ncompile.py
-  |-- views.py
-  |-- yams/
-  `-- yapps/
-
-  
-On retrouve le squelette d'une application web de `Google AppEngine`
-(fichiers ``app.yaml``, ``main.py`` en particulier) avec les dépendances
-supplémentaires nécessaires à l'utilisation du framework `LAX`
-
-
-Lancement de l'application de base
-==================================
-
-Plusieurs répertoires doivent être accessibles via la variable 
-d'environnement ``PYTHONPATH`` ::
-
-  $ export PYTHONPATH=/path/to/google_appengine:/path/to/google_appengine/lib/yaml/lib:/path/to/myapp/
-
-Le répertoire yaml n'est nécessaire que pour le lancement des scripts
-qui se trouvent dans lax/tools et pour l'exécution des tests unitaires.
-
-Pour démarrer::
-
-  $ python /path/to/google_appengine/dev_appserver.py /path/to/lax
-
-
--- a/doc/book/fr/03-create-app.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Créer une application simple
-============================
-
-[TRADUISEZ-MOI]
--- a/doc/book/fr/04-develop-views.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Définir l'interface utilisateur avec des vues
-=============================================
-
-`LAX` provides out-of-the-box a web interface that is generated from
-the schema definition: entities can be created, displayed, updated and
-deleted. As display views are not very fancy, it is usually necessary
-to develop your own.
-
-
-With `LAX`, views are defined by Python classes. A view includes :
-
-- an identifier (all objects in `LAX` are entered in a registry
-  and this identifier will be used as a key)
-  
-- a filter to select the resulsets it can be applied to
-
-`LAX` provides a lot of standard views, for a complete list, you
-will have to read the code in directory views (XXX improve doc).
-For example, the view named ``primary`` is the one used to display
-a single entity.
-
-If you want to change the way a ``BlogEntry`` is displayed, just
-override the view ``primary`` in ``BlogDemo/views.py`` ::
-
-  from ginco.web.views import baseviews
-  
-  class BlogEntryPrimaryView(baseviews.PrimaryView):
-
-      accepts = ('BlogEntry',)
-      
-      def cell_call(self, row, col):
-          entity = self.entity(row, col)
-          self.w(u'<h1>%s</h1>' % entity.title)
-          self.w(u'<div>%s</div>' % entity.publish_date)
-          self.w(u'<div>%s</div>' % entity.category)
-          self.w(u'<div>%s</div>' entity.content)
-
-[WRITE ME]
-
-* Defining views with selection/views
-
-* implementing interfaces, calendar for blog entries
-
-* show that a calendar view can export data to ical
-
-* create view "blogentry table" with title, publish_date, category
-
-* in view blog, select blogentries and apply view "blogentry table"
-
-* demo ajax by filtering blogentry table on category
-
-Components
-===========
-
-[WRITE ME]
-
-* explain the component architecture
-
-* add comments to the blog by importing the comments component
-
-MainTemplate
-============
-
-[WRITE ME]
-
-* customize MainTemplate and show that everything in the user
-  interface can be changed
-
-
-RSS Channel
-===========
-
-[WRITE ME]
-
-* show that the RSS view can be used to display an ordered selection
-  of blog entries, thus providing a RSS channel
-
-* show that a different selection (by category) means a different channel
-
-RQL
-====
-
-[WRITE ME]
-
-* talk about the Relation Query Language
-
-URL Rewriting
-=============
-
-[WRITE ME]
-
-* show how urls are mapped to selections and views and explain URLRewriting 
-
-Security
-=========
-
-[WRITE ME]
-
-* talk about security access rights and show that security is defined
-  using RQL
-
--- a/doc/book/fr/05-components.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Composants
-===========
-
-[TRADUISEZ-MOI]
--- a/doc/book/fr/06-maintemplate.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-MainTemplate
-============
-
-[TRADUISEZ-MOI]
--- a/doc/book/fr/07-rss-xml.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Canaux RSS et exports XML
-=========================
-
-[TRADUISEZ-MOI]
--- a/doc/book/fr/08-rql.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-RQL
-===
-
-[TRADUISEZ-MOI]
--- a/doc/book/fr/09-urlrewrite.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Ré-écriture d'URLs
-==================
-
-[TRANSLATE ME]
-
-
--- a/doc/book/fr/10-security.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Securité
-=========
-
-[TRADUISEZ-MOI]
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-01-intro.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,127 @@
+.. -*- coding: utf-8 -*-
+
+Introduction à `LAX`
+====================
+
+
+Concepts et vocabulaire
+-----------------------
+
+*schéma*
+  le schéma définit le modèle de données d'une application sous forme
+  d'entités et de relations. C'est l'élément central d'une
+  application.
+
+*result set*
+  objet encaspulant les résultats d'une requête à l'entrepôt de données
+  et des informations sur cette requête.
+
+*vue*
+  une vue est une manière de représenter les données d'un `result set`
+  sous forme HTML, CSV, JSON, etc.
+
+
+
+Définition d'une application de Blog
+====================================
+
+La première chose à faire est de copier le répertoire ``lax``
+vers un nouveau répertoire qui sera votre application ``Google AppEngine``::
+
+  $ cp -r lax myapp
+
+Définition du schéma
+--------------------
+
+Ouvrir le fichier ``myapp/schema.py`` afin de définir le schéma des
+données manipulées. La syntaxe de la définition est la même que celle
+proposée par `Google AppEngine` mais il faut remplacer la ligne
+d'import::
+  
+  from google.appengine.ext import db
+
+par celle-ci::
+
+  from ginco.goa import db
+
+
+Un exemple de schéma de données pour un ``Blog`` pourrait être::
+
+  from ginco.goa import db
+  
+  class BlogEntry(db.Model):
+      # un titre à donner à l'entrée
+      title = db.StringProperty(required=True)
+      # la date à laquelle le blog est créé
+      diem = db.DateProperty(required=True, auto_now_add=True)
+      # le contenu de l'entrée
+      content = db.TextProperty()
+      # une entrée peut en citer une autre
+      cites = db.SelfReferenceProperty() 
+      
+
+Personnalisation des vues
+-------------------------
+
+`LAX` permet d'obtenir directement, à partir de la définition
+du schéma, de générer des vues de consultation, d'ajout et
+de modification pour tous les types de donées manipulés.
+Il est toutefois généralement souhaitable de personnaliser
+les vues de consultations.
+
+Dans `LAX`, les vues sont représentées par des classes Python.
+Une vue se caractèrise par :
+
+- un identifiant (tous les objets dans `LAX` sont enregistrés
+  dans un registre et cet identifiant sert de clé pour y retrouver
+  la vue)
+  
+- une description des types de données auxquels elle s'applique
+
+Il existe dans `LAX` des vues prédéfinies et utilisées par le moteur
+d'affichage. Pour avoir une liste exhaustive de ces vues prédéfinies,
+vous pouvez consulter cette page. (XXX mettre le lien vers la liste).
+Par exemple, la vue ``primary`` est la vue utilisée pour générer la
+page principale de consultation d'un objet.
+
+Par exemple, si on souhaite modifier la page principale d'une entrée de
+blog, il faut surcharger la vue ``primary`` des objets ``BlogEntry`` dans
+le fichier ``myapp/views.py``::
+  
+  from ginco.web.views import baseviews
+  
+  class BlogEntryPrimaryView(baseviews.PrimaryView):
+      accepts = ('BlogEntry',)
+      
+      def cell_call(self, row, col):
+          entity = self.entity(row, col)
+          self.w(u'<h1>%s</h1>' % entity.title)
+          self.w(u'<div>%s</div>' entity.content)
+    
+
+Génération du graphique de schéma
+---------------------------------
+
+Il existe une vue ``schema`` qui permet d'afficher un graphique
+représantant les différents types d'entités définis dans le schéma
+ainsi que les relations entre ces types. Ce graphique doit être généré
+statiquement. Le script à utiliser pour générer ce schéma est 
+dans ``myapp/tools``. Ce script nécessite d'avoir accès aux
+bibliothèques fournies par le SDK de ``Google AppEngine``. Il faut
+donc modifier son PYTHONPATH::
+
+  $ export PYTHONPATH=GAE_ROOT/google:GAE_ROOT/lib/yaml
+  $ python tools/generate_schema_img.py 
+
+
+Génération des fichiers de traduction
+-------------------------------------
+
+Des catalogues de traduction se trouvent dans `myapp/i18n`. Il faut
+pour l'instant les mettre à jour à la main (et/ou avec les outils
+``GNU`` comme ``xgettext``) et ensuite les compiler grâce au script
+``myapp/tools/i18ncompile.py``::
+
+  $ export PYTHONPATH=GAE_ROOT/google:GAE_ROOT/lib/yaml
+  $ python tools/i18ncompile.py
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-02-install.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,79 @@
+.. -*- coding: utf-8 -*-
+
+.. _installationGAE:
+
+Installation de `CubicWeb` pour GoogleAppEngine
+===============================================
+
+Qu'est-ce que `LAX` ?
+=======================
+
+`LAX` (Logilab Appengine eXtension) est un framework d'application
+web basé sur `Google AppEngine`.
+
+`LAX` est un portage de la partie web de la plate-forme applicative
+développée par Logilab depuis 2001.  Cette plate-forme publie des
+données tirées de bases SQL, d'annuaires LDAP et de systèmes de
+gestion de version. En avril 2008, elle a été portée pour fonctionner
+sur le "datastore" de `Google AppEngine`.
+
+XXX: faire un parallèle entre Django/GAE et LAX/GAE
+
+
+Téléchargement des sources
+==========================
+
+- Les sources de `Google AppEngine` peuvent être récupérées à l'adresse
+  suivante : http://code.google.com/appengine/downloads.html
+
+- Les sources de `LAX` se trouvent à l'adresse suivante :
+  http://lax.logilab.org/
+
+
+Installation
+============
+
+Une fois décompactée, l'archive `lax-0.1.0-alpha.tar.gz`, on obtient
+l'arborescence suivante::
+  
+  .
+  |-- app.yaml
+  |-- custom.py
+  |-- data
+  |-- ginco/
+  |-- i18n/
+  |-- logilab/
+  |-- main.py
+  |-- mx/
+  |-- rql/
+  |-- schema.py
+  |-- simplejson/
+  |-- tools/
+  |   |-- generate_schema_img.py
+  |   `-- i18ncompile.py
+  |-- views.py
+  |-- yams/
+  `-- yapps/
+
+  
+On retrouve le squelette d'une application web de `Google AppEngine`
+(fichiers ``app.yaml``, ``main.py`` en particulier) avec les dépendances
+supplémentaires nécessaires à l'utilisation du framework `LAX`
+
+
+Lancement de l'application de base
+==================================
+
+Plusieurs répertoires doivent être accessibles via la variable 
+d'environnement ``PYTHONPATH`` ::
+
+  $ export PYTHONPATH=/path/to/google_appengine:/path/to/google_appengine/lib/yaml/lib:/path/to/myapp/
+
+Le répertoire yaml n'est nécessaire que pour le lancement des scripts
+qui se trouvent dans lax/tools et pour l'exécution des tests unitaires.
+
+Pour démarrer::
+
+  $ python /path/to/google_appengine/dev_appserver.py /path/to/lax
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-03-create-app.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+Créer une application simple
+============================
+
+[TRADUISEZ-MOI]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-04-develop-views.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,103 @@
+.. -*- coding: utf-8 -*-
+
+Définir l'interface utilisateur avec des vues
+=============================================
+
+`LAX` provides out-of-the-box a web interface that is generated from
+the schema definition: entities can be created, displayed, updated and
+deleted. As display views are not very fancy, it is usually necessary
+to develop your own.
+
+
+With `LAX`, views are defined by Python classes. A view includes :
+
+- an identifier (all objects in `LAX` are entered in a registry
+  and this identifier will be used as a key)
+  
+- a filter to select the resulsets it can be applied to
+
+`LAX` provides a lot of standard views, for a complete list, you
+will have to read the code in directory views (XXX improve doc).
+For example, the view named ``primary`` is the one used to display
+a single entity.
+
+If you want to change the way a ``BlogEntry`` is displayed, just
+override the view ``primary`` in ``BlogDemo/views.py`` ::
+
+  from ginco.web.views import baseviews
+  
+  class BlogEntryPrimaryView(baseviews.PrimaryView):
+
+      accepts = ('BlogEntry',)
+      
+      def cell_call(self, row, col):
+          entity = self.entity(row, col)
+          self.w(u'<h1>%s</h1>' % entity.title)
+          self.w(u'<div>%s</div>' % entity.publish_date)
+          self.w(u'<div>%s</div>' % entity.category)
+          self.w(u'<div>%s</div>' entity.content)
+
+[WRITE ME]
+
+* Defining views with selection/views
+
+* implementing interfaces, calendar for blog entries
+
+* show that a calendar view can export data to ical
+
+* create view "blogentry table" with title, publish_date, category
+
+* in view blog, select blogentries and apply view "blogentry table"
+
+* demo ajax by filtering blogentry table on category
+
+Components
+===========
+
+[WRITE ME]
+
+* explain the component architecture
+
+* add comments to the blog by importing the comments component
+
+MainTemplate
+============
+
+[WRITE ME]
+
+* customize MainTemplate and show that everything in the user
+  interface can be changed
+
+
+RSS Channel
+===========
+
+[WRITE ME]
+
+* show that the RSS view can be used to display an ordered selection
+  of blog entries, thus providing a RSS channel
+
+* show that a different selection (by category) means a different channel
+
+RQL
+====
+
+[WRITE ME]
+
+* talk about the Relation Query Language
+
+URL Rewriting
+=============
+
+[WRITE ME]
+
+* show how urls are mapped to selections and views and explain URLRewriting 
+
+Security
+=========
+
+[WRITE ME]
+
+* talk about security access rights and show that security is defined
+  using RQL
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-05-components.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,7 @@
+.. -*- coding: utf-8 -*-
+
+
+Composants
+===========
+
+[TRADUISEZ-MOI]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-06-maintemplate.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+MainTemplate
+============
+
+[TRADUISEZ-MOI]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-07-rss-xml.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,7 @@
+.. -*- coding: utf-8 -*-
+
+
+Canaux RSS et exports XML
+=========================
+
+[TRADUISEZ-MOI]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-08-rql.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+RQL
+===
+
+[TRADUISEZ-MOI]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-09-urlrewrite.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,8 @@
+.. -*- coding: utf-8 -*-
+
+Ré-écriture d'URLs
+==================
+
+[TRANSLATE ME]
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-10-security.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,7 @@
+.. -*- coding: utf-8 -*-
+
+Securité
+=========
+
+[TRADUISEZ-MOI]
+
--- a/doc/book/fr/20-gae.fr.txt	Fri Nov 21 17:36:42 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-==========================
-Google AppEngine Datastore
-==========================
-
-
-.. include:: 01-intro.fr.txt
-.. include:: 02-install.fr.txt
-.. include:: 03-create-app.fr.txt
-.. include:: 04-develop-views.fr.txt
-.. include:: 05-components.fr.txt
-.. include:: 06-maintemplate.fr.txt
-.. include:: 07-rss-xml.fr.txt
-.. include:: 08-rql.fr.txt
-.. include:: 09-urlrewrite.fr.txt
-.. include:: 10-security.fr.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-google-appengine.fr.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -0,0 +1,19 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+==========================
+Google AppEngine Datastore
+==========================
+
+
+.. include:: 20-01-intro.fr.txt
+.. include:: 20-02-install.fr.txt
+.. include:: 20-03-create-app.fr.txt
+.. include:: 20-04-develop-views.fr.txt
+.. include:: 20-05-components.fr.txt
+.. include:: 20-06-maintemplate.fr.txt
+.. include:: 20-07-rss-xml.fr.txt
+.. include:: 20-08-rql.fr.txt
+.. include:: 20-09-urlrewrite.fr.txt
+.. include:: 20-10-security.fr.txt
--- a/doc/book/fr/index.txt	Fri Nov 21 17:36:42 2008 +0100
+++ b/doc/book/fr/index.txt	Fri Nov 21 17:37:27 2008 +0100
@@ -53,7 +53,7 @@
    17-migration.fr.txt
    18-tests.fr.txt
    19-i18n.fr.txt
-   20-gae.fr.txt
+   20-google-appengine.fr.txt
    21-references.fr.txt
    22-faq.fr.txt
 
--- a/misc/migration/3.0.0_Any.py	Fri Nov 21 17:36:42 2008 +0100
+++ b/misc/migration/3.0.0_Any.py	Fri Nov 21 17:37:27 2008 +0100
@@ -7,3 +7,5 @@
     rql('SET X pkey %(newk)s WHERE X pkey %(oldk)s',
         {'oldk': pk, 'newk': newk})
     print 'renamed', pk, 'to', newk
+
+add_entity_type('ECache')