--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-00-introduction.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,335 @@
+.. -*- coding: utf-8 -*-
+
+.. _Overview:
+
+Quick overview of `CubicWeb`
+============================
+
+`CubicWeb` allows us to develop web applications instances based on
+one or more `cubes`.
+
+What we call a `cube` is a model defining the data types and views.
+A `cube` is a reusable component grouped with others cubes in the file
+system.
+
+An `instance` refers to a specific installation of one or more `cubes`
+ where are grouped configuration files of the final web application.
+
+In this document, we will show you how to create a `cube` and how to use it
+in an `instance` for your web application.
+
+Create your cube
+----------------
+
+After you installed your `CubicWeb` development environment, you can start
+to build your first cube: ::
+
+ cubicweb-ctl newcube blog
+
+This will create in ``/path/to/forest/cubes`` a directory containing: ::
+
+ blog/
+ |
+ |-- data/
+ | |-- cubes.blog.css
+ | |-- cubes.blog.js
+ | |-- external_resources
+ |
+ |-- debian/
+ | |-- changelog
+ | |-- compat
+ | |-- control
+ | |-- copyright
+ | |-- cubicweb-blog.prerm
+ | |-- rules
+ |
+ |-- entities.py
+ |
+ |-- i18n/
+ | |-- en.po
+ | |-- fr.po
+ |
+ |-- __init__.py
+ |
+ |-- MANIFEST.in
+ |
+ |-- migration/
+ | |-- postcreate.py
+ | |-- precreate.py
+ |
+ |-- __pkginfo__.py
+ |
+ |-- schema.py
+ |
+ |-- setup.py
+ |
+ |-- site_cubicweb.py
+ |
+ |-- sobjects.py
+ |
+ |-- test/
+ | |-- data/
+ | |-- bootstrap_cubes
+ | |-- pytestconf.py
+ | |-- realdb_test_blog.py
+ | |-- test_blog.py
+ |
+ |-- views.py
+
+Any changes applied to your data model should be done in this
+directory.
+
+
+Define your data schema
+-----------------------
+
+The data model or schema is hte core of your `CubicWeb` application.
+This is where is defined the type of content you application will handle.
+
+The data model is defined in the file ``schema.py`` of your cube
+``blog`` such as follows.
+
+::
+
+ from cubicweb.schema import format_constraint
+ class Blog(EntityType):
+ title = String(maxsize=50, required=True)
+ description = String()
+
+ class BlogEntry(EntityType):
+ title = String(required=True, fulltextindexed=True, maxsize=256)
+ publish_date = Date(default='TODAY')
+ content = String(required=True, fulltextindexed=True)
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+
+
+A Blog has a title and a description. The title is a string that is
+required by the class EntityType and must be less than 50 characters.
+The description is a string that is not constrained.
+
+A BlogEntry has a title, a publish_date and a content. The title is a
+string that is required and must be less than 100 characters. The
+publish_date is a Date with a default value of TODAY, meaning that
+when a BlogEntry is created, its publish_date will be the current day
+unless it is modified. The content is a string that will be indexed in
+the full-text index and has no constraint.
+
+A BlogEntry also has a relationship ``entry_of`` that links it to a
+Blog. The cardinality ``?*`` means that a BlogEntry can be part of
+zero or one Blog (``?`` means `zero or one`) and that a Blog can
+have any number of BlogEntry (``*`` means `any number including
+zero`). For completeness, remember that ``+`` means `one or more`.
+
+
+Create your instance
+--------------------
+
+::
+
+ cubicweb-ctl create blog blogdemo
+
+
+This command will create a directory ``~/etc/cubicweb.d/blogdemo``
+which will contain all the configuration files required to start
+you web application.
+
+The instance ``blogdemo`` is based on the cube ``blog``.
+
+
+Welcome in your web application
+-------------------------------
+
+Run your application with the following command: ::
+
+ cubicweb-ctl start -D blogdemo
+
+
+You can now access to your web application to create blogs and post messages
+by visitin the URL http://localhost:8080/.
+A login form will first be prompted. By default, the application will not allow
+anonymous user to get in the application. You should then use the admin
+account you created at the time you initialized the database with
+``cubicweb-ctl create``.
+
+.. image:: images/login-form.png
+
+
+Once authenticated, you can start playing with your application
+and create entities. Bravo!
+
+.. image:: images/blog-demo-first-page.png
+
+Please notice that so far, `CubicWeb` franework managed all aspects of
+the web application based in the schema provided at first.
+
+
+Create entities
+---------------
+
+We will now create a couple of entities in our web application.
+
+Create a Blog
+~~~~~~~~~~~~~
+
+Let us create a few of these entities. Click on the `[+]` at the right
+of the link Blog. Call this new Blog ``Tech-blog`` and type in
+``everything about technology`` as the description, then validate the
+form by clicking on ``Validate``.
+
+.. image:: images/cbw-create-blog.en.png
+ :alt: from to create blog
+
+Click on the logo at top left to get back to the home page, then
+follow the Blog link that will list for you all the existing Blog.
+You should be seeing a list with a single item ``Tech-blog`` you
+just created.
+
+.. image:: images/cbw-list-one-blog.en.png
+ :alt: displaying a list of a single blog
+
+Clicking on this item will get you to its detailed description except
+that in this case, there is not much to display besides the name and
+the phrase ``everything about technology``.
+
+Now get back to the home page by clicking on the top-left logo, then
+create a new Blog called ``MyLife`` and get back to the home page
+again to follow the Blog link for the second time. The list now
+has two items.
+
+.. image:: images/cbw-list-two-blog.en.png
+ :alt: displaying a list of two blogs
+
+Create a BlogEntry
+~~~~~~~~~~~~~~~~~~
+
+Get back to the home page and click on [+] at the right of the link
+BlogEntry. Call this new entry ``Hello World`` and type in some text
+before clicking on ``Validate``. You added a new blog entry without
+saying to what blog it belongs. There is a box on the left entitled
+``actions``, click on the menu item ``modify``. You are back to the form
+to edit the blog entry you just created, except that the form now has
+another section with a combobox titled ``add relation``. Chose
+``entry_of`` in this menu and a second combobox appears where you pick
+``MyLife``.
+
+You could also have, at the time you started to fill the form for a
+new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
+combobox titled ``add relation`` would have showed up.
+
+
+.. image:: images/cbw-add-relation-entryof.en.png
+ :alt: editing a blog entry to add a relation to a blog
+
+Validate the changes by clicking ``Validate``. The entity BlogEntry
+that is displayed now includes a link to the entity Blog named
+``MyLife``.
+
+.. image:: images/cbw-detail-one-blogentry.en.png
+ :alt: displaying the detailed view of a blogentry
+
+Please notice that so far, `CubicWeb` franework managed all aspects of
+the web application based in the schema provided at first.
+Also if you wish to get a graphical view of the schema, visit
+the link `Application schema`` which will direct you to :
+http://localhost:8080/view?vid=schema
+
+.. image:: images/cbw-schema.en.png
+ :alt: graphical view of the schema (aka data-model)
+
+
+Define your entities views
+--------------------------
+
+The views selection principle
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A view is defined by a Python class which includes:
+
+ - an identifier (all objects in `CubicWeb` are entered in a registry
+ and this identifier will be used as a key)
+
+ - a filter to select the resulsets it can be applied to
+
+
+`CubicWeb` provides a lot of standard views for the type
+`EntityView`, for a complete list, you
+will have to read the code in directory ``cubicweb/web/views/``
+
+A view is applied on a `result set` which contains a set of
+entities we are trying to display. `CubicWeb` uses a selector
+mecanism which computes a score used to identify which view
+is the best to apply for the `result set` we are trying to
+display. The standard library of selectors is in
+``cubicweb.common.selector`` and a library of methods used to
+compute scores is available in ``cubicweb.vregistry.vreq``.
+
+It is possible to define multiple views for the same identifier
+and to associate selectors and filters to allow the application
+to find the best way to render the data. We will see more details
+on this in :ref:`DefinitionVues`.
+
+For example, the view named ``primary`` is the one used to display
+a single entity. We will now show you hos to customize this view.
+
+
+View customization
+~~~~~~~~~~~~~~~~~~
+
+If you wish to modify the way a `BlogEntry` is rendered, you will have to
+overwrite the `primary` view defined in the module ``views`` of the cube
+``cubes/blog/views.py``.
+
+We can by example add in front of the pulication date a prefix specifying
+the date we see is the publication date.
+
+To do so, please apply the following changes:
+
+::
+
+ from cubicweb.web.views import baseviews
+
+
+ class BlogEntryPrimaryView(baseviews.PrimaryView):
+
+ accepts = ('BlogEntry',)
+
+ def render_entity_title(self, entity):
+ self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title()))
+
+ def content_format(self, entity):
+ return entity.view('reledit', rtype='content_format')
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+
+ # display entity attributes with prefixes
+ self.w(u'<h1>%s</h1>' % entity.title)
+ self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
+ self.w(u'<p>%s</p>' % entity.content)
+
+ # display relations
+ siderelations = []
+ if self.main_related_section:
+ self.render_entity_relations(entity, siderelations)
+
+.. note::
+ When a view is modified, it is not required to restart the application
+ server. Save the Python file and reload the page in your web browser
+ to view the changes.
+
+You can now see that the publication date has a prefix.
+
+.. image:: images/cbw-update-primary-view.en.png
+ :alt: modified primary view
+
+
+The above source code defines a new primary view for
+``BlogEntry``.
+
+Since views are applied to resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates. We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. In our
+example we use it to output HTML tags and values of the entity's attributes.
+
--- a/doc/book/en/01-introduction.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Overview:
-
-Quick overview of `CubicWeb`
-============================
-
-`CubicWeb` allows us to develop web applications instances based on
-one or more `cubes`.
-
-What we call a `cube` is a model defining the data types and views.
-A `cube` is a reusable component grouped with others cubes in the file
-system.
-
-An `instance` refers to a specific installation of one or more `cubes`
- where are grouped configuration files of the final web application.
-
-In this document, we will show you how to create a `cube` and how to use it
-in an `instance` for your web application.
-
-Create your cube
-----------------
-
-After you installed your `CubicWeb` development environment, you can start
-to build your first cube: ::
-
- cubicweb-ctl newcube blog
-
-This will create in ``/path/to/forest/cubes`` a directory containing: ::
-
- blog/
- |
- |-- data/
- | |-- cubes.blog.css
- | |-- cubes.blog.js
- | |-- external_resources
- |
- |-- debian/
- | |-- changelog
- | |-- compat
- | |-- control
- | |-- copyright
- | |-- cubicweb-blog.prerm
- | |-- rules
- |
- |-- entities.py
- |
- |-- i18n/
- | |-- en.po
- | |-- fr.po
- |
- |-- __init__.py
- |
- |-- MANIFEST.in
- |
- |-- migration/
- | |-- postcreate.py
- | |-- precreate.py
- |
- |-- __pkginfo__.py
- |
- |-- schema.py
- |
- |-- setup.py
- |
- |-- site_cubicweb.py
- |
- |-- sobjects.py
- |
- |-- test/
- | |-- data/
- | |-- bootstrap_cubes
- | |-- pytestconf.py
- | |-- realdb_test_blog.py
- | |-- test_blog.py
- |
- |-- views.py
-
-Any changes applied to your data model should be done in this
-directory.
-
-
-Define your data schema
------------------------
-
-The data model or schema is hte core of your `CubicWeb` application.
-This is where is defined the type of content you application will handle.
-
-The data model is defined in the file ``schema.py`` of your cube
-``blog`` such as follows.
-
-::
-
- from cubicweb.schema import format_constraint
- class Blog(EntityType):
- title = String(maxsize=50, required=True)
- description = String()
-
- class BlogEntry(EntityType):
- title = String(required=True, fulltextindexed=True, maxsize=256)
- publish_date = Date(default='TODAY')
- content = String(required=True, fulltextindexed=True)
- entry_of = SubjectRelation('Blog', cardinality='?*')
-
-
-A Blog has a title and a description. The title is a string that is
-required by the class EntityType and must be less than 50 characters.
-The description is a string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a content. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The content is a string that will be indexed in
-the full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that links it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-
-Create your instance
---------------------
-
-::
-
- cubicweb-ctl create blog blogdemo
-
-
-This command will create a directory ``~/etc/cubicweb.d/blogdemo``
-which will contain all the configuration files required to start
-you web application.
-
-The instance ``blogdemo`` is based on the cube ``blog``.
-
-
-Welcome in your web application
--------------------------------
-
-Run your application with the following command: ::
-
- cubicweb-ctl start -D blogdemo
-
-
-You can now access to your web application to create blogs and post messages
-by visitin the URL http://localhost:8080/.
-A login form will first be prompted. By default, the application will not allow
-anonymous user to get in the application. You should then use the admin
-account you created at the time you initialized the database with
-``cubicweb-ctl create``.
-
-.. image:: images/login-form.png
-
-
-Once authenticated, you can start playing with your application
-and create entities. Bravo!
-
-.. image:: images/blog-demo-first-page.png
-
-Please notice that so far, `CubicWeb` franework managed all aspects of
-the web application based in the schema provided at first.
-
-
-Create entities
----------------
-
-We will now create a couple of entities in our web application.
-
-Create a Blog
-~~~~~~~~~~~~~
-
-Let us create a few of these entities. Click on the `[+]` at the right
-of the link Blog. Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the
-form by clicking on ``Validate``.
-
-.. image:: images/cbw-create-blog.en.png
- :alt: from to create blog
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link that will list for you all the existing Blog.
-You should be seeing a list with a single item ``Tech-blog`` you
-just created.
-
-.. image:: images/cbw-list-one-blog.en.png
- :alt: displaying a list of a single blog
-
-Clicking on this item will get you to its detailed description except
-that in this case, there is not much to display besides the name and
-the phrase ``everything about technology``.
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-.. image:: images/cbw-list-two-blog.en.png
- :alt: displaying a list of two blogs
-
-Create a BlogEntry
-~~~~~~~~~~~~~~~~~~
-
-Get back to the home page and click on [+] at the right of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``Validate``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``.
-
-You could also have, at the time you started to fill the form for a
-new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
-combobox titled ``add relation`` would have showed up.
-
-
-.. image:: images/cbw-add-relation-entryof.en.png
- :alt: editing a blog entry to add a relation to a blog
-
-Validate the changes by clicking ``Validate``. The entity BlogEntry
-that is displayed now includes a link to the entity Blog named
-``MyLife``.
-
-.. image:: images/cbw-detail-one-blogentry.en.png
- :alt: displaying the detailed view of a blogentry
-
-Please notice that so far, `CubicWeb` franework managed all aspects of
-the web application based in the schema provided at first.
-Also if you wish to get a graphical view of the schema, visit
-the link `Application schema`` which will direct you to :
-http://localhost:8080/view?vid=schema
-
-.. image:: images/cbw-schema.en.png
- :alt: graphical view of the schema (aka data-model)
-
-
-Define your entities views
---------------------------
-
-The views selection principle
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A view is defined by a Python class which includes:
-
- - an identifier (all objects in `CubicWeb` are entered in a registry
- and this identifier will be used as a key)
-
- - a filter to select the resulsets it can be applied to
-
-
-`CubicWeb` provides a lot of standard views for the type
-`EntityView`, for a complete list, you
-will have to read the code in directory ``cubicweb/web/views/``
-
-A view is applied on a `result set` which contains a set of
-entities we are trying to display. `CubicWeb` uses a selector
-mecanism which computes a score used to identify which view
-is the best to apply for the `result set` we are trying to
-display. The standard library of selectors is in
-``cubicweb.common.selector`` and a library of methods used to
-compute scores is available in ``cubicweb.vregistry.vreq``.
-
-It is possible to define multiple views for the same identifier
-and to associate selectors and filters to allow the application
-to find the best way to render the data. We will see more details
-on this in :ref:`DefinitionVues`.
-
-For example, the view named ``primary`` is the one used to display
-a single entity. We will now show you hos to customize this view.
-
-
-View customization
-~~~~~~~~~~~~~~~~~~
-
-If you wish to modify the way a `BlogEntry` is rendered, you will have to
-overwrite the `primary` view defined in the module ``views`` of the cube
-``cubes/blog/views.py``.
-
-We can by example add in front of the pulication date a prefix specifying
-the date we see is the publication date.
-
-To do so, please apply the following changes:
-
-::
-
- from cubicweb.web.views import baseviews
-
-
- class BlogEntryPrimaryView(baseviews.PrimaryView):
-
- accepts = ('BlogEntry',)
-
- def render_entity_title(self, entity):
- self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title()))
-
- def content_format(self, entity):
- return entity.view('reledit', rtype='content_format')
-
- def cell_call(self, row, col):
- entity = self.entity(row, col)
-
- # display entity attributes with prefixes
- self.w(u'<h1>%s</h1>' % entity.title)
- self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
- self.w(u'<p>%s</p>' % entity.content)
-
- # display relations
- siderelations = []
- if self.main_related_section:
- self.render_entity_relations(entity, siderelations)
-
-.. note::
- When a view is modified, it is not required to restart the application
- server. Save the Python file and reload the page in your web browser
- to view the changes.
-
-You can now see that the publication date has a prefix.
-
-.. image:: images/cbw-update-primary-view.en.png
- :alt: modified primary view
-
-
-The above source code defines a new primary view for
-``BlogEntry``.
-
-Since views are applied to resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates. We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. In our
-example we use it to output HTML tags and values of the entity's attributes.
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/02-00-foundation.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,567 @@
+.. -*- coding: utf-8 -*-
+
+`CubicWeb` concepts
+===================
+
+A little history...
+-------------------
+
+`CubicWeb` is a web application framework developped by Logilab_ since 2001.
+
+Entirely written in Python, `CubicWeb` publishes data from all sorts
+of sources such as SQL database, LDAP directory and versioning system such
+as subversion.
+
+`CubicWeb` user interface was designed to let the final user a huge flexibility
+on how to select and how to display content. It allows to browse the knowledge
+database and to display the results with the best rendering according to
+the context.
+This interface flexibility gives back the user the control of the
+rendering parameters that are usually reserved for developpers.
+
+
+We can list a couple of web applications developped with `CubicWeb`, an online
+public phone directory (see http://www.118000.fr/), a system for managing
+digital studies and simulations for a research lab, a tool for shared children
+babysitting (see http://garde-partagee.atoukontact.fr/), a tool to manage
+software developpment (see http://www.logilab.org), etc.
+
+In 2008, `CubicWeb` was ported for a new type of source : the datastore
+from GoogleAppEngine_.
+
+Global architecture
+-------------------
+.. image:: images/archi_globale.png
+
+.. note::
+ For real, the client and server sides are integrated in the same
+ process and interact directly, without the needs for distants
+ calls using Pyro. It is important to note down that those two
+ sides, client/server, are disjointed and it is possible to execute
+ a couple of calls in distincts processes to balance the load of
+ your web site on one or more machines.
+
+.. _TermsVocabulary:
+
+Terms and vocabulary
+--------------------
+
+*schema*
+ The schema defines the data model of an application based on entities
+ and relations, modeled with a comprehensive language made of Python
+ classes based on `yams`_ library. This is the core piece
+ of an application. It is initially defined in the file system and is
+ stored in the database at the time an instance is created. `CubicWeb`
+ provides a certain number of system entities included automatically as
+ it is necessarry for the core of `CubicWeb` and a library of
+ cubes that can be explicitely included if necessary.
+
+
+*entity type*
+ An entity is a set of attributes; the essential attribute of
+ an entity is its key, named eid
+
+*relation type*
+ Entities are linked to each others by relations. In `CubicWeb`
+ relations are binary: by convention we name the first item of
+ a relation the `subject` and the second the `object`.
+
+*final entity type*
+ Final types corresponds to the basic types such as string of characters,
+ integers... Those types have a main property which is that they can
+ only be used as `object` of a relation. The attributes of an entity
+ (non final) are entities (finals).
+
+*final relation type*
+ A relation is said final if its `object` is a final type. This is equivalent
+ to an entity attribute.
+
+*relation definition*
+ a relation definition is a 3-uple (subject entity type, relation type, object entity type),
+ with an associated set of property such as cardinality, constraints...
+
+*repository*
+ This is the RQL server side of `CubicWeb`. Be carefull not to get
+ confused with a Mercurial repository or a debian repository.
+
+*source*
+ A data source is a container of data (SGBD, LDAP directory, `Google
+ App Engine`'s datastore ...) integrated in the
+ `CubicWeb` repository. This repository has at least one source, `system` which
+ contains the schema of the application, plain-text index and others
+ vital informations for the system.
+
+*configuration*
+ It is possible to create differents configurations for an instance:
+
+ - ``repository`` : repository only, accessible for clients using Pyro
+ - ``twisted`` : web interface only, access the repository using Pyro
+ - ``all-in-one`` : web interface and repository in a single process.
+ The repository could be or not accessible using Pyro.
+
+*cube*
+ A cube is a model grouping one or multiple data types and/or views
+ to provide a specific functionnality or a complete `CubicWeb` application
+ potentially using other cubes. The available subes are located in the file
+ system at `/path/to/forest/cubicweb/cubes`.
+ Larger applications can be built faster by importing cubes,
+ adding entities and relationships and overriding the
+ views that need to display or edit informations not provided by
+ cubes.
+
+*instance*
+ An instance is a specific installation of a cube. All the required
+ configuration files necessarry for the well being of your web application
+ are grouped in an instance. This will refer to the cube(s) your application
+ is based on.
+ By example logilab.org and our intranet are two instances of a single
+ cube jpl, developped internally.
+ The instances are defined in the directory `~/etc/cubicweb.d`.
+
+*application*
+ The term application is sometime used to talk about an instance
+ and sometimes to talk of a cube depending on the context.
+ So we would like to avoid using this term and try to use *cube* and
+ *instance* instead.
+
+*result set*
+ This object contains the results of an RQL query sent to the source
+ and information on the query.
+
+*Pyro*
+ `Python Remote Object`_, distributed objects system similar to Java's RMI
+ (Remote Method Invocation), which can be used for the dialog between the web
+ side of the framework and the RQL repository.
+
+*query language*
+ A full-blown query language named RQL is used to formulate requests
+ to the database or any sources such as LDAP or `Google App Engine`'s
+ datastore.
+
+*views*
+ A view is applied to a `result set` to present it as HTML, XML,
+ JSON, CSV, etc. Views are implemented as Python classes. There is no
+ templating language.
+
+*generated user interface*
+ A user interface is generated on-the-fly from the schema definition:
+ entities can be created, displayed, updated and deleted. As display
+ views are not very fancy, it is usually necessary to develop your
+ own. Any generated view can be overridden by defining a new one with
+ the same identifier.
+
+
+.. _`Python Remote Object`: http://pyro.sourceforge.net/
+.. _`yams`: http://www.logilab.org/project/yams/
+
+
+`CubicWeb` engine
+-----------------
+
+The engine in `CubicWeb` is a set of classes managing a set of objects loaded
+dynamically at the startup of `CubicWeb` (*appobjects*). Those dynamics objects, based on the schema
+or the library, are building the final application. The differents dymanic components are
+by example:
+
+* client and server side
+
+ - entities definition, containing the logic which enables application data manipulation
+
+* client side
+
+ - *views*, or more specifically
+
+ - boxes
+ - header and footer
+ - forms
+ - page templates
+
+ - *actions*
+ - *controllers*
+
+* server side
+
+ - notification hooks
+ - notification views
+
+The components of the engine are:
+
+* a frontal web (only twisted is available so far), transparent for dynamic objects
+* an object that encapsulates the configuration
+* a `registry` (`cubicweb.cwvreg`) containing the dynamic objects loaded automatically
+
+Every *appobject* may access to the instance configuration using its *config* attribute
+and to the registry using its *vreg* attribute.
+
+Details of the recording process
+--------------------------------
+
+At startup, the `registry` or registers base, inspects a number of directories
+looking for compatible classes definition. After a recording process, the objects
+are assigned to registers so that they can be selected dynamically while the
+application is running.
+
+The base class of those objects is `AppRsetObject` (module `cubicweb.common.appobject`).
+
+XXX registers example
+XXX actual details of the recording process!
+
+Runtime objects selection
+-------------------------
+XXX tell why it's a cw foundation!
+
+Application objects are stored in the registry using a two level hierarchy :
+
+ object's `__registry__` : object's `id` : [list of app objects]
+
+The following rules are applied to select an object given a register and an id and an input context:
+* each object has a selector
+ - its selector may be derivated from a set of basic (or not :)
+ selectors using `chainall` or `chainfirst` combinators
+* a selector return a score >= 0
+* a score of 0 means the objects can't be applied to the input context
+* the object with the greatest score is selected. If multiple objects have an
+ identical score, one of them is selected randomly (this is usually a bug)
+
+The object's selector is the `__selector__` class method on the object's class.
+
+The score is used to choose the most pertinent objects where there are more than
+one selectable object. For instance, if you're selecting the primary
+(eg `id = 'primary'`) view (eg `__registry__ = 'view'`) for a result set containing
+a `Card` entity, 2 objects will probably be selectable:
+
+* the default primary view (`accepts = 'Any'`)
+* the specific `Card` primary view (`accepts = 'Card'`)
+
+This is because primary views are using the `accept_selector` which is considering the
+`accepts` class attribute of the object's class. Other primary views specific to other
+entity types won't be selectable in this case. And among selectable objects, the
+accept selector will return a higher score the the second view since it's more
+specific, so it will be selected as expected.
+
+Usually, you won't define it directly but by defining the `__selectors__` tuple
+on the class, with ::
+
+ __selectors__ = (sel1, sel2)
+
+which is equivalent to ::
+
+ __selector__ = chainall(sel1, sel2)
+
+The former is prefered since it's shorter and it's ease overriding in
+subclasses (you have access to sub-selectors instead of the wrapping function).
+
+:chainall(selectors...): if one selector return 0, return 0, else return the sum of scores
+
+:chainfirst(selectors...): return the score of the first selector which has a non zero score
+
+XXX describe standard selector (link to generated api doc!)
+
+Example
+~~~~~~~
+Le but final : quand on est sur un Blog, on veut que le lien rss de celui-ci pointe
+vers les entrées de ce blog, non vers l'entité blog elle-même.
+
+L'idée générale pour résoudre ça : on définit une méthode sur les classes d'entité
+qui renvoie l'url du flux rss pour l'entité en question. Avec une implémentation
+par défaut sur AnyEntity et une implémentation particulière sur Blog qui fera ce
+qu'on veut.
+
+La limitation : on est embêté dans le cas ou par ex. on a un result set qui contient
+plusieurs entités Blog (ou autre chose), car on ne sait pas sur quelle entité appeler
+la méthode sus-citée. Dans ce cas, on va conserver le comportement actuel (eg appel
+à limited_rql)
+
+Donc : on veut deux cas ici, l'un pour un rset qui contient une et une seule entité,
+l'autre pour un rset qui contient plusieurs entité.
+
+Donc... On a déja dans web/views/boxes.py la classe RSSIconBox qui fonctionne. Son
+sélecteur ::
+
+ class RSSIconBox(ExtResourcesBoxTemplate):
+ """just display the RSS icon on uniform result set"""
+ __selectors__ = ExtResourcesBoxTemplate.__selectors__ + (nfentity_selector,)
+
+
+indique qu'il prend en compte :
+
+* les conditions d'apparition de la boite (faut remonter dans les classes parentes
+ pour voir le détail)
+* nfentity_selector, qui filtre sur des rset contenant une liste d'entité non finale
+
+ça correspond donc à notre 2eme cas. Reste à fournir un composant plus spécifique
+pour le 1er cas ::
+
+ class EntityRSSIconBox(RSSIconBox):
+ """just display the RSS icon on uniform result set for a single entity"""
+ __selectors__ = RSSIconBox.__selectors__ + (onelinerset_selector,)
+
+
+Ici, on ajoute onelinerset_selector, qui filtre sur des rset de taille 1. Il faut
+savoir que quand on chaine des selecteurs, le score final est la somme des scores
+renvoyés par chaque sélecteur (sauf si l'un renvoie zéro, auquel cas l'objet est
+non sélectionnable). Donc ici, sur un rset avec plusieurs entités, onelinerset_selector
+rendra la classe EntityRSSIconBox non sélectionnable, et on obtiendra bien la
+classe RSSIconBox. Pour un rset avec une entité, la classe EntityRSSIconBox aura un
+score supérieur à RSSIconBox et c'est donc bien elle qui sera sélectionnée.
+
+Voili voilou, il reste donc pour finir tout ça :
+
+* à définir le contenu de la méthode call de EntityRSSIconBox
+* fournir l'implémentation par défaut de la méthode renvoyant l'url du flux rss sur
+ AnyEntity
+* surcharger cette methode dans blog.Blog
+
+When to use selectors?
+~~~~~~~~~~~~~~~~~~~~~~
+Il faut utiliser les sélecteurs pour faire des choses différentes en
+fonction de ce qu'on a en entrée. Dès qu'on a un "if" qui teste la
+nature de `self.rset` dans un objet, il faut très sérieusement se
+poser la question s'il ne vaut pas mieux avoir deux objets différent
+avec des sélecteurs approprié.
+
+If this is so fundamental, why don't I see them more often?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Because you're usually using base classes which are hiding the plumbing
+of __registry__ (almost always), id (often when using "standard" object),
+register and selector.
+
+API Python/RQL
+--------------
+
+Inspired from the standard db-api, with a Connection object having the methods
+cursor, rollback and commit essentially. The most important method is
+the `execute` method of a cursor :
+
+`execute(rqlstring, args=None, eid_key=None, build_descr=True)`
+
+:rqlstring: the RQL query to execute (unicode)
+:args: if the query contains substitutions, a dictionnary containing the values to use
+:eid_key:
+ an implementation detail of the RQL queries cache implies that if a substitution
+ is used to introduce an eid *susceptible to raise the ambiguities in the query
+ type resolution*, then we have to specify the correponding key in the dictionnary
+ through this argument
+
+
+The `Connection` object owns the methods `commit` and `rollback`. You *should
+never need to use them* during the development of the web interface based on
+the `CubicWeb` framework as it determines the end of the transaction depending
+on the query execution success.
+
+.. note::
+ While executing updates queries (SET, INSERT, DELETE), if a query generates
+ an error related to security, a rollback is automatically done on the current
+ transaction.
+
+
+The `Request` class (`cubicweb.web`)
+------------------------------------
+
+A request instance is created when an HTPP request is sent to the web server.
+It contains informations such as forms parameters, user authenticated, etc.
+
+**Globally, a request represents a user query, either through HTTP or not
+(we also talk about RQL queries on the server side by example)**
+
+An instance of `Request` has the following attributes:
+
+* `user`, instance of `cubicweb.common.utils.User` corresponding to the authenticated
+ user
+* `form`, dictionnary containing the values of a web form
+* `encoding`, characters encoding to use in the response
+
+But also:
+
+:Session data handling:
+ * `session_data()`, returns a dictinnary containing all the session data
+ * `get_session_data(key, default=None)`, returns a value associated to the given
+ key or the value `default` if the key is not defined
+ * `set_session_data(key, value)`, assign a value to a key
+ * `del_session_data(key)`, suppress the value associated to a key
+
+
+:Cookies handling:
+ * `get_cookie()`, returns a dictionnary containing the value of the header
+ HTTP 'Cookie'
+ * `set_cookie(cookie, key, maxage=300)`, adds a header HTTP `Set-Cookie`,
+ with a minimal 5 minutes length of duration by default (`maxage` = None
+ returns a *session* cookie which will expire when the user closes the browser
+ window
+ * `remove_cookie(cookie, key)`, forces a value to expire
+
+:URL handling:
+ * `url()`, returns the full URL of the HTTP request
+ * `base_url()`, returns the root URL of the web application
+ * `relative_path()`, returns the relative path of the request
+
+:And more...:
+ * `set_content_type(content_type, filename=None)`, adds the header HTTP
+ 'Content-Type'
+ * `get_header(header)`, returns the value associated to an arbitrary header
+ of the HTTP request
+ * `set_header(header, value)`, adds an arbitrary header in the response
+ * `cursor()` returns a RQL cursor on the session
+ * `execute(*args, **kwargs)`, shortcut to ``.cursor().execute()``
+ * `property_value(key)`, properties management (`EProperty`)
+ * dictionnary `data` to store data to share informations between components
+ *while a request is executed*
+
+Please note down that this class is abstract and that a concrete implementation
+will be provided by the *frontend* web used (in particular *twisted* as of
+today). For the views or others that are executed on the server side,
+most of the interface of `Request` is defined in the session associated
+to the client.
+
+The `AppObject` class
+---------------------
+
+In general:
+
+* we do not inherit directly from this class but from a more specific
+ class such as `AnyEntity`, `EntityView`, `AnyRsetView`,
+ `Action`...
+
+* to be recordable, a subclass has to define its own register (attribute
+ `__registry__`) and its identifier (attribute `id`). Usually we do not have
+ to take care of the register, only the identifier `id`.
+
+We can find a certain number of attributes and methods defined in this class
+and so common to all the application objects:
+
+At the recording, the following attributes are dynamically added to
+the *subclasses*:
+
+* `vreg`, the `vregistry` of the application
+* `schema`, the application schema
+* `config`, the application configuration
+
+We also find on instances, the following attributes:
+
+* `req`, `Request` instance
+* `rset`, the *result set* associated to the object if necessarry
+* `cursor`, rql cursor on the session
+
+
+:URL handling:
+ * `build_url(method=None, **kwargs)`, returns an absolute URL based on
+ the given arguments. The *controller* supposed to handle the response
+ can be specified through the special parameter `method` (the connection
+ is theoretically done automatically :).
+
+ * `datadir_url()`, returns the directory of the application data
+ (contains static files such as images, css, js...)
+
+ * `base_url()`, shortcut to `req.base_url()`
+
+ * `url_quote(value)`, version *unicode safe* of the function `urllib.quote`
+
+:Data manipulation:
+
+ * `etype_rset(etype, size=1)`, shortcut to `vreg.etype_rset()`
+
+ * `eid_rset(eid, rql=None, descr=True)`, returns a *result set* object for
+ the given eid
+ * `entity(row, col=0)`, returns the entity corresponding to the data position
+ in the *result set* associated to the object
+
+ * `complete_entity(row, col=0, skip_bytes=True)`, is equivalent to `entity` but
+ also call the method `complete()` on the entity before returning it
+
+:Data formatting:
+ * `format_date(date, date_format=None, time=False)`
+ * `format_time(time)`
+
+:And more...:
+
+ * `external_resource(rid, default=_MARKER)`, access to a value defined in the
+ configuration file `external_resource`
+
+ * `tal_render(template, variables)`,
+
+
+.. note::
+ When we inherit from `AppObject` (even not directly), you *always* have to use
+ **super()** to get the methods and attributes of the superclasses, and not
+ use the class identifier.
+ By example, instead of writting: ::
+
+ class Truc(PrimaryView):
+ def f(self, arg1):
+ PrimaryView.f(self, arg1)
+
+ You'd better write: ::
+
+ class Truc(PrimaryView):
+ def f(self, arg1):
+ super(Truc, self).f(arg1)
+
+
+Standard structure for a cube
+-----------------------------
+
+A complex cube is structured as follows:
+
+::
+
+ mycube/
+ |
+ |-- schema.py
+ |
+ |-- entities/
+ |
+ |-- sobjects/
+ |
+ |-- views/
+ |
+ |-- test/
+ |
+ |-- i18n/
+ |
+ |-- data/
+ |
+ |-- migration/
+ | |- postcreate.py
+ | \- depends.map
+ |
+ |-- debian/
+ |
+ \-- __pkginfo__.py
+
+We can use simple Python module instead of packages, by example:
+
+::
+
+ mycube/
+ |
+ |-- entities.py
+ |-- hooks.py
+ \-- views.py
+
+
+where :
+
+* ``schema`` contains the schema definition (server side only)
+* ``entities`` contains the entities definition (server side and web interface)
+* ``sobjects`` contains hooks and/or views notifications (server side only)
+* ``views`` contains the different components of the web interface (web interface only)
+* ``test`` contains tests specifics to the application (not installed)
+* ``i18n`` contains the messages catalog for supported languages (server side and
+ web interface)
+* ``data`` contains arbitrary data files served statically
+ (images, css, javascripts files)... (web interface only)
+* ``migration`` contains the initialization file for new instances
+ (``postcreate.py``) and in general a file containing the `CubicWeb` dependancies
+ of the cube depending on its version (``depends.map``)
+* ``debian`` contains all the files that manages the debian packaging
+ (you would find there the classical structure with ``control``, ``rules``,
+ ``changelog``... (not installed)
+* the file ``__pkginfo__.py`` provides meta-data on the cube, especially the
+ distribution name and the current version (server side and web interface) or
+ also the sub-cubes used by this cube
+
+The only required files are:
+
+* the file ``__pkginfo__.py``
+* the schema definition
+ XXX false, we may want to have cubes which are only adding a service, no persistent data (eg embeding for instance)
--- a/doc/book/en/02-foundation.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,567 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-`CubicWeb` concepts
-===================
-
-A little history...
--------------------
-
-`CubicWeb` is a web application framework developped by Logilab_ since 2001.
-
-Entirely written in Python, `CubicWeb` publishes data from all sorts
-of sources such as SQL database, LDAP directory and versioning system such
-as subversion.
-
-`CubicWeb` user interface was designed to let the final user a huge flexibility
-on how to select and how to display content. It allows to browse the knowledge
-database and to display the results with the best rendering according to
-the context.
-This interface flexibility gives back the user the control of the
-rendering parameters that are usually reserved for developpers.
-
-
-We can list a couple of web applications developped with `CubicWeb`, an online
-public phone directory (see http://www.118000.fr/), a system for managing
-digital studies and simulations for a research lab, a tool for shared children
-babysitting (see http://garde-partagee.atoukontact.fr/), a tool to manage
-software developpment (see http://www.logilab.org), etc.
-
-In 2008, `CubicWeb` was ported for a new type of source : the datastore
-from GoogleAppEngine_.
-
-Global architecture
--------------------
-.. image:: images/archi_globale.png
-
-.. note::
- For real, the client and server sides are integrated in the same
- process and interact directly, without the needs for distants
- calls using Pyro. It is important to note down that those two
- sides, client/server, are disjointed and it is possible to execute
- a couple of calls in distincts processes to balance the load of
- your web site on one or more machines.
-
-.. _TermsVocabulary:
-
-Terms and vocabulary
---------------------
-
-*schema*
- The schema defines the data model of an application based on entities
- and relations, modeled with a comprehensive language made of Python
- classes based on `yams`_ library. This is the core piece
- of an application. It is initially defined in the file system and is
- stored in the database at the time an instance is created. `CubicWeb`
- provides a certain number of system entities included automatically as
- it is necessarry for the core of `CubicWeb` and a library of
- cubes that can be explicitely included if necessary.
-
-
-*entity type*
- An entity is a set of attributes; the essential attribute of
- an entity is its key, named eid
-
-*relation type*
- Entities are linked to each others by relations. In `CubicWeb`
- relations are binary: by convention we name the first item of
- a relation the `subject` and the second the `object`.
-
-*final entity type*
- Final types corresponds to the basic types such as string of characters,
- integers... Those types have a main property which is that they can
- only be used as `object` of a relation. The attributes of an entity
- (non final) are entities (finals).
-
-*final relation type*
- A relation is said final if its `object` is a final type. This is equivalent
- to an entity attribute.
-
-*relation definition*
- a relation definition is a 3-uple (subject entity type, relation type, object entity type),
- with an associated set of property such as cardinality, constraints...
-
-*repository*
- This is the RQL server side of `CubicWeb`. Be carefull not to get
- confused with a Mercurial repository or a debian repository.
-
-*source*
- A data source is a container of data (SGBD, LDAP directory, `Google
- App Engine`'s datastore ...) integrated in the
- `CubicWeb` repository. This repository has at least one source, `system` which
- contains the schema of the application, plain-text index and others
- vital informations for the system.
-
-*configuration*
- It is possible to create differents configurations for an instance:
-
- - ``repository`` : repository only, accessible for clients using Pyro
- - ``twisted`` : web interface only, access the repository using Pyro
- - ``all-in-one`` : web interface and repository in a single process.
- The repository could be or not accessible using Pyro.
-
-*cube*
- A cube is a model grouping one or multiple data types and/or views
- to provide a specific functionnality or a complete `CubicWeb` application
- potentially using other cubes. The available subes are located in the file
- system at `/path/to/forest/cubicweb/cubes`.
- Larger applications can be built faster by importing cubes,
- adding entities and relationships and overriding the
- views that need to display or edit informations not provided by
- cubes.
-
-*instance*
- An instance is a specific installation of a cube. All the required
- configuration files necessarry for the well being of your web application
- are grouped in an instance. This will refer to the cube(s) your application
- is based on.
- By example logilab.org and our intranet are two instances of a single
- cube jpl, developped internally.
- The instances are defined in the directory `~/etc/cubicweb.d`.
-
-*application*
- The term application is sometime used to talk about an instance
- and sometimes to talk of a cube depending on the context.
- So we would like to avoid using this term and try to use *cube* and
- *instance* instead.
-
-*result set*
- This object contains the results of an RQL query sent to the source
- and information on the query.
-
-*Pyro*
- `Python Remote Object`_, distributed objects system similar to Java's RMI
- (Remote Method Invocation), which can be used for the dialog between the web
- side of the framework and the RQL repository.
-
-*query language*
- A full-blown query language named RQL is used to formulate requests
- to the database or any sources such as LDAP or `Google App Engine`'s
- datastore.
-
-*views*
- A view is applied to a `result set` to present it as HTML, XML,
- JSON, CSV, etc. Views are implemented as Python classes. There is no
- templating language.
-
-*generated user interface*
- A user interface is generated on-the-fly from the schema definition:
- entities can be created, displayed, updated and deleted. As display
- views are not very fancy, it is usually necessary to develop your
- own. Any generated view can be overridden by defining a new one with
- the same identifier.
-
-
-.. _`Python Remote Object`: http://pyro.sourceforge.net/
-.. _`yams`: http://www.logilab.org/project/yams/
-
-
-`CubicWeb` engine
------------------
-
-The engine in `CubicWeb` is a set of classes managing a set of objects loaded
-dynamically at the startup of `CubicWeb` (*appobjects*). Those dynamics objects, based on the schema
-or the library, are building the final application. The differents dymanic components are
-by example:
-
-* client and server side
-
- - entities definition, containing the logic which enables application data manipulation
-
-* client side
-
- - *views*, or more specifically
-
- - boxes
- - header and footer
- - forms
- - page templates
-
- - *actions*
- - *controllers*
-
-* server side
-
- - notification hooks
- - notification views
-
-The components of the engine are:
-
-* a frontal web (only twisted is available so far), transparent for dynamic objects
-* an object that encapsulates the configuration
-* a `registry` (`cubicweb.cwvreg`) containing the dynamic objects loaded automatically
-
-Every *appobject* may access to the instance configuration using its *config* attribute
-and to the registry using its *vreg* attribute.
-
-Details of the recording process
---------------------------------
-
-At startup, the `registry` or registers base, inspects a number of directories
-looking for compatible classes definition. After a recording process, the objects
-are assigned to registers so that they can be selected dynamically while the
-application is running.
-
-The base class of those objects is `AppRsetObject` (module `cubicweb.common.appobject`).
-
-XXX registers example
-XXX actual details of the recording process!
-
-Runtime objects selection
--------------------------
-XXX tell why it's a cw foundation!
-
-Application objects are stored in the registry using a two level hierarchy :
-
- object's `__registry__` : object's `id` : [list of app objects]
-
-The following rules are applied to select an object given a register and an id and an input context:
-* each object has a selector
- - its selector may be derivated from a set of basic (or not :)
- selectors using `chainall` or `chainfirst` combinators
-* a selector return a score >= 0
-* a score of 0 means the objects can't be applied to the input context
-* the object with the greatest score is selected. If multiple objects have an
- identical score, one of them is selected randomly (this is usually a bug)
-
-The object's selector is the `__selector__` class method on the object's class.
-
-The score is used to choose the most pertinent objects where there are more than
-one selectable object. For instance, if you're selecting the primary
-(eg `id = 'primary'`) view (eg `__registry__ = 'view'`) for a result set containing
-a `Card` entity, 2 objects will probably be selectable:
-
-* the default primary view (`accepts = 'Any'`)
-* the specific `Card` primary view (`accepts = 'Card'`)
-
-This is because primary views are using the `accept_selector` which is considering the
-`accepts` class attribute of the object's class. Other primary views specific to other
-entity types won't be selectable in this case. And among selectable objects, the
-accept selector will return a higher score the the second view since it's more
-specific, so it will be selected as expected.
-
-Usually, you won't define it directly but by defining the `__selectors__` tuple
-on the class, with ::
-
- __selectors__ = (sel1, sel2)
-
-which is equivalent to ::
-
- __selector__ = chainall(sel1, sel2)
-
-The former is prefered since it's shorter and it's ease overriding in
-subclasses (you have access to sub-selectors instead of the wrapping function).
-
-:chainall(selectors...): if one selector return 0, return 0, else return the sum of scores
-
-:chainfirst(selectors...): return the score of the first selector which has a non zero score
-
-XXX describe standard selector (link to generated api doc!)
-
-Example
-~~~~~~~
-Le but final : quand on est sur un Blog, on veut que le lien rss de celui-ci pointe
-vers les entrées de ce blog, non vers l'entité blog elle-même.
-
-L'idée générale pour résoudre ça : on définit une méthode sur les classes d'entité
-qui renvoie l'url du flux rss pour l'entité en question. Avec une implémentation
-par défaut sur AnyEntity et une implémentation particulière sur Blog qui fera ce
-qu'on veut.
-
-La limitation : on est embêté dans le cas ou par ex. on a un result set qui contient
-plusieurs entités Blog (ou autre chose), car on ne sait pas sur quelle entité appeler
-la méthode sus-citée. Dans ce cas, on va conserver le comportement actuel (eg appel
-à limited_rql)
-
-Donc : on veut deux cas ici, l'un pour un rset qui contient une et une seule entité,
-l'autre pour un rset qui contient plusieurs entité.
-
-Donc... On a déja dans web/views/boxes.py la classe RSSIconBox qui fonctionne. Son
-sélecteur ::
-
- class RSSIconBox(ExtResourcesBoxTemplate):
- """just display the RSS icon on uniform result set"""
- __selectors__ = ExtResourcesBoxTemplate.__selectors__ + (nfentity_selector,)
-
-
-indique qu'il prend en compte :
-
-* les conditions d'apparition de la boite (faut remonter dans les classes parentes
- pour voir le détail)
-* nfentity_selector, qui filtre sur des rset contenant une liste d'entité non finale
-
-ça correspond donc à notre 2eme cas. Reste à fournir un composant plus spécifique
-pour le 1er cas ::
-
- class EntityRSSIconBox(RSSIconBox):
- """just display the RSS icon on uniform result set for a single entity"""
- __selectors__ = RSSIconBox.__selectors__ + (onelinerset_selector,)
-
-
-Ici, on ajoute onelinerset_selector, qui filtre sur des rset de taille 1. Il faut
-savoir que quand on chaine des selecteurs, le score final est la somme des scores
-renvoyés par chaque sélecteur (sauf si l'un renvoie zéro, auquel cas l'objet est
-non sélectionnable). Donc ici, sur un rset avec plusieurs entités, onelinerset_selector
-rendra la classe EntityRSSIconBox non sélectionnable, et on obtiendra bien la
-classe RSSIconBox. Pour un rset avec une entité, la classe EntityRSSIconBox aura un
-score supérieur à RSSIconBox et c'est donc bien elle qui sera sélectionnée.
-
-Voili voilou, il reste donc pour finir tout ça :
-
-* à définir le contenu de la méthode call de EntityRSSIconBox
-* fournir l'implémentation par défaut de la méthode renvoyant l'url du flux rss sur
- AnyEntity
-* surcharger cette methode dans blog.Blog
-
-When to use selectors?
-~~~~~~~~~~~~~~~~~~~~~~
-Il faut utiliser les sélecteurs pour faire des choses différentes en
-fonction de ce qu'on a en entrée. Dès qu'on a un "if" qui teste la
-nature de `self.rset` dans un objet, il faut très sérieusement se
-poser la question s'il ne vaut pas mieux avoir deux objets différent
-avec des sélecteurs approprié.
-
-If this is so fundamental, why don't I see them more often?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Because you're usually using base classes which are hiding the plumbing
-of __registry__ (almost always), id (often when using "standard" object),
-register and selector.
-
-API Python/RQL
---------------
-
-Inspired from the standard db-api, with a Connection object having the methods
-cursor, rollback and commit essentially. The most important method is
-the `execute` method of a cursor :
-
-`execute(rqlstring, args=None, eid_key=None, build_descr=True)`
-
-:rqlstring: the RQL query to execute (unicode)
-:args: if the query contains substitutions, a dictionnary containing the values to use
-:eid_key:
- an implementation detail of the RQL queries cache implies that if a substitution
- is used to introduce an eid *susceptible to raise the ambiguities in the query
- type resolution*, then we have to specify the correponding key in the dictionnary
- through this argument
-
-
-The `Connection` object owns the methods `commit` and `rollback`. You *should
-never need to use them* during the development of the web interface based on
-the `CubicWeb` framework as it determines the end of the transaction depending
-on the query execution success.
-
-.. note::
- While executing updates queries (SET, INSERT, DELETE), if a query generates
- an error related to security, a rollback is automatically done on the current
- transaction.
-
-
-The `Request` class (`cubicweb.web`)
-------------------------------------
-
-A request instance is created when an HTPP request is sent to the web server.
-It contains informations such as forms parameters, user authenticated, etc.
-
-**Globally, a request represents a user query, either through HTTP or not
-(we also talk about RQL queries on the server side by example)**
-
-An instance of `Request` has the following attributes:
-
-* `user`, instance of `cubicweb.common.utils.User` corresponding to the authenticated
- user
-* `form`, dictionnary containing the values of a web form
-* `encoding`, characters encoding to use in the response
-
-But also:
-
-:Session data handling:
- * `session_data()`, returns a dictinnary containing all the session data
- * `get_session_data(key, default=None)`, returns a value associated to the given
- key or the value `default` if the key is not defined
- * `set_session_data(key, value)`, assign a value to a key
- * `del_session_data(key)`, suppress the value associated to a key
-
-
-:Cookies handling:
- * `get_cookie()`, returns a dictionnary containing the value of the header
- HTTP 'Cookie'
- * `set_cookie(cookie, key, maxage=300)`, adds a header HTTP `Set-Cookie`,
- with a minimal 5 minutes length of duration by default (`maxage` = None
- returns a *session* cookie which will expire when the user closes the browser
- window
- * `remove_cookie(cookie, key)`, forces a value to expire
-
-:URL handling:
- * `url()`, returns the full URL of the HTTP request
- * `base_url()`, returns the root URL of the web application
- * `relative_path()`, returns the relative path of the request
-
-:And more...:
- * `set_content_type(content_type, filename=None)`, adds the header HTTP
- 'Content-Type'
- * `get_header(header)`, returns the value associated to an arbitrary header
- of the HTTP request
- * `set_header(header, value)`, adds an arbitrary header in the response
- * `cursor()` returns a RQL cursor on the session
- * `execute(*args, **kwargs)`, shortcut to ``.cursor().execute()``
- * `property_value(key)`, properties management (`EProperty`)
- * dictionnary `data` to store data to share informations between components
- *while a request is executed*
-
-Please note down that this class is abstract and that a concrete implementation
-will be provided by the *frontend* web used (in particular *twisted* as of
-today). For the views or others that are executed on the server side,
-most of the interface of `Request` is defined in the session associated
-to the client.
-
-The `AppObject` class
----------------------
-
-In general:
-
-* we do not inherit directly from this class but from a more specific
- class such as `AnyEntity`, `EntityView`, `AnyRsetView`,
- `Action`...
-
-* to be recordable, a subclass has to define its own register (attribute
- `__registry__`) and its identifier (attribute `id`). Usually we do not have
- to take care of the register, only the identifier `id`.
-
-We can find a certain number of attributes and methods defined in this class
-and so common to all the application objects:
-
-At the recording, the following attributes are dynamically added to
-the *subclasses*:
-
-* `vreg`, the `vregistry` of the application
-* `schema`, the application schema
-* `config`, the application configuration
-
-We also find on instances, the following attributes:
-
-* `req`, `Request` instance
-* `rset`, the *result set* associated to the object if necessarry
-* `cursor`, rql cursor on the session
-
-
-:URL handling:
- * `build_url(method=None, **kwargs)`, returns an absolute URL based on
- the given arguments. The *controller* supposed to handle the response
- can be specified through the special parameter `method` (the connection
- is theoretically done automatically :).
-
- * `datadir_url()`, returns the directory of the application data
- (contains static files such as images, css, js...)
-
- * `base_url()`, shortcut to `req.base_url()`
-
- * `url_quote(value)`, version *unicode safe* of the function `urllib.quote`
-
-:Data manipulation:
-
- * `etype_rset(etype, size=1)`, shortcut to `vreg.etype_rset()`
-
- * `eid_rset(eid, rql=None, descr=True)`, returns a *result set* object for
- the given eid
- * `entity(row, col=0)`, returns the entity corresponding to the data position
- in the *result set* associated to the object
-
- * `complete_entity(row, col=0, skip_bytes=True)`, is equivalent to `entity` but
- also call the method `complete()` on the entity before returning it
-
-:Data formatting:
- * `format_date(date, date_format=None, time=False)`
- * `format_time(time)`
-
-:And more...:
-
- * `external_resource(rid, default=_MARKER)`, access to a value defined in the
- configuration file `external_resource`
-
- * `tal_render(template, variables)`,
-
-
-.. note::
- When we inherit from `AppObject` (even not directly), you *always* have to use
- **super()** to get the methods and attributes of the superclasses, and not
- use the class identifier.
- By example, instead of writting: ::
-
- class Truc(PrimaryView):
- def f(self, arg1):
- PrimaryView.f(self, arg1)
-
- You'd better write: ::
-
- class Truc(PrimaryView):
- def f(self, arg1):
- super(Truc, self).f(arg1)
-
-
-Standard structure for a cube
------------------------------
-
-A complex cube is structured as follows:
-
-::
-
- mycube/
- |
- |-- schema.py
- |
- |-- entities/
- |
- |-- sobjects/
- |
- |-- views/
- |
- |-- test/
- |
- |-- i18n/
- |
- |-- data/
- |
- |-- migration/
- | |- postcreate.py
- | \- depends.map
- |
- |-- debian/
- |
- \-- __pkginfo__.py
-
-We can use simple Python module instead of packages, by example:
-
-::
-
- mycube/
- |
- |-- entities.py
- |-- hooks.py
- \-- views.py
-
-
-where :
-
-* ``schema`` contains the schema definition (server side only)
-* ``entities`` contains the entities definition (server side and web interface)
-* ``sobjects`` contains hooks and/or views notifications (server side only)
-* ``views`` contains the different components of the web interface (web interface only)
-* ``test`` contains tests specifics to the application (not installed)
-* ``i18n`` contains the messages catalog for supported languages (server side and
- web interface)
-* ``data`` contains arbitrary data files served statically
- (images, css, javascripts files)... (web interface only)
-* ``migration`` contains the initialization file for new instances
- (``postcreate.py``) and in general a file containing the `CubicWeb` dependancies
- of the cube depending on its version (``depends.map``)
-* ``debian`` contains all the files that manages the debian packaging
- (you would find there the classical structure with ``control``, ``rules``,
- ``changelog``... (not installed)
-* the file ``__pkginfo__.py`` provides meta-data on the cube, especially the
- distribution name and the current version (server side and web interface) or
- also the sub-cubes used by this cube
-
-The only required files are:
-
-* the file ``__pkginfo__.py``
-* the schema definition
- XXX false, we may want to have cubes which are only adding a service, no persistent data (eg embeding for instance)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-00-definition-schema.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,20 @@
+.. -*- coding: utf-8 -*-
+
+Data Model definition (*schema*)
+================================
+
+The schema is the main concept of `LAX` applications as it defines the
+data model we will handle. It is based on entities types already defined
+in the library and others, more specific, we would expect to find in one or
+more Python files under the `schema` directory.
+
+It is important to make clear the difference between relation type and relation
+definition: a relation type is only a relation name with potentially other
+additionnal properties (see XXXX), whereas a relation definition is a complete
+triplet "<subject entity type> <relation type> <object entity type>". A relation
+type could have been implied if none is related to a relation definition of the
+schema.
+
+
+.. include:: 03-sect-stdlib-schemas.en.txt
+.. include:: 03-sect-definition-schema.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-00-sect-definition-schema.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,344 @@
+.. -*- coding: utf-8 -*-
+
+Entity type definition
+----------------------
+
+An entity type is defined by a Python class which inherits `EntityType`. The
+class name correponds to the type name. Then the content of the class contains
+the description of attributes and relations for the defined entity type,
+by example ::
+
+ class Personne(EntityType):
+ """A person with the properties and the relations necessarry for my
+ application"""
+
+ last_name = String(required=True, fulltextindexed=True)
+ first_name = String(required=True, fulltextindexed=True)
+ title = String(vocabulary=('M', 'Mme', 'Mlle'))
+ date_of_birth = Date()
+ works_for = SubjectRelation('Company', cardinality='?*')
+
+* the name of the Python attribute corresponds to the name of the attribute
+ or the relation in `LAX` application.
+
+* all built-in types are available: `String`, `Int`, `Float`,
+ `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
+
+* each entity has at least the following meta-relations:
+
+ - `eid` (`Int`)
+
+ - `creation_date` (`Datetime`)
+
+ - `modification_date` (`Datetime`)
+
+ - `created_by` (`EUser`) (which user created the entity)
+
+ - `owned_by` (`EUser`) (who does the entity belongs to, by default the
+ creator but not necessarry and it could have multiple owners)
+
+ - `is` (`EEType`)
+
+
+* it is also possible to define relations of type object by using `ObjectRelation`
+ instead of `SubjectRelation`
+
+* the first argument of `SubjectRelation` and `ObjectRelation` gives respectively
+ the object/subject entity type of the relation. This could be:
+
+ * a string corresponding to an entity type
+
+ * a tuple of string correponding to multiple entities types
+
+ * special string such as follows:
+
+ - "**" : all types of entities
+ - "*" : all types of entities non meta
+ - "@" : all types of meta entities but not system entities (e.g. used for
+ the basis schema description)
+
+* it is possible to use the attribute `meta` to flag an entity type as a `meta`
+ (e.g. used to describe/categorize other entities)
+
+* optional properties for attributes and relations:
+
+ - `description` : string describing an attribute or a relation. By default
+ this string will be used in the editing form of the entity, which means
+ that it is supposed to help the end-user and should be flagged by the
+ function `_` to be properly internationalized.
+
+ - `constraints` : list of conditions/constraints that the relation needs to
+ satisfy (c.f. `Contraints`_)
+
+ - `cardinality` : two characters string which specify the cardinality of the
+ relation. The first character defines the cardinality of the relation on
+ the subject, the second on the object of the relation. When a relation
+ has multiple possible subjects or objects, the cardinality applies to all
+ and not on a one to one basis (so it must be consistent...). The possible
+ values are inspired from regular expressions syntax:
+
+ * `1`: 1..1
+ * `?`: 0..1
+ * `+`: 1..n
+ * `*`: 0..n
+
+ - `meta` : boolean indicating that the relation is a meta-relation (false by
+ default)
+
+* optionnal properties for attributes:
+
+ - `required` : boolean indicating if the attribute is required (false by default)
+
+ - `unique` : boolean indicating if the value of the attribute has to be unique
+ or not within all entities of the same type (false by default)
+
+ - `indexed` : boolean indicating if an index needs to be created for this
+ attribute in the database (false by default). This is usefull only if
+ you know that you will have to run numerous searches on the value of this
+ attribute.
+
+ - `default` : default value of the attribute. In case of date types, the values
+ which could be used correpond to the RQL keywords `TODAY` and `NOW`.
+
+ - `vocabulary` : specify static possible values of an attribute
+
+* optionnal properties of type `String`:
+
+ - `fulltextindexed` : boolean indicating if the attribute is part of
+ the full text index (false by default) (*applicable on the type `Byte`
+ as well*)
+
+ - `internationalizable` : boolean indicating if the value of the attribute
+ is internationalizable (false by default)
+
+ - `maxsize` : integer providing the maximum size of the string (no limit by default)
+
+* optionnal properties for relations:
+
+ - `composite` : string indicating that the subject (composite == 'subject')
+ is composed of the objects of the relations. For the opposite case (when
+ the object is composed of the subjects of the relation), we just need
+ to set 'object' as the value. The composition implies that when the relation
+ is deleted (so when the composite is deleted), the composed are also deleted.
+ [PAS CLAIR]
+
+Contraints
+``````````
+By default, the available constraints types are:
+
+* `SizeConstraint` : allows to specify a minimum and/or maximum size on
+ string (generic case of `maxsize`)
+
+* `BoundConstraint` : allows to specify a minimum and/or maximum value on
+ numeric types
+
+* `UniqueConstraint` : identical to "unique=True"
+
+* `StaticVocabularyConstraint` : identical to "vocabulary=(...)"
+
+* `RQLConstraint` : allows to specify a RQL query that needs to be satisfied
+ by the subject and/or the object of the relation. In this query the variables
+ `S` and `O` are reserved for the entities subject and object of the
+ relation.
+
+* `RQLVocabularyConstraint` : similar to the previous type of constraint except
+ that it does not express a "strong" constraint, which means it is only used to
+ restrict the values listed in the drop-down menu of editing form, but it does
+ not prevent another entity to be selected
+ [PAS CLAIR]
+
+
+Relation type definition
+------------------------
+
+A relation is defined by a Python class heriting `RelationType`. The name
+of the class corresponds to the name of the type. The class then contains
+a description of the properties of this type of relation, as well as a
+string for the subject and a string for the object. This allows to create
+new definition of associated relations, (so that the class can have the
+definition properties from the relation)[PAS CLAIR] by example ::
+
+ class locked_by(RelationType):
+ """relation on all entities indicating that they are locked"""
+ inlined = True
+ cardinality = '?*'
+ subject = '*'
+ object = 'EUser'
+
+In addition to the permissions, the own properties of the relation types
+(shared also by all definition of relation of this type) are:
+
+
+* `inlined` : boolean handling the physical optimization for archiving
+ the relation in the subject entity table, instead of creating a specific
+ table for the relation. This applies to the relation when the cardinality
+ of subject->relation->object is 0..1 ('?') or 1..1 ('1')
+
+* `symetric` : boolean indication that the relation is symetrical, which
+ means `X relation Y` implies `Y relation X`
+
+In the case of simultaneous relations definitions, `subject` and `object`
+can both be equal to the value of the first argument of `SubjectRelation`
+and `ObjectRelation`.
+
+When a relation is not inlined and not symetrical, and it does not require
+specific permissions, its definition (by using `SubjectRelation` and
+`ObjectRelation`) is all we need.
+
+Permissions definition
+----------------------
+
+Define permissions is set through to the attribute `permissions` of entities and
+relations types. It defines a dictionnary where the keys are the access types
+(action), and the values are the authorized groups or expressions.
+
+For an entity type, the possible actions are `read`, `add`, `update` and
+`delete`.
+
+For a relation type, the possible actions are `read`, `add`, and `delete`.
+
+For each access type, a tuple indicates the name of the authorized groups and/or
+one or multiple RQL expressions to satisfy to grant access. The access is
+provided once the user is in the listed groups or one of the RQL condition is
+satisfied.
+
+The standard groups are:
+
+* `guests`
+
+* `users`
+
+* `managers`
+
+* `owners` : virtual group corresponding to the entity's owner.
+ This can only be used for the actions `update` and `delete` of an entity
+ type.
+
+It is also possible to use specific groups if they are define in the precreate
+of the application (``migration/precreate.py``).
+
+Use of RQL expression for writing rights
+````````````````````````````````````````
+It is possible to define RQL expression to provide update permission
+(`add`, `delete` and `update`) on relation and entity types.
+
+RQL expression for entity type permission:
+
+* you have to use the class `ERQLExpression`
+
+* the used expression corresponds to the WHERE statement of an RQL query
+
+* in this expression, the variables X and U are pre-defined references
+ respectively on the current entity (on which the action is verified) and
+ on the user who send the request
+
+* it is possible to use, in this expression, a special relation
+ "has_<ACTION>_permission" where the subject is the user and the
+ object is a any variable, meaning that the user needs to have
+ permission to execute the action <ACTION> on the entities related
+ to this variable
+
+For RQL expressions on a relation type, the principles are the same except
+for the following:
+
+* you have to use the class `RQLExpression` in the case of a non-final relation
+ [WHAT IS A NON FINALE RELATION]
+
+* in the expression, the variables S, O and U are pre-defined references
+ to respectively the subject and the object of the current relation (on
+ which the action is being verified) and the user who executed the query
+
+* we can also defined rights on attributes of an entity (non-final relation),
+ knowing that:
+
+ - to defines RQL expression, we have to use the class `ERQLExpression`
+ in which X represents the entity the attribute belongs to
+
+ - the permissions `add` and `delete` are equivalent. Only `add`/`read`
+ are actually taken in consideration.
+
+
+
+In addition to thatm the entity type `EPermission` from the standard library
+allow to build very complex and dynamic security architecture. The schema of
+this entity type is as follow: ::
+
+ class EPermission(MetaEntityType):
+ """entity type that may be used to construct some advanced security configuration
+ """
+ name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
+ require_group = SubjectRelation('EGroup', cardinality='+*',
+ description=_('groups to which the permission is granted'))
+ require_state = SubjectRelation('State',
+ description=_("entity'state in which the permission is applyable"))
+ # can be used on any entity
+ require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
+ description=_("link a permission to the entity. This "
+ "permission should be used in the security "
+ "definition of the entity's type to be useful."))
+
+
+Example of configuration ::
+
+ ...
+
+ class Version(EntityType):
+ """a version is defining the content of a particular project's release"""
+
+ permissions = {'read': ('managers', 'users', 'guests',),
+ 'update': ('managers', 'logilab', 'owners',),
+ 'delete': ('managers', ),
+ 'add': ('managers', 'logilab',
+ ERQLExpression('X version_of PROJ, U in_group G,'
+ 'PROJ require_permission P, P name "add_version",'
+ 'P require_group G'),)}
+
+ ...
+
+ class version_of(RelationType):
+ """link a version to its project. A version is necessarily linked to one and only one project.
+ """
+ permissions = {'read': ('managers', 'users', 'guests',),
+ 'delete': ('managers', ),
+ 'add': ('managers', 'logilab',
+ RRQLExpression('O require_permission P, P name "add_version",'
+ 'U in_group G, P require_group G'),)
+ }
+ inlined = True
+
+This configuration assumes/indicates [???] that an entity `EPermission` named
+"add_version" can be associated to a project and provides rights to create
+new versions on this project to specific groups. It is important to notice that:
+
+* in such case, we have to protect both the entity type "Version" and the relation
+ associating a version to a project ("version_of")
+
+* because of the genricity of the entity type `EPermission`, we have to execute
+ a unification with the groups and/or the states if necessary in the expression
+ ("U in_group G, P require_group G" in the above example)
+
+
+Use of RQL expression for reading rights
+````````````````````````````````````````
+
+The principles are the same but with the following restrictions:
+
+* we can not [??] `RRQLExpression` on relation types for reading
+
+* special relations "has_<ACTION>_permission" can not be used
+
+
+Note on the use of RQL expression for `add` permission
+``````````````````````````````````````````````````````
+Potentially, the use of an RQL expression to add an entity or a relation
+can cause problems for the user interface, because if the expression uses
+the entity or the relation to create, then we are not able to verify the
+permissions before we actually add the entity (please note that this is
+not a problem for the RQL server at all, because the permissions checks are
+done after the creation). In such case, the permission checks methods
+(check_perm, has_perm) can indicate that the user is not allowed to create
+this entity but can obtain the permission.
+To compensate this problem, it is usually necessary, for such case,
+to use an action that reflects the schema permissions but which enables
+to check properly the permissions so that it would show up if necessary.
+[PAS CLAIR]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-00-sect-stdlib-schemas.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,86 @@
+.. -*- coding: utf-8 -*-
+
+Pre-defined schemas in the library
+----------------------------------
+
+The library defines a set of entities schemas that are required by the system
+or commonly used in `LAX` applications.
+Of course, you can extend those schemas if necessarry.
+
+System schemas
+``````````````
+Those are defined in::
+
+ ./myapp/ginco/schemas/
+ ./myapp/ginco/entities/
+
+``schemas/`` defines the data model you will use in your application.
+It allows you to describre the entities and the relations you will need.
+
+``entities/`` deifnes the methods you might need on the entities you
+defined in your schema.
+
+The system entities available are:
+
+* `EUser`, system users
+* `EGroup`, users groups
+* `EEType`, entity type
+* `ERType`, relation type
+
+* `State`, workflow state
+* `Transition`, workflow transition
+* `TrInfo`, record of a transition trafic for an entity
+
+* `EmailAddress`, email address, used by the system to send notifications
+ to the users and also used by others optionnals schemas
+
+* `EProperty`, used to configure the application
+* `EPermission`, used to configure the security of the application
+
+* `Card`, generic documenting card
+* `Bookmark`, an entity type used to allow a user to customize his links within
+ the application
+
+
+Components in the library
+`````````````````````````
+
+Those are defined in::
+
+ ./myapp/ginco-apps/
+
+An application is based on several basic components. In the set of available
+basic components we can find by example:
+
+* `ecomment`, provides an entity type for `Comment` allowing us to comment others
+ site's entities
+
+* `emailinglist`, provides an entity type for `Mailinglist` which groups informations
+ in a discussion list
+
+* `efile`, provides entity types for `File` et `Image` used to represent
+ files (text or binary) with additionnal informations such as MIME type or
+ encoding.
+
+* `elink`, provides an entity type for hypertext link (`Link`)
+
+* `eblog`, provides an entity type weblog (`Blog`)
+
+* `eperson`, provides an entity type for a person (`Person`)
+
+* `eaddressbook`, provides an entity type used to represent phone
+ numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
+
+* `eclasstags`, categorization system based on tags (`Tag`)
+
+* `eclassfolders`, categorization system based on folders hierarchy in order
+ to create navigation sections (`Folder`)
+
+* `eemail`, archiving management for emails (`Email`, `Emailpart`,
+ `Emailthread`)
+
+* `ebasket`, basket management (`Basket`) allowing to group entities
+
+To declare the use of a component, once installed, add the name of the component
+to the variable `__use__` in the file `__pkginfo__.py` of your own component.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-00-setup.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,13 @@
+.. -*- coding: utf-8 -*-
+
+.. _MiseEnPlaceEnv:
+
+===================================================
+Installation and set-up of a `CubicWeb` environment
+===================================================
+.. contents::
+
+.. include:: 03-01-installation.en.txt
+.. include:: 03-02-create-instance.en.txt
+.. include:: 03-03-cubicweb-ctl.en.txt
+
--- a/doc/book/en/03-definition-schema.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Data Model definition (*schema*)
-================================
-
-The schema is the main concept of `LAX` applications as it defines the
-data model we will handle. It is based on entities types already defined
-in the library and others, more specific, we would expect to find in one or
-more Python files under the `schema` directory.
-
-It is important to make clear the difference between relation type and relation
-definition: a relation type is only a relation name with potentially other
-additionnal properties (see XXXX), whereas a relation definition is a complete
-triplet "<subject entity type> <relation type> <object entity type>". A relation
-type could have been implied if none is related to a relation definition of the
-schema.
-
-
-.. include:: 03-sect-stdlib-schemas.en.txt
-.. include:: 03-sect-definition-schema.en.txt
--- a/doc/book/en/03-sect-definition-schema.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Entity type definition
-----------------------
-
-An entity type is defined by a Python class which inherits `EntityType`. The
-class name correponds to the type name. Then the content of the class contains
-the description of attributes and relations for the defined entity type,
-by example ::
-
- class Personne(EntityType):
- """A person with the properties and the relations necessarry for my
- application"""
-
- last_name = String(required=True, fulltextindexed=True)
- first_name = String(required=True, fulltextindexed=True)
- title = String(vocabulary=('M', 'Mme', 'Mlle'))
- date_of_birth = Date()
- works_for = SubjectRelation('Company', cardinality='?*')
-
-* the name of the Python attribute corresponds to the name of the attribute
- or the relation in `LAX` application.
-
-* all built-in types are available: `String`, `Int`, `Float`,
- `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
-
-* each entity has at least the following meta-relations:
-
- - `eid` (`Int`)
-
- - `creation_date` (`Datetime`)
-
- - `modification_date` (`Datetime`)
-
- - `created_by` (`EUser`) (which user created the entity)
-
- - `owned_by` (`EUser`) (who does the entity belongs to, by default the
- creator but not necessarry and it could have multiple owners)
-
- - `is` (`EEType`)
-
-
-* it is also possible to define relations of type object by using `ObjectRelation`
- instead of `SubjectRelation`
-
-* the first argument of `SubjectRelation` and `ObjectRelation` gives respectively
- the object/subject entity type of the relation. This could be:
-
- * a string corresponding to an entity type
-
- * a tuple of string correponding to multiple entities types
-
- * special string such as follows:
-
- - "**" : all types of entities
- - "*" : all types of entities non meta
- - "@" : all types of meta entities but not system entities (e.g. used for
- the basis schema description)
-
-* it is possible to use the attribute `meta` to flag an entity type as a `meta`
- (e.g. used to describe/categorize other entities)
-
-* optional properties for attributes and relations:
-
- - `description` : string describing an attribute or a relation. By default
- this string will be used in the editing form of the entity, which means
- that it is supposed to help the end-user and should be flagged by the
- function `_` to be properly internationalized.
-
- - `constraints` : list of conditions/constraints that the relation needs to
- satisfy (c.f. `Contraints`_)
-
- - `cardinality` : two characters string which specify the cardinality of the
- relation. The first character defines the cardinality of the relation on
- the subject, the second on the object of the relation. When a relation
- has multiple possible subjects or objects, the cardinality applies to all
- and not on a one to one basis (so it must be consistent...). The possible
- values are inspired from regular expressions syntax:
-
- * `1`: 1..1
- * `?`: 0..1
- * `+`: 1..n
- * `*`: 0..n
-
- - `meta` : boolean indicating that the relation is a meta-relation (false by
- default)
-
-* optionnal properties for attributes:
-
- - `required` : boolean indicating if the attribute is required (false by default)
-
- - `unique` : boolean indicating if the value of the attribute has to be unique
- or not within all entities of the same type (false by default)
-
- - `indexed` : boolean indicating if an index needs to be created for this
- attribute in the database (false by default). This is usefull only if
- you know that you will have to run numerous searches on the value of this
- attribute.
-
- - `default` : default value of the attribute. In case of date types, the values
- which could be used correpond to the RQL keywords `TODAY` and `NOW`.
-
- - `vocabulary` : specify static possible values of an attribute
-
-* optionnal properties of type `String`:
-
- - `fulltextindexed` : boolean indicating if the attribute is part of
- the full text index (false by default) (*applicable on the type `Byte`
- as well*)
-
- - `internationalizable` : boolean indicating if the value of the attribute
- is internationalizable (false by default)
-
- - `maxsize` : integer providing the maximum size of the string (no limit by default)
-
-* optionnal properties for relations:
-
- - `composite` : string indicating that the subject (composite == 'subject')
- is composed of the objects of the relations. For the opposite case (when
- the object is composed of the subjects of the relation), we just need
- to set 'object' as the value. The composition implies that when the relation
- is deleted (so when the composite is deleted), the composed are also deleted.
- [PAS CLAIR]
-
-Contraints
-``````````
-By default, the available constraints types are:
-
-* `SizeConstraint` : allows to specify a minimum and/or maximum size on
- string (generic case of `maxsize`)
-
-* `BoundConstraint` : allows to specify a minimum and/or maximum value on
- numeric types
-
-* `UniqueConstraint` : identical to "unique=True"
-
-* `StaticVocabularyConstraint` : identical to "vocabulary=(...)"
-
-* `RQLConstraint` : allows to specify a RQL query that needs to be satisfied
- by the subject and/or the object of the relation. In this query the variables
- `S` and `O` are reserved for the entities subject and object of the
- relation.
-
-* `RQLVocabularyConstraint` : similar to the previous type of constraint except
- that it does not express a "strong" constraint, which means it is only used to
- restrict the values listed in the drop-down menu of editing form, but it does
- not prevent another entity to be selected
- [PAS CLAIR]
-
-
-Relation type definition
-------------------------
-
-A relation is defined by a Python class heriting `RelationType`. The name
-of the class corresponds to the name of the type. The class then contains
-a description of the properties of this type of relation, as well as a
-string for the subject and a string for the object. This allows to create
-new definition of associated relations, (so that the class can have the
-definition properties from the relation)[PAS CLAIR] by example ::
-
- class locked_by(RelationType):
- """relation on all entities indicating that they are locked"""
- inlined = True
- cardinality = '?*'
- subject = '*'
- object = 'EUser'
-
-In addition to the permissions, the own properties of the relation types
-(shared also by all definition of relation of this type) are:
-
-
-* `inlined` : boolean handling the physical optimization for archiving
- the relation in the subject entity table, instead of creating a specific
- table for the relation. This applies to the relation when the cardinality
- of subject->relation->object is 0..1 ('?') or 1..1 ('1')
-
-* `symetric` : boolean indication that the relation is symetrical, which
- means `X relation Y` implies `Y relation X`
-
-In the case of simultaneous relations definitions, `subject` and `object`
-can both be equal to the value of the first argument of `SubjectRelation`
-and `ObjectRelation`.
-
-When a relation is not inlined and not symetrical, and it does not require
-specific permissions, its definition (by using `SubjectRelation` and
-`ObjectRelation`) is all we need.
-
-Permissions definition
-----------------------
-
-Define permissions is set through to the attribute `permissions` of entities and
-relations types. It defines a dictionnary where the keys are the access types
-(action), and the values are the authorized groups or expressions.
-
-For an entity type, the possible actions are `read`, `add`, `update` and
-`delete`.
-
-For a relation type, the possible actions are `read`, `add`, and `delete`.
-
-For each access type, a tuple indicates the name of the authorized groups and/or
-one or multiple RQL expressions to satisfy to grant access. The access is
-provided once the user is in the listed groups or one of the RQL condition is
-satisfied.
-
-The standard groups are:
-
-* `guests`
-
-* `users`
-
-* `managers`
-
-* `owners` : virtual group corresponding to the entity's owner.
- This can only be used for the actions `update` and `delete` of an entity
- type.
-
-It is also possible to use specific groups if they are define in the precreate
-of the application (``migration/precreate.py``).
-
-Use of RQL expression for writing rights
-````````````````````````````````````````
-It is possible to define RQL expression to provide update permission
-(`add`, `delete` and `update`) on relation and entity types.
-
-RQL expression for entity type permission:
-
-* you have to use the class `ERQLExpression`
-
-* the used expression corresponds to the WHERE statement of an RQL query
-
-* in this expression, the variables X and U are pre-defined references
- respectively on the current entity (on which the action is verified) and
- on the user who send the request
-
-* it is possible to use, in this expression, a special relation
- "has_<ACTION>_permission" where the subject is the user and the
- object is a any variable, meaning that the user needs to have
- permission to execute the action <ACTION> on the entities related
- to this variable
-
-For RQL expressions on a relation type, the principles are the same except
-for the following:
-
-* you have to use the class `RQLExpression` in the case of a non-final relation
- [WHAT IS A NON FINALE RELATION]
-
-* in the expression, the variables S, O and U are pre-defined references
- to respectively the subject and the object of the current relation (on
- which the action is being verified) and the user who executed the query
-
-* we can also defined rights on attributes of an entity (non-final relation),
- knowing that:
-
- - to defines RQL expression, we have to use the class `ERQLExpression`
- in which X represents the entity the attribute belongs to
-
- - the permissions `add` and `delete` are equivalent. Only `add`/`read`
- are actually taken in consideration.
-
-
-
-In addition to thatm the entity type `EPermission` from the standard library
-allow to build very complex and dynamic security architecture. The schema of
-this entity type is as follow: ::
-
- class EPermission(MetaEntityType):
- """entity type that may be used to construct some advanced security configuration
- """
- name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
- require_group = SubjectRelation('EGroup', cardinality='+*',
- description=_('groups to which the permission is granted'))
- require_state = SubjectRelation('State',
- description=_("entity'state in which the permission is applyable"))
- # can be used on any entity
- require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
- description=_("link a permission to the entity. This "
- "permission should be used in the security "
- "definition of the entity's type to be useful."))
-
-
-Example of configuration ::
-
- ...
-
- class Version(EntityType):
- """a version is defining the content of a particular project's release"""
-
- permissions = {'read': ('managers', 'users', 'guests',),
- 'update': ('managers', 'logilab', 'owners',),
- 'delete': ('managers', ),
- 'add': ('managers', 'logilab',
- ERQLExpression('X version_of PROJ, U in_group G,'
- 'PROJ require_permission P, P name "add_version",'
- 'P require_group G'),)}
-
- ...
-
- class version_of(RelationType):
- """link a version to its project. A version is necessarily linked to one and only one project.
- """
- permissions = {'read': ('managers', 'users', 'guests',),
- 'delete': ('managers', ),
- 'add': ('managers', 'logilab',
- RRQLExpression('O require_permission P, P name "add_version",'
- 'U in_group G, P require_group G'),)
- }
- inlined = True
-
-This configuration assumes/indicates [???] that an entity `EPermission` named
-"add_version" can be associated to a project and provides rights to create
-new versions on this project to specific groups. It is important to notice that:
-
-* in such case, we have to protect both the entity type "Version" and the relation
- associating a version to a project ("version_of")
-
-* because of the genricity of the entity type `EPermission`, we have to execute
- a unification with the groups and/or the states if necessary in the expression
- ("U in_group G, P require_group G" in the above example)
-
-
-Use of RQL expression for reading rights
-````````````````````````````````````````
-
-The principles are the same but with the following restrictions:
-
-* we can not [??] `RRQLExpression` on relation types for reading
-
-* special relations "has_<ACTION>_permission" can not be used
-
-
-Note on the use of RQL expression for `add` permission
-``````````````````````````````````````````````````````
-Potentially, the use of an RQL expression to add an entity or a relation
-can cause problems for the user interface, because if the expression uses
-the entity or the relation to create, then we are not able to verify the
-permissions before we actually add the entity (please note that this is
-not a problem for the RQL server at all, because the permissions checks are
-done after the creation). In such case, the permission checks methods
-(check_perm, has_perm) can indicate that the user is not allowed to create
-this entity but can obtain the permission.
-To compensate this problem, it is usually necessary, for such case,
-to use an action that reflects the schema permissions but which enables
-to check properly the permissions so that it would show up if necessary.
-[PAS CLAIR]
--- a/doc/book/en/03-sect-stdlib-schemas.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Pre-defined schemas in the library
-----------------------------------
-
-The library defines a set of entities schemas that are required by the system
-or commonly used in `LAX` applications.
-Of course, you can extend those schemas if necessarry.
-
-System schemas
-``````````````
-Those are defined in::
-
- ./myapp/ginco/schemas/
- ./myapp/ginco/entities/
-
-``schemas/`` defines the data model you will use in your application.
-It allows you to describre the entities and the relations you will need.
-
-``entities/`` deifnes the methods you might need on the entities you
-defined in your schema.
-
-The system entities available are:
-
-* `EUser`, system users
-* `EGroup`, users groups
-* `EEType`, entity type
-* `ERType`, relation type
-
-* `State`, workflow state
-* `Transition`, workflow transition
-* `TrInfo`, record of a transition trafic for an entity
-
-* `EmailAddress`, email address, used by the system to send notifications
- to the users and also used by others optionnals schemas
-
-* `EProperty`, used to configure the application
-* `EPermission`, used to configure the security of the application
-
-* `Card`, generic documenting card
-* `Bookmark`, an entity type used to allow a user to customize his links within
- the application
-
-
-Components in the library
-`````````````````````````
-
-Those are defined in::
-
- ./myapp/ginco-apps/
-
-An application is based on several basic components. In the set of available
-basic components we can find by example:
-
-* `ecomment`, provides an entity type for `Comment` allowing us to comment others
- site's entities
-
-* `emailinglist`, provides an entity type for `Mailinglist` which groups informations
- in a discussion list
-
-* `efile`, provides entity types for `File` et `Image` used to represent
- files (text or binary) with additionnal informations such as MIME type or
- encoding.
-
-* `elink`, provides an entity type for hypertext link (`Link`)
-
-* `eblog`, provides an entity type weblog (`Blog`)
-
-* `eperson`, provides an entity type for a person (`Person`)
-
-* `eaddressbook`, provides an entity type used to represent phone
- numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
-
-* `eclasstags`, categorization system based on tags (`Tag`)
-
-* `eclassfolders`, categorization system based on folders hierarchy in order
- to create navigation sections (`Folder`)
-
-* `eemail`, archiving management for emails (`Email`, `Emailpart`,
- `Emailthread`)
-
-* `ebasket`, basket management (`Basket`) allowing to group entities
-
-To declare the use of a component, once installed, add the name of the component
-to the variable `__use__` in the file `__pkginfo__.py` of your own component.
-
--- a/doc/book/en/03-setup.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _MiseEnPlaceEnv:
-
-===================================================
-Installation and set-up of a `CubicWeb` environment
-===================================================
-.. contents::
-
-.. include:: 03-01-installation.en.txt
-.. include:: 03-02-create-instance.en.txt
-.. include:: 03-03-cubicweb-ctl.en.txt
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/04-00-define-schema.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,22 @@
+.. -*- coding: utf-8 -*-
+
+Data model definition (*schema*)
+================================
+
+The schema is the core piece of a `CubicWeb` application as it defines
+the data model handled. It is based on entities types already defined
+in the `CubicWeb` standard library and others, more specific, we would
+expect to find in one or more Python files under the `schema` directory.
+
+At this point, it is important to make clear the difference between
+relation type and relation definition: a relation type is only a relation
+name with potentially other additionnal properties (see XXXX), whereas a
+relation definition is a complete triplet
+"<subject entity type> <relation type> <object entity type>".
+A relation type could have been implied if none is related to a
+relation definition of the schema.
+
+
+.. include:: 04-01-schema-stdlib.en.txt
+.. include:: 04-02-schema-definition.en.txt
+
--- a/doc/book/en/04-define-schema.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Data model definition (*schema*)
-================================
-
-The schema is the core piece of a `CubicWeb` application as it defines
-the data model handled. It is based on entities types already defined
-in the `CubicWeb` standard library and others, more specific, we would
-expect to find in one or more Python files under the `schema` directory.
-
-At this point, it is important to make clear the difference between
-relation type and relation definition: a relation type is only a relation
-name with potentially other additionnal properties (see XXXX), whereas a
-relation definition is a complete triplet
-"<subject entity type> <relation type> <object entity type>".
-A relation type could have been implied if none is related to a
-relation definition of the schema.
-
-
-.. include:: 04-01-schema-stdlib.en.txt
-.. include:: 04-02-schema-definition.en.txt
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/05-00-define-views.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,238 @@
+.. -*- coding: utf-8 -*-
+
+.. _DefinitionVues:
+
+Views definition
+================
+
+Basic class for views
+---------------------
+
+Class `View` (`cubicweb.common.view`)
+`````````````````````````````````````
+
+A view writes in its output exit thanks to its attribute `w` (`UStreamIO`).
+
+The basic interface for views is as follows:
+
+* `dispatch(**context)`, render the view by calling `call` or
+ `cell_call` depending on the given parameters
+* `call(**kwargs)`, call the view for a complete result set or null
+* `cell_call(row, col, **kwargs)`, call the view for a given cell of a result set
+* `url()`, returns the URL enabling us to get the view with the current
+ result set
+* `view(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of identifier
+ `__vid` on the given result set. It is possible to give a view identifier
+ of fallback that will be used if the view requested is not applicable to the
+ result set
+
+* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, similar to `view` except
+ the flow is automatically passed in the parameters
+
+* `html_headers()`, returns a list of HTML headers to set by the main template
+
+* `page_title()`, returns the title to use in the HTML header `title`
+
+* `creator(eid)`, returns the eid and the login of the entity creator of the entity
+ having the eid given in the parameter
+
+Other basic classes:
+
+* `EntityView`, view applying to lines or cell containing an entity (e.g. an eid)
+* `StartupView`, start view that does not require a result set to apply to
+* `AnyRsetView`, view applied to any result set
+
+
+The selection view principle
+----------------------------
+
+A view includes :
+
+- an identifier (all objects in `LAX` are entered in a registry
+ and this identifier will be used as a key)
+
+- a filter to select the resulsets it can be applied to
+
+
+For a given identifier, multiple views can be defined. `CubicWeb` uses
+a selector which computes scores so that it can identify and select the
+best view to apply in context. The selector library is in
+``cubicweb.common.selector`` and a library of the methods used to
+compute scores is in ``cubicweb.vregistry.vreq``.
+
+
+`CubicWeb` provides a lot of standard views, for a complete list, you
+will have to read the code in directory ``cubicweb/web/views/`` (XXX
+improve doc).
+
+For example, the view named ``primary`` is the one used to display
+a single entity.
+
+If you want to change the way a ``BlogEntry`` is displayed, just
+override the view ``primary`` in ``BlogDemo/views.py`` ::
+
+ 01. from ginco.web.views import baseviews
+ 02.
+ 03. class BlogEntryPrimaryView(baseviews.PrimaryView):
+ 04.
+ 05. accepts = ('BlogEntry',)
+ 06.
+ 07. def cell_call(self, row, col):
+ 08. entity = self.entity(row, col)
+ 09. self.w(u'<h1>%s</h1>' % entity.title)
+ 10. self.w(u'<p>published on %s in category %s</p>' % \
+ 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
+ 12. self.w(u'<p>%s</p>' % entity.text)
+
+The above source code defines a new primary view (`line 03`) for
+``BlogEntry`` (`line 05`).
+
+Since views are applied to resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates (`line 08`). We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. Here `lines
+09-12` output HTML tags and values of the entity's attributes.
+
+When displaying same blog entry as before, you will notice that the
+page is now looking much nicer.
+
+.. image:: images/lax-book.09-new-view-blogentry.en.png
+ :alt: blog entries now look much nicer
+
+Let us now improve the primary view of a blog ::
+
+ 01. class BlogPrimaryView(baseviews.PrimaryView):
+ 02.
+ 03. accepts = ('Blog',)
+ 04.
+ 05. def cell_call(self, row, col):
+ 06. entity = self.entity(row, col)
+ 07. self.w(u'<h1>%s</h1>' % entity.title)
+ 08. self.w(u'<p>%s</p>' % entity.description)
+ 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
+ 10. self.wview('primary', rset)
+
+In the above source code, `lines 01-08` are similar to the previous
+view we defined.
+
+At `line 09`, a simple request in made to build a resultset with all
+the entities linked to the current ``Blog`` entity by the relationship
+``entry_of``. The part of the framework handling the request knows
+about the schema and infer that such entities have to be of the
+``BlogEntry`` kind and retrieves them.
+
+The request returns a selection of data called a resultset. At
+`line 10` the view 'primary' is applied to this resultset to output
+HTML.
+
+**This is to be compared to interfaces and protocols in object-oriented
+languages. Applying a given view to all the entities of a resultset only
+requires the availability, for each entity of this resultset, of a
+view with that name that can accepts the entity.**
+
+Assuming we added entries to the blog titled `MyLife`, displaying it
+now allows to read its description and all its entries.
+
+.. image:: images/lax-book.10-blog-with-two-entries.en.png
+ :alt: a blog and all its entries
+
+**Before we move forward, remember that the selection/view principle is
+at the core of `CubicWeb`. Everywhere in the engine, data is requested
+using the RQL language, then HTML/XML/text/PNG is output by applying a
+view to the resultset returned by the query. That is where most of the
+flexibility comes from.**
+
+[WRITE ME]
+
+* implementing interfaces, calendar for blog entries
+* show that a calendar view can export data to ical
+
+We will implement the cubicwweb.interfaces.ICalendarable interfaces on
+entities.BloEntry and apply the OneMonthCalendar and iCalendar views
+to resultsets like "Any E WHERE E is BlogEntry"
+
+* create view "blogentry table" with title, publish_date, category
+
+We will show that by default the view that displays
+"Any E,D,C WHERE E publish_date D, E category C" is the table view.
+Of course, the same can be obtained by calling
+self.wview('table',rset)
+
+* in view blog, select blogentries and apply view "blogentry table"
+* demo ajax by filtering blogentry table on category
+
+we did the same with 'primary', but with tables we can turn on filters
+and show that ajax comes for free.
+[FILLME]
+
+
+Templates
+---------
+
+*Templates* are specific view that does not depend on a result set. The basic
+class `Template` (`cubicweb.common.view`) is derived from the class `View`.
+
+To build a HTML page, a *main template* is used. In general, the template of
+identifier `main` is the one (it is not used in case an error is raised or for
+the login form by example). This template uses other templates in addition
+to the views which depends on the content to generate the HTML page to return.
+
+A *template* is responsible for:
+
+1. executing RQL query of data to render if necessarry
+2. identifying the view to use to render data if it is not specified
+3. composing the HTML page to return
+
+
+The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
+------------------------------------------------------------------------------
+
+The default main template build the page based on the following pattern:
+
+.. image:: images/main_template_layout.png
+
+The rectangle containing `view.dispathc()` represents the area where the content
+view has to be displayed. The others represents sub-templates called to complete
+the page. A default implementation of those is provided in
+`cubicweb.views.basetemplates`. You can, of course, overload those sub-templates
+to implement your own customization of the HTML page.
+
+We can also control certain aspects of the main template thanks to the following
+forms parameters:
+
+* `__notemplate`, if present (whatever the value assigned), only the content view
+ is returned
+* `__force_display`, if present and its value is not null, no navigation
+ whatever the number of entities to display
+* `__method`, if the result set to render contains only one entity and this
+ parameter is set, it refers to a method to call on the entity by passing it
+ the dictionnary of the forms parameters, before going the classic way (through
+ step 1 and 2 described juste above)
+
+.. include:: 05-01-views-stdlib.en.txt
+
+
+XML views, binaries...
+----------------------
+For the views generating other formats that HTML (an image generated dynamically
+by example), and which can not usually be included in the HTML page generated
+by the main template (see above), you have to:
+
+* set the atribute `templatable` of the class to `False`
+* set, through the attribute `content_type` of the class, the MIME type generated
+ by the view to `application/octet-stream`
+
+For the views dedicated to binary content creation (an image dynamically generated
+by example), we have to set the attribute `binary` of the class to `True` (which
+implies that `templateable == False`, so that the attribute `w` of the view could be
+replaced by a binary flow instead of unicode).
+
+(X)HTML tricks to apply
+-----------------------
+
+Some web browser (Firefox by example) are not happy with empty `<div>`
+(by empty we mean that there is no content in the tag, but there
+could be attributes), so we should always use `<div></div>` even if
+it is empty and not use `<div/>`.
+
--- a/doc/book/en/05-define-views.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _DefinitionVues:
-
-Views definition
-================
-
-Basic class for views
----------------------
-
-Class `View` (`cubicweb.common.view`)
-`````````````````````````````````````
-
-A view writes in its output exit thanks to its attribute `w` (`UStreamIO`).
-
-The basic interface for views is as follows:
-
-* `dispatch(**context)`, render the view by calling `call` or
- `cell_call` depending on the given parameters
-* `call(**kwargs)`, call the view for a complete result set or null
-* `cell_call(row, col, **kwargs)`, call the view for a given cell of a result set
-* `url()`, returns the URL enabling us to get the view with the current
- result set
-* `view(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of identifier
- `__vid` on the given result set. It is possible to give a view identifier
- of fallback that will be used if the view requested is not applicable to the
- result set
-
-* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, similar to `view` except
- the flow is automatically passed in the parameters
-
-* `html_headers()`, returns a list of HTML headers to set by the main template
-
-* `page_title()`, returns the title to use in the HTML header `title`
-
-* `creator(eid)`, returns the eid and the login of the entity creator of the entity
- having the eid given in the parameter
-
-Other basic classes:
-
-* `EntityView`, view applying to lines or cell containing an entity (e.g. an eid)
-* `StartupView`, start view that does not require a result set to apply to
-* `AnyRsetView`, view applied to any result set
-
-
-The selection view principle
-----------------------------
-
-A view includes :
-
-- an identifier (all objects in `LAX` are entered in a registry
- and this identifier will be used as a key)
-
-- a filter to select the resulsets it can be applied to
-
-
-For a given identifier, multiple views can be defined. `CubicWeb` uses
-a selector which computes scores so that it can identify and select the
-best view to apply in context. The selector library is in
-``cubicweb.common.selector`` and a library of the methods used to
-compute scores is in ``cubicweb.vregistry.vreq``.
-
-
-`CubicWeb` provides a lot of standard views, for a complete list, you
-will have to read the code in directory ``cubicweb/web/views/`` (XXX
-improve doc).
-
-For example, the view named ``primary`` is the one used to display
-a single entity.
-
-If you want to change the way a ``BlogEntry`` is displayed, just
-override the view ``primary`` in ``BlogDemo/views.py`` ::
-
- 01. from ginco.web.views import baseviews
- 02.
- 03. class BlogEntryPrimaryView(baseviews.PrimaryView):
- 04.
- 05. accepts = ('BlogEntry',)
- 06.
- 07. def cell_call(self, row, col):
- 08. entity = self.entity(row, col)
- 09. self.w(u'<h1>%s</h1>' % entity.title)
- 10. self.w(u'<p>published on %s in category %s</p>' % \
- 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
- 12. self.w(u'<p>%s</p>' % entity.text)
-
-The above source code defines a new primary view (`line 03`) for
-``BlogEntry`` (`line 05`).
-
-Since views are applied to resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates (`line 08`). We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. Here `lines
-09-12` output HTML tags and values of the entity's attributes.
-
-When displaying same blog entry as before, you will notice that the
-page is now looking much nicer.
-
-.. image:: images/lax-book.09-new-view-blogentry.en.png
- :alt: blog entries now look much nicer
-
-Let us now improve the primary view of a blog ::
-
- 01. class BlogPrimaryView(baseviews.PrimaryView):
- 02.
- 03. accepts = ('Blog',)
- 04.
- 05. def cell_call(self, row, col):
- 06. entity = self.entity(row, col)
- 07. self.w(u'<h1>%s</h1>' % entity.title)
- 08. self.w(u'<p>%s</p>' % entity.description)
- 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
- 10. self.wview('primary', rset)
-
-In the above source code, `lines 01-08` are similar to the previous
-view we defined.
-
-At `line 09`, a simple request in made to build a resultset with all
-the entities linked to the current ``Blog`` entity by the relationship
-``entry_of``. The part of the framework handling the request knows
-about the schema and infer that such entities have to be of the
-``BlogEntry`` kind and retrieves them.
-
-The request returns a selection of data called a resultset. At
-`line 10` the view 'primary' is applied to this resultset to output
-HTML.
-
-**This is to be compared to interfaces and protocols in object-oriented
-languages. Applying a given view to all the entities of a resultset only
-requires the availability, for each entity of this resultset, of a
-view with that name that can accepts the entity.**
-
-Assuming we added entries to the blog titled `MyLife`, displaying it
-now allows to read its description and all its entries.
-
-.. image:: images/lax-book.10-blog-with-two-entries.en.png
- :alt: a blog and all its entries
-
-**Before we move forward, remember that the selection/view principle is
-at the core of `CubicWeb`. Everywhere in the engine, data is requested
-using the RQL language, then HTML/XML/text/PNG is output by applying a
-view to the resultset returned by the query. That is where most of the
-flexibility comes from.**
-
-[WRITE ME]
-
-* implementing interfaces, calendar for blog entries
-* show that a calendar view can export data to ical
-
-We will implement the cubicwweb.interfaces.ICalendarable interfaces on
-entities.BloEntry and apply the OneMonthCalendar and iCalendar views
-to resultsets like "Any E WHERE E is BlogEntry"
-
-* create view "blogentry table" with title, publish_date, category
-
-We will show that by default the view that displays
-"Any E,D,C WHERE E publish_date D, E category C" is the table view.
-Of course, the same can be obtained by calling
-self.wview('table',rset)
-
-* in view blog, select blogentries and apply view "blogentry table"
-* demo ajax by filtering blogentry table on category
-
-we did the same with 'primary', but with tables we can turn on filters
-and show that ajax comes for free.
-[FILLME]
-
-
-Templates
----------
-
-*Templates* are specific view that does not depend on a result set. The basic
-class `Template` (`cubicweb.common.view`) is derived from the class `View`.
-
-To build a HTML page, a *main template* is used. In general, the template of
-identifier `main` is the one (it is not used in case an error is raised or for
-the login form by example). This template uses other templates in addition
-to the views which depends on the content to generate the HTML page to return.
-
-A *template* is responsible for:
-
-1. executing RQL query of data to render if necessarry
-2. identifying the view to use to render data if it is not specified
-3. composing the HTML page to return
-
-
-The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
-------------------------------------------------------------------------------
-
-The default main template build the page based on the following pattern:
-
-.. image:: images/main_template_layout.png
-
-The rectangle containing `view.dispathc()` represents the area where the content
-view has to be displayed. The others represents sub-templates called to complete
-the page. A default implementation of those is provided in
-`cubicweb.views.basetemplates`. You can, of course, overload those sub-templates
-to implement your own customization of the HTML page.
-
-We can also control certain aspects of the main template thanks to the following
-forms parameters:
-
-* `__notemplate`, if present (whatever the value assigned), only the content view
- is returned
-* `__force_display`, if present and its value is not null, no navigation
- whatever the number of entities to display
-* `__method`, if the result set to render contains only one entity and this
- parameter is set, it refers to a method to call on the entity by passing it
- the dictionnary of the forms parameters, before going the classic way (through
- step 1 and 2 described juste above)
-
-.. include:: 05-01-views-stdlib.en.txt
-
-
-XML views, binaries...
-----------------------
-For the views generating other formats that HTML (an image generated dynamically
-by example), and which can not usually be included in the HTML page generated
-by the main template (see above), you have to:
-
-* set the atribute `templatable` of the class to `False`
-* set, through the attribute `content_type` of the class, the MIME type generated
- by the view to `application/octet-stream`
-
-For the views dedicated to binary content creation (an image dynamically generated
-by example), we have to set the attribute `binary` of the class to `True` (which
-implies that `templateable == False`, so that the attribute `w` of the view could be
-replaced by a binary flow instead of unicode).
-
-(X)HTML tricks to apply
------------------------
-
-Some web browser (Firefox by example) are not happy with empty `<div>`
-(by empty we mean that there is no content in the tag, but there
-could be attributes), so we should always use `<div></div>` even if
-it is empty and not use `<div/>`.
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/06-00-define-workflows.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,154 @@
+.. -*- coding: utf-8 -*-
+
+Définition de workflow
+======================
+On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
+
+Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
+
+Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
+
+Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
+
+* `%(eid)s`, eid de l'objet
+* `%(ueid)s`, eid de l'utilisateur qui fait la requête
+* `%(seid)s`, eid de l'état courant de l'objet
+
+Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
+pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
+
+General
+-------
+
+A workflow can be defined in a `LAX` application thanks to the system
+entities ``State`` and ``Transition``. Those are defined within all
+LAX application and can be set-up through the main administrator interface.
+
+Once your schema is defined, you can start creating the set of states and
+the required transitions for your applications entities.
+
+You first need to define the states and then the transitions between those
+to complete your workflow.
+
+A ``State`` defines the status of an entity. While creating a new state,
+you will be first given the option to select the entity type the state
+can be applied to. By choosing ``Apply``, a new section will be displayed
+in the editing screen to enable you to add relation to the state you are
+creating.
+
+A ``Transition`` is also based on an entity type it can be applied to.
+By choosing ``Apply``, a new section will be displayed in the editing
+screen to enable you to add relation to the transition you are
+creating.
+
+At the transition level you will also define the group of user which can
+aplly this transition to an object.
+
+
+Example of a simple workflow
+----------------------------
+
+Please see the tutorial to view and example of a simple workflow.
+
+
+[Create a simple workflow for BlogDemo, to have a moderator approve new blog
+entry to be published. This implies, specify a dedicated group of blog
+moderator as well as hide the view of a blog entry to the user until
+it reaches the state published]
+
+Set-up a workflow
+-----------------
+
+Before starting, make sure you refresh your mind by reading [link to
+definition_workflow chapter].
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on your application. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it needs to
+be in the state `published`. To move from `submitted` to `published`
+we need a transition that we can name `approve_blogentry`.
+
+We do not want every user to be allowed to change the state of a
+BlogEntry. We need to define a group of user, `moderators`, and
+this group will have appropriate permissions to approve BlogEntry
+to be published and visible to all.
+
+There are two ways to create a workflow, form the user interface,
+and also by defining it in ``migration/postcreate.py``. This script
+is executed each time a new ``./bin/laxctl db-init`` is done.
+If you create the states and transitions through the user interface
+this means that next time you will need to initialize the database
+you will have to re-create all the entities.
+We strongly recommand you create the workflow in ``migration\postcreate.py``
+and we will now show you how.
+The user interface would only be a reference for you to view the states
+and transitions but is not the appropriate interface to define your
+application workflow.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+To enable a BlogEntry to have a State, we have to define a relation
+``in_state`` in the schema of BlogEntry. Please do as follows, add
+the line ``in_state (...)``::
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text_format = String(meta=True, internationalizable=True, maxsize=50,
+ default='text/rest', constraints=[format_constraint])
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+ in_state = SubjectRelation('State', cardinality='1*')
+
+As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
+to initialize the database and migrate your existing entities.
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time the ``postcreate.py`` script is executed, several methods
+can be used. They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the method we use to create a wrokflow here.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+
+ _ = unicode
+
+ moderators = add_entity('EGroup', name=u"moderators")
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+ checkpoint()
+
+``add_entity`` is used here to define the new group of users that we
+need to define the transitions, `moderators`.
+If this group required by the transition is not defined before the
+transition is created, it will not create the relation `transition
+require the group moderator`.
+
+``add_state`` expects as the first argument the name of the state you are
+willing to create, then the entity type on which the state can be applied,
+and an optionnal argument to set if the state is the initial state
+of the entity type or not.
+
+``add_transition`` expects as the first argument the name of the
+transition, then the entity type on which we can apply the transition,
+then the list of possible initial states from which the transition
+can be applied, the target state of the transition, and the permissions
+(e.g. list of the groups of users who can apply the transition).
+
+.. image:: images/lax-book.03-transitions-view.en.png
+
+You can now notice that in the actions box of a BlogEntry, the state
+is now listed as well as the possible transitions from this state
+defined by the workflow. This transition, as defined in the workflow,
+will only being displayed for the users belonging to the group
+moderators of managers.
+
+
--- a/doc/book/en/06-define-workflows.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Définition de workflow
-======================
-On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
-
-Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
-
-Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
-
-Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
-
-* `%(eid)s`, eid de l'objet
-* `%(ueid)s`, eid de l'utilisateur qui fait la requête
-* `%(seid)s`, eid de l'état courant de l'objet
-
-Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
-pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
-
-General
--------
-
-A workflow can be defined in a `LAX` application thanks to the system
-entities ``State`` and ``Transition``. Those are defined within all
-LAX application and can be set-up through the main administrator interface.
-
-Once your schema is defined, you can start creating the set of states and
-the required transitions for your applications entities.
-
-You first need to define the states and then the transitions between those
-to complete your workflow.
-
-A ``State`` defines the status of an entity. While creating a new state,
-you will be first given the option to select the entity type the state
-can be applied to. By choosing ``Apply``, a new section will be displayed
-in the editing screen to enable you to add relation to the state you are
-creating.
-
-A ``Transition`` is also based on an entity type it can be applied to.
-By choosing ``Apply``, a new section will be displayed in the editing
-screen to enable you to add relation to the transition you are
-creating.
-
-At the transition level you will also define the group of user which can
-aplly this transition to an object.
-
-
-Example of a simple workflow
-----------------------------
-
-Please see the tutorial to view and example of a simple workflow.
-
-
-[Create a simple workflow for BlogDemo, to have a moderator approve new blog
-entry to be published. This implies, specify a dedicated group of blog
-moderator as well as hide the view of a blog entry to the user until
-it reaches the state published]
-
-Set-up a workflow
------------------
-
-Before starting, make sure you refresh your mind by reading [link to
-definition_workflow chapter].
-
-We want to create a workflow to control the quality of the BlogEntry
-submitted on your application. When a BlogEntry is created by a user
-its state should be `submitted`. To be visible to all, it needs to
-be in the state `published`. To move from `submitted` to `published`
-we need a transition that we can name `approve_blogentry`.
-
-We do not want every user to be allowed to change the state of a
-BlogEntry. We need to define a group of user, `moderators`, and
-this group will have appropriate permissions to approve BlogEntry
-to be published and visible to all.
-
-There are two ways to create a workflow, form the user interface,
-and also by defining it in ``migration/postcreate.py``. This script
-is executed each time a new ``./bin/laxctl db-init`` is done.
-If you create the states and transitions through the user interface
-this means that next time you will need to initialize the database
-you will have to re-create all the entities.
-We strongly recommand you create the workflow in ``migration\postcreate.py``
-and we will now show you how.
-The user interface would only be a reference for you to view the states
-and transitions but is not the appropriate interface to define your
-application workflow.
-
-Update the schema
-~~~~~~~~~~~~~~~~~
-To enable a BlogEntry to have a State, we have to define a relation
-``in_state`` in the schema of BlogEntry. Please do as follows, add
-the line ``in_state (...)``::
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/rest', constraints=[format_constraint])
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
- in_state = SubjectRelation('State', cardinality='1*')
-
-As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
-to initialize the database and migrate your existing entities.
-[WRITE ABOUT MIGRATION]
-
-Create states, transitions and group permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At the time the ``postcreate.py`` script is executed, several methods
-can be used. They are all defined in the ``class ServerMigrationHelper``.
-We will only discuss the method we use to create a wrokflow here.
-
-To define our workflow for BlogDemo, please add the following lines
-to ``migration/postcreate.py``::
-
- _ = unicode
-
- moderators = add_entity('EGroup', name=u"moderators")
-
- submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
- published = add_state(_('published'), 'BlogEntry')
-
- add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
-
- checkpoint()
-
-``add_entity`` is used here to define the new group of users that we
-need to define the transitions, `moderators`.
-If this group required by the transition is not defined before the
-transition is created, it will not create the relation `transition
-require the group moderator`.
-
-``add_state`` expects as the first argument the name of the state you are
-willing to create, then the entity type on which the state can be applied,
-and an optionnal argument to set if the state is the initial state
-of the entity type or not.
-
-``add_transition`` expects as the first argument the name of the
-transition, then the entity type on which we can apply the transition,
-then the list of possible initial states from which the transition
-can be applied, the target state of the transition, and the permissions
-(e.g. list of the groups of users who can apply the transition).
-
-.. image:: images/lax-book.03-transitions-view.en.png
-
-You can now notice that in the actions box of a BlogEntry, the state
-is now listed as well as the possible transitions from this state
-defined by the workflow. This transition, as defined in the workflow,
-will only being displayed for the users belonging to the group
-moderators of managers.
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/07-00-data-as-objects.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,142 @@
+.. -*- coding: utf-8 -*-
+
+
+Manipulation des données stockées
+=================================
+
+Les classes `Entity` et `AnyEntity`
+-----------------------------------
+Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
+une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
+définir ces classes dans un module du package `entities` d'une application pour
+qu'elle soit disponible à la fois coté serveur et coté client.
+
+La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
+de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
+ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
+
+Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
+fonction du schéma :
+
+* on peut accéder aux attributs définis dans le schéma via les attributs de même
+ nom sur les instances (valeur typée)
+
+* on peut accéder aux relations définies dans le schéma via les attributs de même
+ nom sur les instances (liste d'instances d'entité)
+
+Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
+
+* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
+ création)
+
+* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
+ l'action demandée sur l'entité
+
+:Formattage et génération de la sortie:
+
+ * `view(vid, **kwargs)`, applique la vue donnée à l'entité
+
+ * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
+ vue primaire d'une entité
+
+ * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
+
+ * `format(attr)`, retourne le format (type MIME) du champ passé en argument
+
+ * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
+ retourne une chaine permettant l'affichage dans un format donné de la valeur
+ d'un attribut (la valeur est automatiquement récupérée au besoin)
+
+ * `display_name(form='')`, retourne une chaîne pour afficher le type de
+ l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
+ forme plurielle)
+
+:Gestion de données:
+
+ * `as_rset()`, transforme l'entité en un resultset équivalent simulant
+ le résultat de la requête `Any X WHERE X eid _eid_`
+
+ * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
+ coup toutes les valeurs d'attributs manquant sur l'entité
+
+ * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
+
+ * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
+ des entités liées à l'entité courant par la relation donnée en argument
+
+ * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
+ des entités not liées à l'entité courante par la relation donnée en argument
+ et satisfaisants les contraintes de celle-ci
+
+ * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
+ les valeurs correspondantes passées sous forme d'arguments nommés
+
+ * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
+ argument sur l'entité courante
+
+ * `last_modified(view)`, retourne la date à laquelle on doit considérer
+ l'objet comme modifié (utiliser par la gestion de cache HTTP)
+
+ * `delete()` permet de supprimer l'entité représentée
+
+:Meta-données standard (Dublin Core):
+
+ * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
+ 'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
+ l'entité)
+
+ * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
+
+ * `dc_description(format='text/plain')`, retourne une chaine unicode
+ correspondant à la méta-donnée 'Description' (cherche un attribut
+ 'description' par défaut)
+
+ * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
+ 'Authors' (propriétaires par défaut)
+
+ * `dc_date(date_format=None)`, retourne une chaine unicode
+ correspondant à la méta-donnée 'Date' (date de modification par défaut)
+
+:Contrôle du vocabulaire pour les relations:
+
+ * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
+ par les vues d'édition d'erudi, elle renvoie une liste de couple
+ (label, eid) des entités qui pourraient être liées à l'entité
+ via la relation `rtype`
+ * `subject_relation_vocabulary(rtype, limit=None)`, appelée
+ en interne par `vocabulary` dans le cas d'une relation sujet
+ * `object_relation_vocabulary(rtype, limit=None)`, appelée
+ en interne par `vocabulary` dans le cas d'une relation objet
+ * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
+ en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
+
+
+Les *rtags*
+-----------
+Les *rtags* permettent de spécifier certains comportements propres aux relations
+d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe
+d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un
+triplet ::
+
+ <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
+
+et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés
+s'appliquant à cette relation.
+
+Il est possible de simplifier ce dictionnaire :
+
+* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
+ un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
+* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
+ position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
+ utiliser le nom du type de relation comme clé
+* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
+ faut utiliser la chaine `*` comme type d'entité cible
+
+A noter également que ce dictionnaire est *traité à la création de la classe*.
+Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
+besoin de copier celui de la classe parent pour le modifier). De même modifier
+celui-ci après création de la classe n'aura aucun effet...
+
+
+.. include:: 07-01-define-entities.en.txt
--- a/doc/book/en/07-data-as-objects.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Manipulation des données stockées
-=================================
-
-Les classes `Entity` et `AnyEntity`
------------------------------------
-Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
-une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
-définir ces classes dans un module du package `entities` d'une application pour
-qu'elle soit disponible à la fois coté serveur et coté client.
-
-La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
-de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
-ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
-
-Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
-fonction du schéma :
-
-* on peut accéder aux attributs définis dans le schéma via les attributs de même
- nom sur les instances (valeur typée)
-
-* on peut accéder aux relations définies dans le schéma via les attributs de même
- nom sur les instances (liste d'instances d'entité)
-
-Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
-
-* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
- création)
-
-* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
- l'action demandée sur l'entité
-
-:Formattage et génération de la sortie:
-
- * `view(vid, **kwargs)`, applique la vue donnée à l'entité
-
- * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
- vue primaire d'une entité
-
- * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
-
- * `format(attr)`, retourne le format (type MIME) du champ passé en argument
-
- * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
- retourne une chaine permettant l'affichage dans un format donné de la valeur
- d'un attribut (la valeur est automatiquement récupérée au besoin)
-
- * `display_name(form='')`, retourne une chaîne pour afficher le type de
- l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
- forme plurielle)
-
-:Gestion de données:
-
- * `as_rset()`, transforme l'entité en un resultset équivalent simulant
- le résultat de la requête `Any X WHERE X eid _eid_`
-
- * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
- coup toutes les valeurs d'attributs manquant sur l'entité
-
- * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
-
- * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
- des entités liées à l'entité courant par la relation donnée en argument
-
- * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
- des entités not liées à l'entité courante par la relation donnée en argument
- et satisfaisants les contraintes de celle-ci
-
- * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
- les valeurs correspondantes passées sous forme d'arguments nommés
-
- * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
- argument sur l'entité courante
-
- * `last_modified(view)`, retourne la date à laquelle on doit considérer
- l'objet comme modifié (utiliser par la gestion de cache HTTP)
-
- * `delete()` permet de supprimer l'entité représentée
-
-:Meta-données standard (Dublin Core):
-
- * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
- l'entité)
-
- * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
-
- * `dc_description(format='text/plain')`, retourne une chaine unicode
- correspondant à la méta-donnée 'Description' (cherche un attribut
- 'description' par défaut)
-
- * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Authors' (propriétaires par défaut)
-
- * `dc_date(date_format=None)`, retourne une chaine unicode
- correspondant à la méta-donnée 'Date' (date de modification par défaut)
-
-:Contrôle du vocabulaire pour les relations:
-
- * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
- par les vues d'édition d'erudi, elle renvoie une liste de couple
- (label, eid) des entités qui pourraient être liées à l'entité
- via la relation `rtype`
- * `subject_relation_vocabulary(rtype, limit=None)`, appelée
- en interne par `vocabulary` dans le cas d'une relation sujet
- * `object_relation_vocabulary(rtype, limit=None)`, appelée
- en interne par `vocabulary` dans le cas d'une relation objet
- * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
- en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
-
-
-Les *rtags*
------------
-Les *rtags* permettent de spécifier certains comportements propres aux relations
-d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe
-d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un
-triplet ::
-
- <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
-
-et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés
-s'appliquant à cette relation.
-
-Il est possible de simplifier ce dictionnaire :
-
-* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
- un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
-* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
- position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
- utiliser le nom du type de relation comme clé
-* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
- faut utiliser la chaine `*` comme type d'entité cible
-
-A noter également que ce dictionnaire est *traité à la création de la classe*.
-Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
-besoin de copier celui de la classe parent pour le modifier). De même modifier
-celui-ci après création de la classe n'aura aucun effet...
-
-
-.. include:: 07-01-define-entities.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/08-00-site-config.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,94 @@
+.. -*- coding: utf-8 -*-
+
+Interface de configuration du site
+==================================
+
+.. image:: images/lax-book.03-site-config-panel.en.png
+
+This panel allows you to configure the appearance of your application site.
+Six menus are available and we will go through each of them to explain how
+to use them.
+
+Navigation
+~~~~~~~~~~
+This menu provides you a way to adjust some navigation options depending on
+your needs, such as the number of entities to display by page of results.
+Follows the detailled list of available options :
+
+* navigation.combobox-limit : maximum number of entities to display in related
+ combo box (sample format: 23)
+* navigation.page-size : maximum number of objects displayed by page of results
+ (sample format: 23)
+* navigation.related-limit : maximum number of related entities to display in
+ the primary view (sample format: 23)
+* navigation.short-line-size : maximum number of characters in short description
+ (sample format: 23)
+
+UI
+~~
+This menu provides you a way to customize the user interface settings such as
+date format or encoding in the produced html.
+Follows the detailled list of available options :
+
+* ui.date-format : how to format date in the ui ("man strftime" for format description)
+* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
+ description)
+* ui.default-text-format : default text format for rich text fields.
+* ui.encoding : user interface encoding
+* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
+ You should also select text/html as default text format to actually get fckeditor.
+* ui.float-format : how to format float numbers in the ui
+* ui.language : language of the user interface
+* ui.main-template : id of main template used to render pages
+* ui.site-title : site title, which is displayed right next to the logo in the header
+* ui.time-format : how to format time in the ui ("man strftime" for format description)
+
+
+Actions
+~~~~~~~
+This menu provides a way to configure the context in which you expect the actions
+to be displayed to the user and if you want the action to be visible or not.
+You must have notice that when you view a list of entities, an action box is
+available on the left column which display some actions as well as a drop-down
+menu for more actions.
+
+The context available are :
+
+* mainactions : actions listed in the left box
+* moreactions : actions listed in the `more` menu of the left box
+* addrelated : add actions listed in the left box
+* useractions : actions listed in the first section of drop-down menu
+ accessible from the right corner user login link
+* siteactions : actions listed in the second section of drop-down menu
+ accessible from the right corner user login link
+* hidden : select this to hide the specific action
+
+Boxes
+~~~~~
+The application has already a pre-defined set of boxes you can use right away.
+This configuration section allows you to place those boxes where you want in the
+application interface to customize it.
+
+The available boxes are :
+
+* actions box : box listing the applicable actions on the displayed data
+
+* boxes_blog_archives_box : box listing the blog archives
+
+* possible views box : box listing the possible views for the displayed data
+
+* rss box : RSS icon to get displayed data as a RSS thread
+
+* search box : search box
+
+* startup views box : box listing the configuration options available for
+ the application site, such as `Preferences` and `Site Configuration`
+
+Components
+~~~~~~~~~~
+[WRITE ME]
+
+Contextual components
+~~~~~~~~~~~~~~~~~~~~~
+[WRITE ME]
+
--- a/doc/book/en/08-site-config.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Interface de configuration du site
-==================================
-
-.. image:: images/lax-book.03-site-config-panel.en.png
-
-This panel allows you to configure the appearance of your application site.
-Six menus are available and we will go through each of them to explain how
-to use them.
-
-Navigation
-~~~~~~~~~~
-This menu provides you a way to adjust some navigation options depending on
-your needs, such as the number of entities to display by page of results.
-Follows the detailled list of available options :
-
-* navigation.combobox-limit : maximum number of entities to display in related
- combo box (sample format: 23)
-* navigation.page-size : maximum number of objects displayed by page of results
- (sample format: 23)
-* navigation.related-limit : maximum number of related entities to display in
- the primary view (sample format: 23)
-* navigation.short-line-size : maximum number of characters in short description
- (sample format: 23)
-
-UI
-~~
-This menu provides you a way to customize the user interface settings such as
-date format or encoding in the produced html.
-Follows the detailled list of available options :
-
-* ui.date-format : how to format date in the ui ("man strftime" for format description)
-* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
- description)
-* ui.default-text-format : default text format for rich text fields.
-* ui.encoding : user interface encoding
-* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
- You should also select text/html as default text format to actually get fckeditor.
-* ui.float-format : how to format float numbers in the ui
-* ui.language : language of the user interface
-* ui.main-template : id of main template used to render pages
-* ui.site-title : site title, which is displayed right next to the logo in the header
-* ui.time-format : how to format time in the ui ("man strftime" for format description)
-
-
-Actions
-~~~~~~~
-This menu provides a way to configure the context in which you expect the actions
-to be displayed to the user and if you want the action to be visible or not.
-You must have notice that when you view a list of entities, an action box is
-available on the left column which display some actions as well as a drop-down
-menu for more actions.
-
-The context available are :
-
-* mainactions : actions listed in the left box
-* moreactions : actions listed in the `more` menu of the left box
-* addrelated : add actions listed in the left box
-* useractions : actions listed in the first section of drop-down menu
- accessible from the right corner user login link
-* siteactions : actions listed in the second section of drop-down menu
- accessible from the right corner user login link
-* hidden : select this to hide the specific action
-
-Boxes
-~~~~~
-The application has already a pre-defined set of boxes you can use right away.
-This configuration section allows you to place those boxes where you want in the
-application interface to customize it.
-
-The available boxes are :
-
-* actions box : box listing the applicable actions on the displayed data
-
-* boxes_blog_archives_box : box listing the blog archives
-
-* possible views box : box listing the possible views for the displayed data
-
-* rss box : RSS icon to get displayed data as a RSS thread
-
-* search box : search box
-
-* startup views box : box listing the configuration options available for
- the application site, such as `Preferences` and `Site Configuration`
-
-Components
-~~~~~~~~~~
-[WRITE ME]
-
-Contextual components
-~~~~~~~~~~~~~~~~~~~~~
-[WRITE ME]
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/09-00-instance-config.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,162 @@
+.. -*- coding: utf-8 -*-
+
+Configuration d'une instance
+============================
+
+À la création d'une instance, un fichier de configuration est généré dans ::
+
+ $(CW_REGISTRY)/<instance>/<nom configuration>.conf
+
+par exemple ::
+
+ /etc/cubicweb.d/jpl/all-in-one.conf
+
+C'est un simple fichier texte au format INI. Dans la description suivante,
+chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
+le cas échéant, e.g. "`<section>.<option>` [valeur]".
+
+
+Configuration du serveur web
+----------------------------
+:`web.auth-mode` [cookie]:
+ mode d'authentification, cookie ou http
+:`web.realm`:
+ realm de l'application en mode d'authentification http
+:`web.http-session-time` [0]:
+ délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
+ en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
+ fermeture du navigateur du client)
+
+:`main.anonymous-user`, `main.anonymous-password`:
+ login et mot de passe à utiliser pour se connecter au serveur RQL lors des
+ connexions HTTP anonymes. Il faut que le compte EUser associé existe.
+
+:`main.base-url`:
+ url de base du site, à utiliser pour générer les urls des pages web
+
+Configuration https
+```````````````````
+Il est possible de rendre un site accessible en http pour les connections
+anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
+utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
+fichier de configuration.
+
+:Exemple:
+
+ pour une redirection apache d'un site accessible via `http://localhost/demo`
+ et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
+ faut avoir pour la version http : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
+
+ et pour la version https : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
+
+
+ et on aura dans le fichier all-in-one.conf de l'instance : ::
+
+ base-url = http://localhost/demo
+ https-url = `https://localhost/demo`
+
+Configuration de l'interface web
+--------------------------------
+:`web.embed-allowed`:
+ expression régulière correspondant aux sites pouvant être "incorporé" dans
+ le site (controleur 'embed')
+:`web.submit-url`:
+ url à laquelle les bugs rencontrés dans l'application peuvent être posté
+
+
+Configuration du serveur RQL
+----------------------------
+:`main.host`:
+ nom de l'hôte s'il ne peut être détecter correctement
+:`main.pid-file`:
+ fichier où sera écrit le pid du serveur
+:`main.uid`:
+ compte utilisateur à utiliser pour le lancement du serveur quand il est
+ lancé en root par init
+:`main.session-time [30*60]`:
+ temps d'expiration d'une session RQL
+:`main.query-log-file`:
+ fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
+
+
+Configuration Pyro pour l'instance
+-----------------------------------
+Coté serveur web :
+
+:`pyro-client.pyro-application-id`:
+ identifiant pyro du serveur RQL (e.g. le nom de l'instance)
+
+Coté serveur RQL :
+
+:`pyro-server.pyro-port`:
+ numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
+ automatiquement.
+
+Coté serveur RQL et serveur web :
+
+:`pyro-name-server.pyro-ns-host`:
+ nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
+ spécifié, il est localisé par une requête de broadcast
+:`pyro-name-server.pyro-ns-group` [cubicweb]:
+ groupe pyro sous lequel enregistrer l'application
+
+
+Configuration courriel
+----------------------
+Coté serveur RQL et serveur web :
+
+:`email.mangle-emails [no]`:
+ indique si les adresses email doivent être affichées telle quelle ou
+ transformée
+
+Coté serveur RQL :
+
+:`email.smtp-host [mail]`:
+ nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
+:`email.smtp-port [25]`:
+ port du serveur SMTP à utiliser pour le courriel sortant
+:`email.sender-name`:
+ nom à utiliser pour les courriels sortant de l'application
+:`email.sender-addr`:
+ adresse à utiliser pour les courriels sortant de l'application
+:`email.default-dest-addrs`:
+ adresses de destination par défaut, si utilisé par la configuration de la
+ diffusion du modèle (séparées par des virgules)
+:`email.supervising-addrs`:
+ addresses de destination des courriels de supervision (séparées par des
+ virgules)
+
+
+Configuration journalisation
+----------------------------
+:`main.log-threshold`:
+ niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
+:`main.log-file`:
+ fichier dans lequel écrire les messages
+
+
+Configuration Eproperties
+-------------------------
+D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
+dans la base de données. Il faut donc les éditer via l'interface web ou par des
+requêtes rql.
+
+:`ui.encoding`:
+ encodage de caractères à utiliser pour l'interface web
+:`navigation.short-line-size`: # XXX should be in ui
+ nombre de caractères maximum pour les affichages "courts"
+:`navigation.page-size`:
+ nombre d'entités maximum à afficher par page de résultat
+:`navigation.related-limit`:
+ nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
+:`navigation.combobox-limit`:
+ nombre d'entités non liées maximum à afficher sur les listes déroulantes de
+ la vue d'édition d'une entité
--- a/doc/book/en/09-instance-config.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Configuration d'une instance
-============================
-
-À la création d'une instance, un fichier de configuration est généré dans ::
-
- $(CW_REGISTRY)/<instance>/<nom configuration>.conf
-
-par exemple ::
-
- /etc/cubicweb.d/jpl/all-in-one.conf
-
-C'est un simple fichier texte au format INI. Dans la description suivante,
-chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
-le cas échéant, e.g. "`<section>.<option>` [valeur]".
-
-
-Configuration du serveur web
-----------------------------
-:`web.auth-mode` [cookie]:
- mode d'authentification, cookie ou http
-:`web.realm`:
- realm de l'application en mode d'authentification http
-:`web.http-session-time` [0]:
- délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
- en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
- fermeture du navigateur du client)
-
-:`main.anonymous-user`, `main.anonymous-password`:
- login et mot de passe à utiliser pour se connecter au serveur RQL lors des
- connexions HTTP anonymes. Il faut que le compte EUser associé existe.
-
-:`main.base-url`:
- url de base du site, à utiliser pour générer les urls des pages web
-
-Configuration https
-```````````````````
-Il est possible de rendre un site accessible en http pour les connections
-anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
-utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
-fichier de configuration.
-
-:Exemple:
-
- pour une redirection apache d'un site accessible via `http://localhost/demo`
- et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
- faut avoir pour la version http : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
-
- et pour la version https : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
-
-
- et on aura dans le fichier all-in-one.conf de l'instance : ::
-
- base-url = http://localhost/demo
- https-url = `https://localhost/demo`
-
-Configuration de l'interface web
---------------------------------
-:`web.embed-allowed`:
- expression régulière correspondant aux sites pouvant être "incorporé" dans
- le site (controleur 'embed')
-:`web.submit-url`:
- url à laquelle les bugs rencontrés dans l'application peuvent être posté
-
-
-Configuration du serveur RQL
-----------------------------
-:`main.host`:
- nom de l'hôte s'il ne peut être détecter correctement
-:`main.pid-file`:
- fichier où sera écrit le pid du serveur
-:`main.uid`:
- compte utilisateur à utiliser pour le lancement du serveur quand il est
- lancé en root par init
-:`main.session-time [30*60]`:
- temps d'expiration d'une session RQL
-:`main.query-log-file`:
- fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
-
-
-Configuration Pyro pour l'instance
------------------------------------
-Coté serveur web :
-
-:`pyro-client.pyro-application-id`:
- identifiant pyro du serveur RQL (e.g. le nom de l'instance)
-
-Coté serveur RQL :
-
-:`pyro-server.pyro-port`:
- numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
- automatiquement.
-
-Coté serveur RQL et serveur web :
-
-:`pyro-name-server.pyro-ns-host`:
- nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
- spécifié, il est localisé par une requête de broadcast
-:`pyro-name-server.pyro-ns-group` [cubicweb]:
- groupe pyro sous lequel enregistrer l'application
-
-
-Configuration courriel
-----------------------
-Coté serveur RQL et serveur web :
-
-:`email.mangle-emails [no]`:
- indique si les adresses email doivent être affichées telle quelle ou
- transformée
-
-Coté serveur RQL :
-
-:`email.smtp-host [mail]`:
- nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
-:`email.smtp-port [25]`:
- port du serveur SMTP à utiliser pour le courriel sortant
-:`email.sender-name`:
- nom à utiliser pour les courriels sortant de l'application
-:`email.sender-addr`:
- adresse à utiliser pour les courriels sortant de l'application
-:`email.default-dest-addrs`:
- adresses de destination par défaut, si utilisé par la configuration de la
- diffusion du modèle (séparées par des virgules)
-:`email.supervising-addrs`:
- addresses de destination des courriels de supervision (séparées par des
- virgules)
-
-
-Configuration journalisation
-----------------------------
-:`main.log-threshold`:
- niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
-:`main.log-file`:
- fichier dans lequel écrire les messages
-
-
-Configuration Eproperties
--------------------------
-D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
-dans la base de données. Il faut donc les éditer via l'interface web ou par des
-requêtes rql.
-
-:`ui.encoding`:
- encodage de caractères à utiliser pour l'interface web
-:`navigation.short-line-size`: # XXX should be in ui
- nombre de caractères maximum pour les affichages "courts"
-:`navigation.page-size`:
- nombre d'entités maximum à afficher par page de résultat
-:`navigation.related-limit`:
- nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
-:`navigation.combobox-limit`:
- nombre d'entités non liées maximum à afficher sur les listes déroulantes de
- la vue d'édition d'une entité
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/10-00-form-management.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,133 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de formulaires
+======================
+
+Contrôle de la génération automatique de formulaire pour les entités manipulée
+------------------------------------------------------------------------------
+XXX FILLME
+
+* les formulaires 'edition' et 'creation'
+
+Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
+obligé de le refaire à la main ! :)
+
+* rtags primary, secondary, generated, generic,
+ `Entity.relation_category(rtype, x='subject')`
+* inline_view (now a rtag?)
+* spécification widget
+
+
+Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
+--------------------------------------------------------------
+
+Contrôle de l'édition
+`````````````````````
+Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
+
+ <nom de champ>:<eid de l'entité>
+
+où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
+dénommera ces paramètres comme *qualifié*.
+
+1. récupération des entités à éditer en cherchant les paramètres de formulaire
+ commençant par 'eid:' ayant également un paramètre '__type' associé
+ (également *qualifié* par l'eid évidemment)
+
+2. pour tous les attributs et relations de chaque entité à éditer
+
+ 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
+ qualifié dans le cas d'une relation dont l'entité est objet
+ 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
+ pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
+ le paramètre <nom relation> (qualifié)
+ 3. si la valeur est différente de l'originale, une requête de modification en
+ base est effectuée
+
+3. pour chaque entité à éditer
+
+ 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <relation type>:<eids>:<target>
+
+ où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
+ autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
+ relation et chaque relation ainsi spécifiée sera insérée.
+
+ 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
+ relations de l'entité spécifiée en valeur de cette argument sont copiées sur
+ l'entité éditée
+
+
+ 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <subject eids>:<relation type>:<object eids>
+
+ où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
+ relation ainsi spécifiée sera supprimée.
+
+ 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
+ même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
+ insérée.
+
+4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
+ ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
+ édité)
+
+5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
+ `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
+ par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
+ relations
+
+
+A noter que :
+
+* si le paramètre `__action_delete` est trouvé, toutes les entités comme
+ spécifiées à éditer seront supprimées
+
+* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
+
+* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
+ normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
+ de la redirection`_)
+
+* le paramètre `__method` est également supporté comme sur le template principal
+ (XXX not very consistent, maybe __method should be dealed in the view controller)
+
+* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
+ `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
+ une erreur est levée
+
+* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
+ valeur de ce paramètre comme message d'information à l'utilisateur une fois
+ l'édition effectuée.
+
+
+Contrôle de la redirection
+``````````````````````````
+Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
+tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
+se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
+controller ça en utilisant les paramètres suivant :
+
+* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
+ de formulaire
+
+* `__redirectparams`: paramètres de formulaires à ajouter au chemin
+
+* `__redirectrql`: requête RQL de redirection
+
+* `__redirectvid`: identifiant de vue de redirection
+
+* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
+ d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
+ page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
+ cas échéant responsable d'afficher les erreurs)
+
+* `__form_id`: identifiant de vue du formulaire original, utilisée si
+ `__action_apply` est trouvé
+
+En général on utilise soit `__redirectpath et `__redirectparams` soit
+`__redirectrql` et `__redirectvid`.
--- a/doc/book/en/10-form-management.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de formulaires
-======================
-
-Contrôle de la génération automatique de formulaire pour les entités manipulée
-------------------------------------------------------------------------------
-XXX FILLME
-
-* les formulaires 'edition' et 'creation'
-
-Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
-obligé de le refaire à la main ! :)
-
-* rtags primary, secondary, generated, generic,
- `Entity.relation_category(rtype, x='subject')`
-* inline_view (now a rtag?)
-* spécification widget
-
-
-Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
---------------------------------------------------------------
-
-Contrôle de l'édition
-`````````````````````
-Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
-
- <nom de champ>:<eid de l'entité>
-
-où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
-dénommera ces paramètres comme *qualifié*.
-
-1. récupération des entités à éditer en cherchant les paramètres de formulaire
- commençant par 'eid:' ayant également un paramètre '__type' associé
- (également *qualifié* par l'eid évidemment)
-
-2. pour tous les attributs et relations de chaque entité à éditer
-
- 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
- qualifié dans le cas d'une relation dont l'entité est objet
- 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
- pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
- le paramètre <nom relation> (qualifié)
- 3. si la valeur est différente de l'originale, une requête de modification en
- base est effectuée
-
-3. pour chaque entité à éditer
-
- 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <relation type>:<eids>:<target>
-
- où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
- autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
- relation et chaque relation ainsi spécifiée sera insérée.
-
- 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
- relations de l'entité spécifiée en valeur de cette argument sont copiées sur
- l'entité éditée
-
-
- 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <subject eids>:<relation type>:<object eids>
-
- où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
- relation ainsi spécifiée sera supprimée.
-
- 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
- même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
- insérée.
-
-4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
- ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
- édité)
-
-5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
- `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
- par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
- relations
-
-
-A noter que :
-
-* si le paramètre `__action_delete` est trouvé, toutes les entités comme
- spécifiées à éditer seront supprimées
-
-* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
-
-* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
- normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
- de la redirection`_)
-
-* le paramètre `__method` est également supporté comme sur le template principal
- (XXX not very consistent, maybe __method should be dealed in the view controller)
-
-* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
- `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
- une erreur est levée
-
-* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
- valeur de ce paramètre comme message d'information à l'utilisateur une fois
- l'édition effectuée.
-
-
-Contrôle de la redirection
-``````````````````````````
-Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
-tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
-se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
-controller ça en utilisant les paramètres suivant :
-
-* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
- de formulaire
-
-* `__redirectparams`: paramètres de formulaires à ajouter au chemin
-
-* `__redirectrql`: requête RQL de redirection
-
-* `__redirectvid`: identifiant de vue de redirection
-
-* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
- d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
- page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
- cas échéant responsable d'afficher les erreurs)
-
-* `__form_id`: identifiant de vue du formulaire original, utilisée si
- `__action_apply` est trouvé
-
-En général on utilise soit `__redirectpath et `__redirectparams` soit
-`__redirectrql` et `__redirectvid`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/11-00-ajax-json.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,16 @@
+.. -*- coding: utf-8 -*-
+
+AJAX
+====
+JSON bla bla
+XXX FILLME
+
+
+Le contrôleur 'json'
+--------------------
+XXX FILLME
+
+
+API Javascript
+--------------
+XXX FILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/11-00-definition-workflow.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,43 @@
+.. -*- coding: utf-8 -*-
+
+Defining a Workflow
+===================
+
+General
+-------
+
+A workflow can be defined in a `LAX` application thanks to the system
+entities ``State`` and ``Transition``. Those are defined within all
+LAX application and can be set-up through the main administrator interface.
+
+Once your schema is defined, you can start creating the set of states and
+the required transitions for your applications entities.
+
+You first need to define the states and then the transitions between those
+to complete your workflow.
+
+A ``State`` defines the status of an entity. While creating a new state,
+you will be first given the option to select the entity type the state
+can be applied to. By choosing ``Apply``, a new section will be displayed
+in the editing screen to enable you to add relation to the state you are
+creating.
+
+A ``Transition`` is also based on an entity type it can be applied to.
+By choosing ``Apply``, a new section will be displayed in the editing
+screen to enable you to add relation to the transition you are
+creating.
+
+At the transition level you will also define the group of user which can
+aplly this transition to an object.
+
+
+Example of a simple workflow
+----------------------------
+
+Please see the tutorial to view and example of a simple workflow.
+
+
+[Create a simple workflow for BlogDemo, to have a moderator approve new blog
+entry to be published. This implies, specify a dedicated group of blog
+moderator as well as hide the view of a blog entry to the user until
+it reaches the published state.]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/11-00-faq.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,110 @@
+.. -*- coding: utf-8 -*-
+
+Frequently Asked Questions
+==========================
+
+* Why does not LAX have a template language ?
+
+ It does. Actually, you can use your preferred template language if you
+ want. [explain how to use a template language]
+
+ The reason template languages are not used in this book is that
+ experience has proved us that using pure python was more efficient.
+
+* Why do you think using pure python is better than using a template language ?
+
+ [copy answer from forum]
+
+ code is easier to maintain, does not have to learn a new dialect
+ each time, real function/classes etc -> real development
+
+* Why do you use the GPL license to prevent me from doing X ?
+
+ [copy answer from forum]
+
+* LAX looks pretty recent. Is it stable ?
+
+ [answer that framework has evolved over the past seven years and that
+ data migrated from one schema to the other ever since]
+
+* Why is the RQL query language looking similar to X ?
+
+ [copy answer from forum, explain why similar to sparql and why better
+ than django and SQL]
+
+* which ajax library
+
+ [we use mochikit and things on top of that]
+
+* `Error while publishing rest text ...`
+
+ While modifying the description of an entity, you get an error message in
+ the application `Error while publishing ...` for Rest text and plain text.
+ The server returns a traceback like as follows :
+ 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
+ Traceback (most recent call last):
+ File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
+ File "/usr/lib/python2.5/codecs.py", line 817, in open
+ file = __builtin__.open(filename, mode, buffering)
+ TypeError: __init__() takes at most 3 arguments (4 given)
+
+
+ This can be fixed by applying the patch described in :
+ http://code.google.com/p/googleappengine/issues/detail?id=48
+[ADD MORE FAQ]
+.. -*- coding: utf-8 -*-
+
+Frequently Asked Questions
+==========================
+
+* Why does not LAX have a template language ?
+
+ It does. Actually, you can use your preferred template language if you
+ want. [explain how to use a template language]
+
+ The reason template languages are not used in this book is that
+ experience has proved us that using pure python was more efficient.
+
+* Why do you think using pure python is better than using a template language ?
+
+ [copy answer from forum]
+
+ code is easier to maintain, does not have to learn a new dialect
+ each time, real function/classes etc -> real development
+
+* Why do you use the GPL license to prevent me from doing X ?
+
+ [copy answer from forum]
+
+* LAX looks pretty recent. Is it stable ?
+
+ [answer that framework has evolved over the past seven years and that
+ data migrated from one schema to the other ever since]
+
+* Why is the RQL query language looking similar to X ?
+
+ [copy answer from forum, explain why similar to sparql and why better
+ than django and SQL]
+
+* which ajax library
+
+ [we use mochikit and things on top of that]
+
+* `Error while publishing rest text ...`
+
+ While modifying the description of an entity, you get an error message in
+ the application `Error while publishing ...` for Rest text and plain text.
+ The server returns a traceback like as follows ::
+
+ 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
+ Traceback (most recent call last):
+ File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
+ (...)
+ File "/usr/lib/python2.5/codecs.py", line 817, in open
+ file = __builtin__.open(filename, mode, buffering)
+ TypeError: __init__() takes at most 3 arguments (4 given)
+
+ This can be fixed by applying the patch described in :
+ `Google group appengine <http://code.google.com/p/googleappengine/issues/detail?id=48>`_
+
+[ADD MORE FAQ]
--- a/doc/book/en/11-ajax-json.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-AJAX
-====
-JSON bla bla
-XXX FILLME
-
-
-Le contrôleur 'json'
---------------------
-XXX FILLME
-
-
-API Javascript
---------------
-XXX FILLME
--- a/doc/book/en/11-definition-workflow.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Defining a Workflow
-===================
-
-General
--------
-
-A workflow can be defined in a `LAX` application thanks to the system
-entities ``State`` and ``Transition``. Those are defined within all
-LAX application and can be set-up through the main administrator interface.
-
-Once your schema is defined, you can start creating the set of states and
-the required transitions for your applications entities.
-
-You first need to define the states and then the transitions between those
-to complete your workflow.
-
-A ``State`` defines the status of an entity. While creating a new state,
-you will be first given the option to select the entity type the state
-can be applied to. By choosing ``Apply``, a new section will be displayed
-in the editing screen to enable you to add relation to the state you are
-creating.
-
-A ``Transition`` is also based on an entity type it can be applied to.
-By choosing ``Apply``, a new section will be displayed in the editing
-screen to enable you to add relation to the transition you are
-creating.
-
-At the transition level you will also define the group of user which can
-aplly this transition to an object.
-
-
-Example of a simple workflow
-----------------------------
-
-Please see the tutorial to view and example of a simple workflow.
-
-
-[Create a simple workflow for BlogDemo, to have a moderator approve new blog
-entry to be published. This implies, specify a dedicated group of blog
-moderator as well as hide the view of a blog entry to the user until
-it reaches the published state.]
--- a/doc/book/en/11-faq.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Frequently Asked Questions
-==========================
-
-* Why does not LAX have a template language ?
-
- It does. Actually, you can use your preferred template language if you
- want. [explain how to use a template language]
-
- The reason template languages are not used in this book is that
- experience has proved us that using pure python was more efficient.
-
-* Why do you think using pure python is better than using a template language ?
-
- [copy answer from forum]
-
- code is easier to maintain, does not have to learn a new dialect
- each time, real function/classes etc -> real development
-
-* Why do you use the GPL license to prevent me from doing X ?
-
- [copy answer from forum]
-
-* LAX looks pretty recent. Is it stable ?
-
- [answer that framework has evolved over the past seven years and that
- data migrated from one schema to the other ever since]
-
-* Why is the RQL query language looking similar to X ?
-
- [copy answer from forum, explain why similar to sparql and why better
- than django and SQL]
-
-* which ajax library
-
- [we use mochikit and things on top of that]
-
-* `Error while publishing rest text ...`
-
- While modifying the description of an entity, you get an error message in
- the application `Error while publishing ...` for Rest text and plain text.
- The server returns a traceback like as follows :
- 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
- Traceback (most recent call last):
- File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
- File "/usr/lib/python2.5/codecs.py", line 817, in open
- file = __builtin__.open(filename, mode, buffering)
- TypeError: __init__() takes at most 3 arguments (4 given)
-
-
- This can be fixed by applying the patch described in :
- http://code.google.com/p/googleappengine/issues/detail?id=48
-[ADD MORE FAQ]
-.. -*- coding: utf-8 -*-
-
-Frequently Asked Questions
-==========================
-
-* Why does not LAX have a template language ?
-
- It does. Actually, you can use your preferred template language if you
- want. [explain how to use a template language]
-
- The reason template languages are not used in this book is that
- experience has proved us that using pure python was more efficient.
-
-* Why do you think using pure python is better than using a template language ?
-
- [copy answer from forum]
-
- code is easier to maintain, does not have to learn a new dialect
- each time, real function/classes etc -> real development
-
-* Why do you use the GPL license to prevent me from doing X ?
-
- [copy answer from forum]
-
-* LAX looks pretty recent. Is it stable ?
-
- [answer that framework has evolved over the past seven years and that
- data migrated from one schema to the other ever since]
-
-* Why is the RQL query language looking similar to X ?
-
- [copy answer from forum, explain why similar to sparql and why better
- than django and SQL]
-
-* which ajax library
-
- [we use mochikit and things on top of that]
-
-* `Error while publishing rest text ...`
-
- While modifying the description of an entity, you get an error message in
- the application `Error while publishing ...` for Rest text and plain text.
- The server returns a traceback like as follows ::
-
- 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
- Traceback (most recent call last):
- File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
- (...)
- File "/usr/lib/python2.5/codecs.py", line 817, in open
- file = __builtin__.open(filename, mode, buffering)
- TypeError: __init__() takes at most 3 arguments (4 given)
-
- This can be fixed by applying the patch described in :
- `Google group appengine <http://code.google.com/p/googleappengine/issues/detail?id=48>`_
-
-[ADD MORE FAQ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/12-00-internationalization.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,100 @@
+.. -*- coding: utf-8 -*-
+
+.. _internationalization:
+
+
+Internationalization
+====================
+
+Cubicweb fully supports the internalization of it's content and interface.
+
+Cubicweb's interface internationalization is based on the translation project `GNU gettext`_.
+
+.. _`GNU gettext`: http://www.gnu.org/software/gettext/
+
+Cubicweb' internalization involves two steps:
+
+* in your Python code and cubicweb-tal templates : mark translatable strings
+
+* in your application : handle the translation catalog
+
+String internalization
+----------------------
+
+In the Python code and cubicweb-tal templates translatable strings can be
+marked in one of the following ways :
+
+ * by using the *built-in* function `_` ::
+
+ class PrimaryView(EntityView):
+ """the full view of an non final entity"""
+ id = 'primary'
+ title = _('primary')
+
+ OR
+
+ * by using the equivalent request's method ::
+
+ class NoResultView(EmptyRsetView):
+ """default view when no result has been found"""
+ id = 'noresult'
+
+ def call(self, **kwargs):
+ self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
+ % self.req._('No result matching query'))
+
+The goal of the *built-in* function `_` is only **to mark the
+translatable strings**, it will only return the translation string
+it-self, but not it's translation.
+
+In the other hand the request's method `_` is ment to retrive the
+proper translation of translation strings in the requested language.
+
+Translations in cubicweb-tal template can also be done with TAL tags
+`i18n:content` and `i18n:replace`.
+
+Note ::
+
+ We dont need to mark the translation strings of entities/relations
+ used by a particular application's schema as they are generated
+ automatically.
+
+
+Handle the translation catalog
+------------------------------
+
+Once the internalization is done in your application's code, you need
+to populate and update the translation catalog. Cubicweb provides the
+following commands for this purpose:
+
+
+* `i18nlibupdate` updates Cubicweb framework's translation
+ catalogs. Unless you work on the framework development, you dont
+ need to use this command.
+
+* `i18nupdate` updates the translation catalogs of *one particular
+ component* (or of all components). FIXME After this command is
+ executed you must update the translation files *.po* in the "i18n"
+ directory of your template. This command will of course not remove
+ existing translations still in use
+
+* `i18ncompile` recompile the transaltion catalogs of *one particular
+ instance* (or of all instances) after the translation catalogs of
+ its components have been updated. This command is automatically
+ called every time you create or update your instance. The compiled
+ catalogs (*.mo*) are stored in the i18n/<lang>/LC_MESSAGES of
+ application where `lang` is the language identifier ('en' or 'fr'
+ for exemple).
+
+
+Example
+```````
+You have added and/or modified some translation strings in your application
+(after creating a new view or modifying the application's schema for exemple).
+To update the translation catalogs you need to do:
+
+1. `cubicweb-ctl i18nupdate <component>`
+2. Edit the <component>/xxx.po files and add missing translations (empty `msgstr`)
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <myapplication>`
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/12-00-reference.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,33 @@
+.. -*- coding: utf-8 -*-
+
+API Reference
+=============
+
+Schema API
+----------
+
+Base Types
+~~~~~~~~~~
+
+Base types are defined as a set in yams.BASE_TYPES that includes:
+`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
+`Interval`, `Password`, `Bytes`.
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+
+Constraints
+~~~~~~~~~~~
+
+Constraints are defined in yams.constraints and include:
+`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
+`BoundConstraint`, `IntervalBoundConstraint`,
+`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+
+Views API
+---------
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+[WRITE ME]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/12-00-ui-components.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,14 @@
+Autres composants de l'interface web
+====================================
+
+Actions
+-------
+XXXFILLME
+
+Component, VComponent
+---------------------
+XXXFILLME
+
+EProperty
+---------
+XXXFILLME
--- a/doc/book/en/12-internationalization.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _internationalization:
-
-
-Internationalization
-====================
-
-Cubicweb fully supports the internalization of it's content and interface.
-
-Cubicweb's interface internationalization is based on the translation project `GNU gettext`_.
-
-.. _`GNU gettext`: http://www.gnu.org/software/gettext/
-
-Cubicweb' internalization involves two steps:
-
-* in your Python code and cubicweb-tal templates : mark translatable strings
-
-* in your application : handle the translation catalog
-
-String internalization
-----------------------
-
-In the Python code and cubicweb-tal templates translatable strings can be
-marked in one of the following ways :
-
- * by using the *built-in* function `_` ::
-
- class PrimaryView(EntityView):
- """the full view of an non final entity"""
- id = 'primary'
- title = _('primary')
-
- OR
-
- * by using the equivalent request's method ::
-
- class NoResultView(EmptyRsetView):
- """default view when no result has been found"""
- id = 'noresult'
-
- def call(self, **kwargs):
- self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
- % self.req._('No result matching query'))
-
-The goal of the *built-in* function `_` is only **to mark the
-translatable strings**, it will only return the translation string
-it-self, but not it's translation.
-
-In the other hand the request's method `_` is ment to retrive the
-proper translation of translation strings in the requested language.
-
-Translations in cubicweb-tal template can also be done with TAL tags
-`i18n:content` and `i18n:replace`.
-
-Note ::
-
- We dont need to mark the translation strings of entities/relations
- used by a particular application's schema as they are generated
- automatically.
-
-
-Handle the translation catalog
-------------------------------
-
-Once the internalization is done in your application's code, you need
-to populate and update the translation catalog. Cubicweb provides the
-following commands for this purpose:
-
-
-* `i18nlibupdate` updates Cubicweb framework's translation
- catalogs. Unless you work on the framework development, you dont
- need to use this command.
-
-* `i18nupdate` updates the translation catalogs of *one particular
- component* (or of all components). FIXME After this command is
- executed you must update the translation files *.po* in the "i18n"
- directory of your template. This command will of course not remove
- existing translations still in use
-
-* `i18ncompile` recompile the transaltion catalogs of *one particular
- instance* (or of all instances) after the translation catalogs of
- its components have been updated. This command is automatically
- called every time you create or update your instance. The compiled
- catalogs (*.mo*) are stored in the i18n/<lang>/LC_MESSAGES of
- application where `lang` is the language identifier ('en' or 'fr'
- for exemple).
-
-
-Example
-```````
-You have added and/or modified some translation strings in your application
-(after creating a new view or modifying the application's schema for exemple).
-To update the translation catalogs you need to do:
-
-1. `cubicweb-ctl i18nupdate <component>`
-2. Edit the <component>/xxx.po files and add missing translations (empty `msgstr`)
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18n compile <myapplication>`
-
--- a/doc/book/en/12-reference.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-API Reference
-=============
-
-Schema API
-----------
-
-Base Types
-~~~~~~~~~~
-
-Base types are defined as a set in yams.BASE_TYPES that includes:
-`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
-`Interval`, `Password`, `Bytes`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Constraints
-~~~~~~~~~~~
-
-Constraints are defined in yams.constraints and include:
-`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
-`BoundConstraint`, `IntervalBoundConstraint`,
-`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Views API
----------
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-[WRITE ME]
-
--- a/doc/book/en/12-ui-components.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Autres composants de l'interface web
-====================================
-
-Actions
--------
-XXXFILLME
-
-Component, VComponent
----------------------
-XXXFILLME
-
-EProperty
----------
-XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/13-00-security.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,45 @@
+.. -*- coding: utf-8 -*-
+
+Utilisateurs de l'application : Le contrôle d'accès
+===================================================
+
+
+Vocabulaire
+-----------
+* Personne, Societe définissent deux *types* d'entité
+* "Personne travaille_pour Societé" déclare qu'une relation
+ travaille_pour peut exister entre une entité de type Personne et une
+ entité de type Societe. L'ensemble des règles de ce type appliqué
+ à la relation "travaille_pour" définit le schéma de la relation
+ "travaille_pour"
+
+
+Description du modèle de sécurité
+---------------------------------
+
+Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
+Control List`. Les notions sont les suivantes :
+
+* utilisateurs et groupes d'utilisateurs
+* un utilisateur appartient à au moins un groupe
+* droits (lire, modifier, créer, supprimer)
+* les droits sont attribués aux groupes (et non aux utilisateurs)
+
+Pour CubicWeb plus spécifiquement :
+
+* on associe les droits au niveau des schemas d'entites / relations
+* pour chaque type d'entité, on distingue les droits de lecture,
+ ajout, modification et suppression
+* pour chaque type de relation, on distingue les droits de lecture,
+ ajout et suppression (on ne peut pas modifer une relation)
+* les groupes de base sont : Administrateurs, Utilisateurs, Invités
+* les utilisateurs font par défaut parti du groupe Utilisateurs
+* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
+ associer uniquement les droits de suppression et de modification
+* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
+ ajoutés implicitement dans le contexte des objets dont ils sont
+ propriétaires
+* les droits de ce groupe ne sont vérifiés que sur
+ modification / suppression si tous les autres groupes auxquels
+ l'utilisateur appartient se sont vu interdir l'accès
+
--- a/doc/book/en/13-security.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Utilisateurs de l'application : Le contrôle d'accès
-===================================================
-
-
-Vocabulaire
------------
-* Personne, Societe définissent deux *types* d'entité
-* "Personne travaille_pour Societé" déclare qu'une relation
- travaille_pour peut exister entre une entité de type Personne et une
- entité de type Societe. L'ensemble des règles de ce type appliqué
- à la relation "travaille_pour" définit le schéma de la relation
- "travaille_pour"
-
-
-Description du modèle de sécurité
----------------------------------
-
-Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
-Control List`. Les notions sont les suivantes :
-
-* utilisateurs et groupes d'utilisateurs
-* un utilisateur appartient à au moins un groupe
-* droits (lire, modifier, créer, supprimer)
-* les droits sont attribués aux groupes (et non aux utilisateurs)
-
-Pour CubicWeb plus spécifiquement :
-
-* on associe les droits au niveau des schemas d'entites / relations
-* pour chaque type d'entité, on distingue les droits de lecture,
- ajout, modification et suppression
-* pour chaque type de relation, on distingue les droits de lecture,
- ajout et suppression (on ne peut pas modifer une relation)
-* les groupes de base sont : Administrateurs, Utilisateurs, Invités
-* les utilisateurs font par défaut parti du groupe Utilisateurs
-* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
- associer uniquement les droits de suppression et de modification
-* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
- ajoutés implicitement dans le contexte des objets dont ils sont
- propriétaires
-* les droits de ce groupe ne sont vérifiés que sur
- modification / suppression si tous les autres groupes auxquels
- l'utilisateur appartient se sont vu interdir l'accès
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/14-00-hooks.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,31 @@
+.. -*- coding: utf-8 -*-
+
+Les crochets (*hooks*)
+======================
+
+XXX FILLME
+
+Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
+relations dans le dépot
+
+Leur prototypes sont les suivants
+
+
+ * after_add_entity (session, entity)
+ * after_update_entity (session, entity)
+ * after_delete_entity (session, eid)
+ * before_add_entity (session, entity)
+ * before_update_entity (session, entity)
+ * before_delete_entity (session, eid)
+
+ * after_add_relation (session, fromeid, rtype, toeid)
+ * after_delete_relation (session, fromeid, rtype, toeid)
+ * before_add_relation (session, fromeid, rtype, toeid)
+ * before_delete_relation (session, fromeid, rtype, toeid)
+
+ * server_startup
+ * server_shutdown
+
+ * session_open
+ * session_close
+
--- a/doc/book/en/14-hooks.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Les crochets (*hooks*)
-======================
-
-XXX FILLME
-
-Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
-relations dans le dépot
-
-Leur prototypes sont les suivants
-
-
- * after_add_entity (session, entity)
- * after_update_entity (session, entity)
- * after_delete_entity (session, eid)
- * before_add_entity (session, entity)
- * before_update_entity (session, entity)
- * before_delete_entity (session, eid)
-
- * after_add_relation (session, fromeid, rtype, toeid)
- * after_delete_relation (session, fromeid, rtype, toeid)
- * before_add_relation (session, fromeid, rtype, toeid)
- * before_delete_relation (session, fromeid, rtype, toeid)
-
- * server_startup
- * server_shutdown
-
- * session_open
- * session_close
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/15-00-notifications.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de notifications
+========================
+
+XXX FILLME
--- a/doc/book/en/15-notifications.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de notifications
-========================
-
-XXX FILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/16-00-rql.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,11 @@
+.. -*- coding: utf-8 -*-
+
+Le langage RQL (Relation Query Language)
+========================================
+
+Voir la `documentation de RQL <file:///home/sandrine/src/fcubicweb/rql/doc/build/html/index.html>`_ .
+
+
+[TODO]
+Specific link to RQL complete documentation to remove duplicated content.
+
--- a/doc/book/en/16-rql.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Le langage RQL (Relation Query Language)
-========================================
-
-Voir la `documentation de RQL <file:///home/sandrine/src/fcubicweb/rql/doc/build/html/index.html>`_ .
-
-
-[TODO]
-Specific link to RQL complete documentation to remove duplicated content.
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/17-00-migration.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+
+Migration
+=========
+
+Une des idées de base d'Erudi est la création incrémentale d'application, et
+pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
+une application et tout particulièrement le modèle de données manipulé sans
+perdre les données des instances existantes.
+
+La version courante d'un modèle d'application est données dans le fichier
+`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
+
+
+Gestion des scripts de migrations
+---------------------------------
+Les scripts des migrations doivent être placés dans le répertoire `migration` de
+l'application, et nommé de la manière suivante :
+
+::
+
+ <n° de version X.Y.Z>[_<description>]_<mode>.py
+
+dans lequel :
+
+* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
+ migrer,
+
+* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
+ de l'application (serveur RQL, serveur web) le script s'applique en cas
+ d'installation distribuée. Il peut valoir :
+
+ * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
+ et met à jour des fichiers sur le disque (migration de fichier de
+ configuration par exemple).
+
+ * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
+ sur le disque
+
+ * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
+ fichiers sur le disque
+
+ * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
+ données en base (migrations de schéma et de données par ex.)
+
+
+Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
+d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
+d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
+des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
+une ligne de la manière suivante : ::
+
+ <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
+
+Par exemple ::
+
+ 0.12.0: 2.26.0
+ 0.13.0: 2.27.0
+ # 0.14 works with 2.27 <= erudi <= 2.28 at least
+ 0.15.0: 2.28.0
+
+
+Contexte de base
+----------------
+Les identifiants suivants sont préféfinis dans les scripts de migration :
+
+* `config`, configuration de l'instance
+
+* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
+ interactif ou non
+
+* `appltemplversion`, version du modèle d'application de l'instance
+
+* `applerudiversion`, version erudi de l'instance
+
+* `templversion`, version du modéle d'application installée
+
+* `erudiversion`, version erudi installée
+
+* `confirm(question)`, fonction posant une question et retournant vrai si
+ l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
+ interactif)
+
+* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
+ internationaliser dans les scripts de migration
+
+Dans les scripts "repository", les identifiants suivant sont également définis :
+
+* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
+
+* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
+ cours de migration)
+
+* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
+ version à jour du modèle et de erudi)
+
+* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
+ nécessaire ou avantageux de passer par du sql
+
+* `repo`, l'objet repository
+
+
+Migration de schéma
+-------------------
+Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
+ nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
+ spécifié il est extrait du schéma à jour.
+
+* `drop_attribute(etype, attrname, commit=True)`, supprime un
+ attribut à un type d'entité existante.
+
+* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
+
+* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
+ d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
+ et ayant un type d'entité connu à l'autre extrémité vont également être
+ ajoutées.
+
+* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
+ les relations l'utilisant.
+
+* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
+
+* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
+ de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
+ type seront également ajoutées.
+
+* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
+ toutes les définitions de ce type.
+
+* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
+
+* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
+ définition de relation.
+
+* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
+ une définition de relation.
+
+* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
+ d'un type d'entité ou de relation
+
+* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
+ permissions d'un type de relation.
+
+* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
+ permissions d'un type d'entité.
+
+* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
+ schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
+ de relations ni de définitions de relation).
+
+* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
+ les propriétés d'une definition de relation en utilisant les arguments nommés
+ pour les propriétés à changer.
+
+* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
+ pour la relation <rtype> du type d'entité <etype>
+
+* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
+ de taille pour la relation <rtype> du type d'entité <etype>
+
+
+Migration de données
+--------------------
+Les fonctions de migration de données suivantes sont disponibles dans les scripts
+"repository" :
+
+* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
+ requête rql arbitraire, d'interrogation ou de modification. Un objet result
+ set est retourné.
+
+* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
+ données. La valeur des attributs et relations est spécifiée en utilisant les
+ arguments nommés et positionnels.
+
+
+Création de workflow
+--------------------
+Les fonctions de création de workflow suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
+ nouvel état de workflow
+
+* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
+ ajoute une nouvelle transtion de workflow
+
+Migration de configuration
+--------------------------
+Les fonctions de migration de configuration suivantes sont disponibles dans tout
+les scripts :
+
+* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
+
+* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
+ changé de groupe
+
+* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
+
+* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
+
+
+Autres fonctions de migration
+-----------------------------
+Ces fonctions ne sont utilisés que pour des opérations de bas niveau
+irréalisables autrement ou pour réparer des bases cassées lors de session
+interactive. Elles sont disponibles dans les scripts "repository".
+
+* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
+ arbitraire, à n'utiliser
+
+* `add_entity_type_table(etype, commit=True)`
+* `add_relation_type_table(rtype, commit=True)`
+* `uninline_relation(rtype, commit=True)`
--- a/doc/book/en/17-migration.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Migration
-=========
-
-Une des idées de base d'Erudi est la création incrémentale d'application, et
-pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
-une application et tout particulièrement le modèle de données manipulé sans
-perdre les données des instances existantes.
-
-La version courante d'un modèle d'application est données dans le fichier
-`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
-
-
-Gestion des scripts de migrations
----------------------------------
-Les scripts des migrations doivent être placés dans le répertoire `migration` de
-l'application, et nommé de la manière suivante :
-
-::
-
- <n° de version X.Y.Z>[_<description>]_<mode>.py
-
-dans lequel :
-
-* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
- migrer,
-
-* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
- de l'application (serveur RQL, serveur web) le script s'applique en cas
- d'installation distribuée. Il peut valoir :
-
- * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
- et met à jour des fichiers sur le disque (migration de fichier de
- configuration par exemple).
-
- * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
- sur le disque
-
- * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
- fichiers sur le disque
-
- * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
- données en base (migrations de schéma et de données par ex.)
-
-
-Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
-d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
-d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
-des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
-une ligne de la manière suivante : ::
-
- <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
-
-Par exemple ::
-
- 0.12.0: 2.26.0
- 0.13.0: 2.27.0
- # 0.14 works with 2.27 <= erudi <= 2.28 at least
- 0.15.0: 2.28.0
-
-
-Contexte de base
-----------------
-Les identifiants suivants sont préféfinis dans les scripts de migration :
-
-* `config`, configuration de l'instance
-
-* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
- interactif ou non
-
-* `appltemplversion`, version du modèle d'application de l'instance
-
-* `applerudiversion`, version erudi de l'instance
-
-* `templversion`, version du modéle d'application installée
-
-* `erudiversion`, version erudi installée
-
-* `confirm(question)`, fonction posant une question et retournant vrai si
- l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
- interactif)
-
-* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
- internationaliser dans les scripts de migration
-
-Dans les scripts "repository", les identifiants suivant sont également définis :
-
-* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
-
-* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
- cours de migration)
-
-* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
- version à jour du modèle et de erudi)
-
-* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
- nécessaire ou avantageux de passer par du sql
-
-* `repo`, l'objet repository
-
-
-Migration de schéma
--------------------
-Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
- nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
- spécifié il est extrait du schéma à jour.
-
-* `drop_attribute(etype, attrname, commit=True)`, supprime un
- attribut à un type d'entité existante.
-
-* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
-
-* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
- d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
- et ayant un type d'entité connu à l'autre extrémité vont également être
- ajoutées.
-
-* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
- les relations l'utilisant.
-
-* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
-
-* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
- de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
- type seront également ajoutées.
-
-* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
- toutes les définitions de ce type.
-
-* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
-
-* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
- définition de relation.
-
-* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
- une définition de relation.
-
-* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
- d'un type d'entité ou de relation
-
-* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
- permissions d'un type de relation.
-
-* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
- permissions d'un type d'entité.
-
-* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
- schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
- de relations ni de définitions de relation).
-
-* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
- les propriétés d'une definition de relation en utilisant les arguments nommés
- pour les propriétés à changer.
-
-* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
- pour la relation <rtype> du type d'entité <etype>
-
-* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
- de taille pour la relation <rtype> du type d'entité <etype>
-
-
-Migration de données
---------------------
-Les fonctions de migration de données suivantes sont disponibles dans les scripts
-"repository" :
-
-* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
- requête rql arbitraire, d'interrogation ou de modification. Un objet result
- set est retourné.
-
-* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
- données. La valeur des attributs et relations est spécifiée en utilisant les
- arguments nommés et positionnels.
-
-
-Création de workflow
---------------------
-Les fonctions de création de workflow suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
- nouvel état de workflow
-
-* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
- ajoute une nouvelle transtion de workflow
-
-Migration de configuration
---------------------------
-Les fonctions de migration de configuration suivantes sont disponibles dans tout
-les scripts :
-
-* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
-
-* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
- changé de groupe
-
-* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
-
-* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
-
-
-Autres fonctions de migration
------------------------------
-Ces fonctions ne sont utilisés que pour des opérations de bas niveau
-irréalisables autrement ou pour réparer des bases cassées lors de session
-interactive. Elles sont disponibles dans les scripts "repository".
-
-* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
- arbitraire, à n'utiliser
-
-* `add_entity_type_table(etype, commit=True)`
-* `add_relation_type_table(rtype, commit=True)`
-* `uninline_relation(rtype, commit=True)`
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/18-00-tests.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,38 @@
+.. -*- coding: utf-8 -*-
+
+Tests
+=====
+
+Écriture de tests unitaires
+---------------------------
+Le framework de test fournit principalement deux classes de tests dans le module
+`ginco.devtools.apptest`:
+
+* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
+* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
+
+Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
+rendant l'écriture de test puissante et rapide.
+
+XXXFILLME describe API
+
+Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
+unitaires ou fonctionnels pour vos entités, vues, crochets...
+
+
+Test des courriels de notifications
+```````````````````````````````````
+Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
+envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
+liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
+et `RepositoryBasedTC`).
+
+Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
+contient des objets ayant deux attributs :
+* `recipients`, la liste des destinataires
+* `msg`, l'objet email.Message
+
+
+Tests automatiques
+------------------
+XXXFILLME
--- a/doc/book/en/18-tests.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Tests
-=====
-
-Écriture de tests unitaires
----------------------------
-Le framework de test fournit principalement deux classes de tests dans le module
-`ginco.devtools.apptest`:
-
-* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
-* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
-
-Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
-rendant l'écriture de test puissante et rapide.
-
-XXXFILLME describe API
-
-Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
-unitaires ou fonctionnels pour vos entités, vues, crochets...
-
-
-Test des courriels de notifications
-```````````````````````````````````
-Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
-envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
-liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
-et `RepositoryBasedTC`).
-
-Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
-contient des objets ayant deux attributs :
-* `recipients`, la liste des destinataires
-* `msg`, l'objet email.Message
-
-
-Tests automatiques
-------------------
-XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/19-00-i18n.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,71 @@
+.. -*- coding: utf-8 -*-
+
+.. _Internationalisation:
+
+
+Internationalisation
+====================
+
+Le système d'internationalisation de l'interface web de CubicWeb est basé sur le
+système `GNU gettext`_.
+
+.. _`GNU gettext`: http://www.gnu.org/software/gettext/
+
+Messages à internationaliser
+----------------------------
+
+Marquage des messages à internaliser
+````````````````````````````````````
+Les chaines de caractères à internationaliser sont marqués par l'appel à la
+fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
+dans les expressions python de template TAL.
+
+Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
+traduire via les balises `i18n:content` et `i18n:replace`.
+
+De plus des messages correspondant aux entités/relations utilisés par le schéma
+de l'application seront automatiquement ajoutés.
+
+Renvoi d'un message internationalisé lors de la construction d'une page
+```````````````````````````````````````````````````````````````````````
+La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
+traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
+méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
+message au lieu de sa traduction dans la langue propre à la requête.1
+
+
+Gestion des catalogues de traduction
+------------------------------------
+Une fois l'application rendu internationalisable coté code, reste à gérer les
+catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes :
+
+* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie
+ cubicweb*. Sauf si vous développez sur le framework (et non votre propre
+ application), vous ne devriez pas avoir à utiliser cette commande
+
+* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous
+ les composants). A la suite de cette commande, vous devez mettre à jour les
+ fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
+ template. Évidemment les traductions précédentes toujours utilisées ont été
+ conservées.
+
+* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de
+ toutes les instances) après mise à jour des catalogues de son composant. Cela
+ est effectué automatiquement lors d'une création ou d'une mise à jour. Les
+ catalogues de messages compilés se trouvent dans le répertoire
+ "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
+ l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
+
+
+Le cas classique
+````````````````
+Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
+application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
+exemple) :
+
+1. `cubicweb-ctl i18nupdate <composant>`
+2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
+ manquantes (`msgstr` vide)
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <monapplication>`
+
--- a/doc/book/en/19-i18n.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Internationalisation:
-
-
-Internationalisation
-====================
-
-Le système d'internationalisation de l'interface web de CubicWeb est basé sur le
-système `GNU gettext`_.
-
-.. _`GNU gettext`: http://www.gnu.org/software/gettext/
-
-Messages à internationaliser
-----------------------------
-
-Marquage des messages à internaliser
-````````````````````````````````````
-Les chaines de caractères à internationaliser sont marqués par l'appel à la
-fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
-dans les expressions python de template TAL.
-
-Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
-traduire via les balises `i18n:content` et `i18n:replace`.
-
-De plus des messages correspondant aux entités/relations utilisés par le schéma
-de l'application seront automatiquement ajoutés.
-
-Renvoi d'un message internationalisé lors de la construction d'une page
-```````````````````````````````````````````````````````````````````````
-La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
-traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
-méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
-message au lieu de sa traduction dans la langue propre à la requête.1
-
-
-Gestion des catalogues de traduction
-------------------------------------
-Une fois l'application rendu internationalisable coté code, reste à gérer les
-catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes :
-
-* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie
- cubicweb*. Sauf si vous développez sur le framework (et non votre propre
- application), vous ne devriez pas avoir à utiliser cette commande
-
-* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous
- les composants). A la suite de cette commande, vous devez mettre à jour les
- fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
- template. Évidemment les traductions précédentes toujours utilisées ont été
- conservées.
-
-* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de
- toutes les instances) après mise à jour des catalogues de son composant. Cela
- est effectué automatiquement lors d'une création ou d'une mise à jour. Les
- catalogues de messages compilés se trouvent dans le répertoire
- "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
- l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
-
-
-Le cas classique
-````````````````
-Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
-application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
-exemple) :
-
-1. `cubicweb-ctl i18nupdate <composant>`
-2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
- manquantes (`msgstr` vide)
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18n compile <monapplication>`
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-00-google-appengine.en.txt Thu Nov 20 20:14:23 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/20-google-appengine.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-.. -*- 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/21-00-appendix.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,17 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+Appendix
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ 21-01-architecture.en.txt
+ 21-02-querier.en.txt
+ 21-03-modules-stdlib.en.txt
+ 21-04-modules-cbw-api.en.txt
+ 21-05-mercurial.en.txt
+ 21-06-mercurial-forest.en.txt
+
--- a/doc/book/en/21-appendix.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-Appendix
-========
-
-.. toctree::
- :maxdepth: 1
-
- 21-01-architecture.en.txt
- 21-02-querier.en.txt
- 21-03-modules-stdlib.en.txt
- 21-04-modules-cbw-api.en.txt
- 21-05-mercurial.en.txt
- 21-06-mercurial-forest.en.txt
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/22-00-faq.en.txt Thu Nov 20 20:14:23 2008 +0100
@@ -0,0 +1,55 @@
+.. -*- coding: utf-8 -*-
+
+Foire Aux Questions
+===================
+
+[FILL ME]
+
+* A quoi servent les crochets?
+
+ Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
+ permet d'executer des actions specifiques lors d'un acces a la base
+ de donnees, ce qui donne un controle de la base de donnees afin de
+ prevenir l'insertion de `mauvaises` entites dans la base.
+
+* Quand utiliser un template HTML plutot qu'un composant graphique?
+
+ Un template HTML ne peut contenir de logique, il ne permettra donc
+ que de definir une vue statique. Un composant permet lui de gerer
+ plus de logique et d'operations sur le contexte dans lequel il
+ s'applique. Il faut donc bien reflechir avant de decider de l'un ou
+ de l'autre, mais vous avez la possibilite de choisir.
+
+* Comment mettre à jour une base de données après avoir modifié le schéma?
+
+ Cela dépend de ce qui a été modifié dans le schéma.
+
+ * Modification d'une relation non finale
+
+ * Modification d'une relation finale
+
+[TO COMPLETE]
+
+* Comment créer un utilisateur anonyme?
+
+ Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
+ Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
+ anonyme en initilisant les valeurs des variables suivantes ::
+
+ # login of the Erudi user account to use for anonymous user (if you want to
+ # allow anonymous)
+ anonymous-user=anon
+
+ # password of the Erudi user account matching login
+ anonymous-password=anon
+
+ Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
+ de données, le plus simple étant de s'identifier sur votre application en
+ administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
+
+* Quelle est la différence entre `AppRsetObject` et `AppObject` ?
+
+ La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
+ les instances de la premières sont séléctionnées pour une requête et un "result
+ set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
+ identifiant.
--- a/doc/book/en/22-faq.en.txt Thu Nov 20 10:25:44 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Foire Aux Questions
-===================
-
-[FILL ME]
-
-* A quoi servent les crochets?
-
- Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
- permet d'executer des actions specifiques lors d'un acces a la base
- de donnees, ce qui donne un controle de la base de donnees afin de
- prevenir l'insertion de `mauvaises` entites dans la base.
-
-* Quand utiliser un template HTML plutot qu'un composant graphique?
-
- Un template HTML ne peut contenir de logique, il ne permettra donc
- que de definir une vue statique. Un composant permet lui de gerer
- plus de logique et d'operations sur le contexte dans lequel il
- s'applique. Il faut donc bien reflechir avant de decider de l'un ou
- de l'autre, mais vous avez la possibilite de choisir.
-
-* Comment mettre à jour une base de données après avoir modifié le schéma?
-
- Cela dépend de ce qui a été modifié dans le schéma.
-
- * Modification d'une relation non finale
-
- * Modification d'une relation finale
-
-[TO COMPLETE]
-
-* Comment créer un utilisateur anonyme?
-
- Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
- Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
- anonyme en initilisant les valeurs des variables suivantes ::
-
- # login of the Erudi user account to use for anonymous user (if you want to
- # allow anonymous)
- anonymous-user=anon
-
- # password of the Erudi user account matching login
- anonymous-password=anon
-
- Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
- de données, le plus simple étant de s'identifier sur votre application en
- administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
-
-* Quelle est la différence entre `AppRsetObject` et `AppObject` ?
-
- La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
- les instances de la premières sont séléctionnées pour une requête et un "result
- set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
- identifiant.
--- a/misc/migration/3.0.0_Any.py Thu Nov 20 10:25:44 2008 -0800
+++ b/misc/migration/3.0.0_Any.py Thu Nov 20 20:14:23 2008 +0100
@@ -7,3 +7,5 @@
rql('SET X pkey %(newk)s WHERE X pkey %(oldk)s',
{'oldk': pk, 'newk': newk})
print 'renamed', pk, 'to', newk
+
+add_entity_type('ECache')