[doc] another step towards dissolving LAX book into CubicWeb book
authorNicolas Chauvat <nicolas.chauvat@logilab.fr>
Thu, 20 Nov 2008 15:00:34 +0100
changeset 108 60faaa480f02
parent 107 4fe4ce7e2544
child 109 10b63bb96e70
[doc] another step towards dissolving LAX book into CubicWeb book
doc/book/en/01-intro.en.txt
doc/book/en/02-install.en.txt
doc/book/en/03-create-app.en.txt
doc/book/en/04-develop-views.en.txt
doc/book/en/05-components.en.txt
doc/book/en/06-maintemplate.en.txt
doc/book/en/07-rss-xml.en.txt
doc/book/en/08-rql.en.txt
doc/book/en/09-urlrewrite.en.txt
doc/book/en/10-security.en.txt
doc/book/en/20-01-intro.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/20-gae.en.txt
doc/book/en/20-google-appengine.en.txt
doc/book/en/index.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-01-intro.fr.txt
doc/book/fr/20-02-install.fr.txt
doc/book/fr/20-03-create-app.fr.txt
doc/book/fr/20-04-develop-views.fr.txt
doc/book/fr/20-05-components.fr.txt
doc/book/fr/20-06-maintemplate.fr.txt
doc/book/fr/20-07-rss-xml.fr.txt
doc/book/fr/20-08-rql.fr.txt
doc/book/fr/20-09-urlrewrite.fr.txt
doc/book/fr/20-10-security.fr.txt
doc/book/fr/20-gae.fr.txt
doc/book/fr/20-google-appengine.fr.txt
doc/book/fr/index.txt
--- a/doc/book/en/01-intro.en.txt	Thu Nov 20 11:51:28 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/02-install.en.txt	Thu Nov 20 11:51:28 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/
-
-
--- a/doc/book/en/03-create-app.en.txt	Thu Nov 20 11:51:28 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/04-develop-views.en.txt	Thu Nov 20 11:51:28 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.
--- a/doc/book/en/05-components.en.txt	Thu Nov 20 11:51:28 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/06-maintemplate.en.txt	Thu Nov 20 11:51:28 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.
--- a/doc/book/en/07-rss-xml.en.txt	Thu Nov 20 11:51:28 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
-
--- a/doc/book/en/08-rql.en.txt	Thu Nov 20 11:51:28 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/09-urlrewrite.en.txt	Thu Nov 20 11:51:28 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 
-
--- a/doc/book/en/10-security.en.txt	Thu Nov 20 11:51:28 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/20-01-intro.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,63 @@
+.. -*- 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.
+
+.. _Logilab: http://www.logilab.fr/
+.. [1] for more on this matter, read our blog at http://www.logilab.org/blog/5216
+
+
+Essentials
+----------
+
+XXXFIXME MERGE WITH 02-foundation.en.txt
+
+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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-02-install.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,223 @@
+.. -*- coding: utf-8 -*-
+
+.. _installation:
+
+Installation
+============
+
+XXXFIXME KEEP WHAT IS SPECIFIC TO APPENGINE AND MERGE THE REST WITH
+03-setup.en.txt
+
+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/20-03-create-app.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,204 @@
+.. -*- 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-04-develop-views.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,128 @@
+.. -*- 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-05-components.en.txt	Thu Nov 20 15:00:34 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/20-06-maintemplate.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,211 @@
+.. -*- 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-07-rss-xml.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,47 @@
+.. -*- 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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-08-rql.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,213 @@
+.. -*- 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'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-09-urlrewrite.en.txt	Thu Nov 20 15:00:34 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 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-10-security.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,10 @@
+.. -*- coding: utf-8 -*-
+
+Security
+=========
+
+[WRITE ME]
+
+* talk about security access rights and show that security is defined
+  using RQL
+
--- a/doc/book/en/20-gae.en.txt	Thu Nov 20 11:51:28 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/20-google-appengine.en.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,19 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+==========================
+Google AppEngine Datastore
+==========================
+
+
+.. 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/index.txt	Thu Nov 20 11:51:28 2008 +0100
+++ b/doc/book/en/index.txt	Thu Nov 20 15:00:34 2008 +0100
@@ -57,7 +57,7 @@
    17-migration.en.txt
    18-tests.en.txt
    19-i18n.en.txt
-   20-gae.en.txt
+   20-google-appengine.en.txt
    21-appendix.en.txt
    22-faq.en.txt
 
--- a/doc/book/fr/01-intro.fr.txt	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 11:51:28 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 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	Thu Nov 20 15:00:34 2008 +0100
@@ -0,0 +1,7 @@
+.. -*- coding: utf-8 -*-
+
+Securité
+=========
+
+[TRADUISEZ-MOI]
+
--- a/doc/book/fr/20-gae.fr.txt	Thu Nov 20 11:51:28 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	Thu Nov 20 15:00:34 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	Thu Nov 20 11:51:28 2008 +0100
+++ b/doc/book/fr/index.txt	Thu Nov 20 15:00:34 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