[doc] merge old lax book with the rest
authorNicolas Chauvat <nicolas.chauvat@logilab.fr>
Thu, 20 Nov 2008 21:30:55 +0100
changeset 115 4b66ad23fbd1
parent 114 9ecd54ea0634
child 116 e2303f9b5bfa
[doc] merge old lax book with the rest
doc/book/en/01-00-introduction.en.txt
doc/book/en/01-05-components.en.txt
doc/book/en/01-06-maintemplate.en.txt
doc/book/en/01-07-rss-xml.en.txt
doc/book/en/16-00-rql.en.txt
doc/book/en/20-00-google-appengine.en.txt
doc/book/en/20-02-install.en.txt
doc/book/en/20-03-create-app.en.txt
doc/book/en/20-04-develop-views.en.txt
doc/book/en/20-05-components.en.txt
doc/book/en/20-06-maintemplate.en.txt
doc/book/en/20-07-rss-xml.en.txt
doc/book/en/20-08-rql.en.txt
doc/book/en/20-09-urlrewrite.en.txt
doc/book/en/20-10-security.en.txt
doc/book/en/XX-XX-urlrewrite.en.txt
--- a/doc/book/en/01-00-introduction.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ b/doc/book/en/01-00-introduction.en.txt	Thu Nov 20 21:30:55 2008 +0100
@@ -227,11 +227,9 @@
 .. 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
+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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-05-components.en.txt	Thu Nov 20 21:30:55 2008 +0100
@@ -0,0 +1,152 @@
+.. -*- coding: utf-8 -*-
+
+.. _components:
+
+Components
+===========
+
+XXXFIXME TURN THIS INTO A CHAPTER
+
+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	Thu Nov 20 21:30:55 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.
+
+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/01-07-rss-xml.en.txt	Thu Nov 20 21:30:55 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
+
--- a/doc/book/en/16-00-rql.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ b/doc/book/en/16-00-rql.en.txt	Thu Nov 20 21:30:55 2008 +0100
@@ -1,11 +1,216 @@
 .. -*- coding: utf-8 -*-
 
-Le langage RQL (Relation Query Language)
-========================================
+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`.
+
+
 
-Voir la `documentation de RQL <file:///home/sandrine/src/fcubicweb/rql/doc/build/html/index.html>`_ .
+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 
 
 
-[TODO]
-Specific link to RQL complete documentation to remove duplicated content.
+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/20-00-google-appengine.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ b/doc/book/en/20-00-google-appengine.en.txt	Thu Nov 20 21:30:55 2008 +0100
@@ -9,11 +9,3 @@
 
 .. include:: 20-01-intro.en.txt
 .. include:: 20-02-install.en.txt
-.. include:: 20-03-create-app.en.txt
-.. include:: 20-04-develop-views.en.txt
-.. include:: 20-05-components.en.txt
-.. include:: 20-06-maintemplate.en.txt
-.. include:: 20-07-rss-xml.en.txt
-.. include:: 20-08-rql.en.txt
-.. include:: 20-09-urlrewrite.en.txt
-.. include:: 20-10-security.en.txt
--- a/doc/book/en/20-02-install.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ b/doc/book/en/20-02-install.en.txt	Thu Nov 20 21:30:55 2008 +0100
@@ -5,9 +5,6 @@
 Installation
 ============
 
-XXXFIXME KEEP WHAT IS SPECIFIC TO APPENGINE AND MERGE THE REST WITH
-03-setup.en.txt
-
 Download the source
 -------------------
 
--- a/doc/book/en/20-03-create-app.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Creating your first application
-===============================
-
-XXXFIXME KEEP WHAT IS SPECIFIC TO APPENGINE AND MERGE THE REST WITH OVERVIEW OR
-MAKE A NEW CHAPTER
-
-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/20-04-develop-views.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Developing the user interface with Views
-========================================
-
-XXXFIXME MERGE THIS WITH 05-define-views.en.txt
-
-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.
--- a/doc/book/en/20-05-components.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _components:
-
-Components
-===========
-
-XXXFIXME TURN THIS INTO A CHAPTER
-
-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/20-06-maintemplate.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Views & Templates
-=================
-
-XXXFIXME TURN THIS INTO A CHAPTER
-
-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.
--- a/doc/book/en/20-07-rss-xml.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-RSS Channel
-===========
-
-XXXFIXME TURN THIS INTO A CHAPTER
-
-Assuming you have several blog entries, click on the title of the
-search box in the left column. A larger search box should appear. Enter::
-
-   Any X ORDERBY D WHERE X is BlogEntry, X creation_date D
-
-and you get a list of blog entries.
-
-Click on your login at the top right corner. Chose "user preferences",
-then "boxes", then "possible views box" and check "visible = yes"
-before validating your changes.
-
-Enter the same query in the search box and you will see the same list,
-plus a box titled "possible views" in the left column. Click on
-"entityview", then "RSS". 
-
-You just applied the "RSS" view to the RQL selection you requested.
-
-That's it, you have a RSS channel for your blog.
-
-Try again with::
-
-    Any X ORDERBY D WHERE X is BlogEntry, X creation_date D, 
-    X entry_of B, B title "MyLife"
-
-Another RSS channel, but a bit more focused.
-
-A last one for the road::
-
-    Any C ORDERBY D WHERE C is Comment, C creation_date D LIMIT 15
-    
-displayed with the RSS view, that's a channel for the last fifteen
-comments posted.
-
-[WRITE ME]
-
-* show that the RSS view can be used to display an ordered selection
-  of blog entries, thus providing a RSS channel
-
-* show that a different selection (by category) means a different channel
-
--- a/doc/book/en/20-08-rql.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-RQL language (Relation Query Language)
-======================================
-
-XXXFIXME MERGE WITH 16-rql.en.txt
-
-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/20-09-urlrewrite.en.txt	Thu Nov 20 20:36:03 2008 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-.. -*- 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/20-10-security.en.txt	Thu Nov 20 20:36:03 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/XX-XX-urlrewrite.en.txt	Thu Nov 20 21:30:55 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 
+