[doc] Restructure the documentation
authorChristophe de Vienne <christophe@unlish.com>
Thu, 08 Jan 2015 22:11:06 +0100
changeset 10491 c67bcee93248
parent 10490 76ab3c71aff2
child 10492 68c13e0c0fc5
[doc] Restructure the documentation * Create a new index file * Move the sphinx configuration files do the documentation root * Move book/README to dev/documenting.rst * Move book/mode_plan.py to tools/ * Move book/en/images to images * Move book/en/* to book/ * Move changelogs to changes/* * Adapt the Makefile * Add a title to the javascript api index Related to #4832808
.hgignore
doc/3.14.rst
doc/3.15.rst
doc/3.16.rst
doc/3.17.rst
doc/3.18.rst
doc/3.19.rst
doc/3.20.rst
doc/Makefile
doc/_static/cubicweb.png
doc/_static/logilab.png
doc/_static/sphinx-default.css
doc/_templates/layout.html
doc/_themes/cubicweb/layout.html
doc/_themes/cubicweb/static/cubicweb.css_t
doc/_themes/cubicweb/static/cubicweb.ico
doc/_themes/cubicweb/static/logo-cubicweb-small.svg
doc/_themes/cubicweb/static/logo-cubicweb.svg
doc/_themes/cubicweb/theme.conf
doc/book/MERGE_ME-tut-create-app.en.txt
doc/book/MERGE_ME-tut-create-gae-app.en.txt
doc/book/README
doc/book/additionnal_services/index.rst
doc/book/additionnal_services/undo.rst
doc/book/admin/additional-tips.rst
doc/book/admin/config.rst
doc/book/admin/create-instance.rst
doc/book/admin/cubicweb-ctl.rst
doc/book/admin/index.rst
doc/book/admin/instance-config.rst
doc/book/admin/ldap.rst
doc/book/admin/migration.rst
doc/book/admin/multisources.rst
doc/book/admin/pyro.rst
doc/book/admin/rql-logs.rst
doc/book/admin/setup-windows.rst
doc/book/admin/setup.rst
doc/book/admin/site-config.rst
doc/book/annexes/depends.rst
doc/book/annexes/docstrings-conventions.rst
doc/book/annexes/faq.rst
doc/book/annexes/index.rst
doc/book/annexes/mercurial.rst
doc/book/annexes/rql/Graph-ex.gif
doc/book/annexes/rql/debugging.rst
doc/book/annexes/rql/implementation.rst
doc/book/annexes/rql/index.rst
doc/book/annexes/rql/intro.rst
doc/book/annexes/rql/language.rst
doc/book/devrepo/cubes/available-cubes.rst
doc/book/devrepo/cubes/cc-newcube.rst
doc/book/devrepo/cubes/index.rst
doc/book/devrepo/cubes/layout.rst
doc/book/devrepo/dataimport.rst
doc/book/devrepo/datamodel/baseschema.rst
doc/book/devrepo/datamodel/define-workflows.rst
doc/book/devrepo/datamodel/definition.rst
doc/book/devrepo/datamodel/index.rst
doc/book/devrepo/datamodel/metadata.rst
doc/book/devrepo/devcore/dbapi.rst
doc/book/devrepo/devcore/index.rst
doc/book/devrepo/devcore/reqbase.rst
doc/book/devrepo/entityclasses/adapters.rst
doc/book/devrepo/entityclasses/application-logic.rst
doc/book/devrepo/entityclasses/data-as-objects.rst
doc/book/devrepo/entityclasses/index.rst
doc/book/devrepo/entityclasses/load-sort.rst
doc/book/devrepo/fti.rst
doc/book/devrepo/index.rst
doc/book/devrepo/migration.rst
doc/book/devrepo/profiling.rst
doc/book/devrepo/repo/hooks.rst
doc/book/devrepo/repo/index.rst
doc/book/devrepo/repo/notifications.rst
doc/book/devrepo/repo/sessions.rst
doc/book/devrepo/repo/tasks.rst
doc/book/devrepo/testing.rst
doc/book/devrepo/vreg.rst
doc/book/devweb/ajax.rst
doc/book/devweb/controllers.rst
doc/book/devweb/css.rst
doc/book/devweb/edition/dissection.rst
doc/book/devweb/edition/editcontroller.rst
doc/book/devweb/edition/examples.rst
doc/book/devweb/edition/form.rst
doc/book/devweb/edition/index.rst
doc/book/devweb/facets.rst
doc/book/devweb/httpcaching.rst
doc/book/devweb/index.rst
doc/book/devweb/internationalization.rst
doc/book/devweb/js.rst
doc/book/devweb/property.rst
doc/book/devweb/publisher.rst
doc/book/devweb/request.rst
doc/book/devweb/resource.rst
doc/book/devweb/rtags.rst
doc/book/devweb/searchbar.rst
doc/book/devweb/views/basetemplates.rst
doc/book/devweb/views/baseviews.rst
doc/book/devweb/views/boxes.rst
doc/book/devweb/views/breadcrumbs.rst
doc/book/devweb/views/idownloadable.rst
doc/book/devweb/views/index.rst
doc/book/devweb/views/primary.rst
doc/book/devweb/views/reledit.rst
doc/book/devweb/views/startup.rst
doc/book/devweb/views/table.rst
doc/book/devweb/views/urlpublish.rst
doc/book/devweb/views/views.rst
doc/book/devweb/views/wdoc.rst
doc/book/devweb/views/xmlrss.rst
doc/book/en/.static/cubicweb.png
doc/book/en/.static/logilab.png
doc/book/en/.static/sphinx-default.css
doc/book/en/.templates/layout.html
doc/book/en/MERGE_ME-tut-create-app.en.txt
doc/book/en/MERGE_ME-tut-create-gae-app.en.txt
doc/book/en/_themes/cubicweb/layout.html
doc/book/en/_themes/cubicweb/static/cubicweb.css_t
doc/book/en/_themes/cubicweb/static/cubicweb.ico
doc/book/en/_themes/cubicweb/static/logo-cubicweb-small.svg
doc/book/en/_themes/cubicweb/static/logo-cubicweb.svg
doc/book/en/_themes/cubicweb/theme.conf
doc/book/en/additionnal_services/index.rst
doc/book/en/additionnal_services/undo.rst
doc/book/en/admin/additional-tips.rst
doc/book/en/admin/config.rst
doc/book/en/admin/create-instance.rst
doc/book/en/admin/cubicweb-ctl.rst
doc/book/en/admin/index.rst
doc/book/en/admin/instance-config.rst
doc/book/en/admin/ldap.rst
doc/book/en/admin/migration.rst
doc/book/en/admin/multisources.rst
doc/book/en/admin/rql-logs.rst
doc/book/en/admin/setup-windows.rst
doc/book/en/admin/setup.rst
doc/book/en/admin/site-config.rst
doc/book/en/annexes/depends.rst
doc/book/en/annexes/docstrings-conventions.rst
doc/book/en/annexes/faq.rst
doc/book/en/annexes/index.rst
doc/book/en/annexes/mercurial.rst
doc/book/en/annexes/rql/Graph-ex.gif
doc/book/en/annexes/rql/debugging.rst
doc/book/en/annexes/rql/implementation.rst
doc/book/en/annexes/rql/index.rst
doc/book/en/annexes/rql/intro.rst
doc/book/en/annexes/rql/language.rst
doc/book/en/conf.py
doc/book/en/devrepo/cubes/available-cubes.rst
doc/book/en/devrepo/cubes/cc-newcube.rst
doc/book/en/devrepo/cubes/index.rst
doc/book/en/devrepo/cubes/layout.rst
doc/book/en/devrepo/dataimport.rst
doc/book/en/devrepo/datamodel/baseschema.rst
doc/book/en/devrepo/datamodel/define-workflows.rst
doc/book/en/devrepo/datamodel/definition.rst
doc/book/en/devrepo/datamodel/index.rst
doc/book/en/devrepo/datamodel/metadata.rst
doc/book/en/devrepo/devcore/index.rst
doc/book/en/devrepo/devcore/reqbase.rst
doc/book/en/devrepo/entityclasses/adapters.rst
doc/book/en/devrepo/entityclasses/application-logic.rst
doc/book/en/devrepo/entityclasses/data-as-objects.rst
doc/book/en/devrepo/entityclasses/index.rst
doc/book/en/devrepo/entityclasses/load-sort.rst
doc/book/en/devrepo/fti.rst
doc/book/en/devrepo/index.rst
doc/book/en/devrepo/migration.rst
doc/book/en/devrepo/profiling.rst
doc/book/en/devrepo/repo/hooks.rst
doc/book/en/devrepo/repo/index.rst
doc/book/en/devrepo/repo/notifications.rst
doc/book/en/devrepo/repo/sessions.rst
doc/book/en/devrepo/repo/tasks.rst
doc/book/en/devrepo/testing.rst
doc/book/en/devrepo/vreg.rst
doc/book/en/devweb/ajax.rst
doc/book/en/devweb/controllers.rst
doc/book/en/devweb/css.rst
doc/book/en/devweb/edition/dissection.rst
doc/book/en/devweb/edition/editcontroller.rst
doc/book/en/devweb/edition/examples.rst
doc/book/en/devweb/edition/form.rst
doc/book/en/devweb/edition/index.rst
doc/book/en/devweb/facets.rst
doc/book/en/devweb/httpcaching.rst
doc/book/en/devweb/index.rst
doc/book/en/devweb/internationalization.rst
doc/book/en/devweb/js.rst
doc/book/en/devweb/property.rst
doc/book/en/devweb/publisher.rst
doc/book/en/devweb/request.rst
doc/book/en/devweb/resource.rst
doc/book/en/devweb/rtags.rst
doc/book/en/devweb/searchbar.rst
doc/book/en/devweb/views/basetemplates.rst
doc/book/en/devweb/views/baseviews.rst
doc/book/en/devweb/views/boxes.rst
doc/book/en/devweb/views/breadcrumbs.rst
doc/book/en/devweb/views/idownloadable.rst
doc/book/en/devweb/views/index.rst
doc/book/en/devweb/views/primary.rst
doc/book/en/devweb/views/reledit.rst
doc/book/en/devweb/views/startup.rst
doc/book/en/devweb/views/table.rst
doc/book/en/devweb/views/urlpublish.rst
doc/book/en/devweb/views/views.rst
doc/book/en/devweb/views/wdoc.rst
doc/book/en/devweb/views/xmlrss.rst
doc/book/en/images/03-transitions-view_en.png
doc/book/en/images/archi_globale.png
doc/book/en/images/archi_globale_en.png
doc/book/en/images/breadcrumbs_header.png
doc/book/en/images/facet_date_range.png
doc/book/en/images/facet_has_image.png
doc/book/en/images/facet_overview.png
doc/book/en/images/facet_range.png
doc/book/en/images/lax-book_00-login_en.png
doc/book/en/images/lax-book_01-start_en.png
doc/book/en/images/lax-book_02-cookie-values_en.png
doc/book/en/images/lax-book_02-create-blog_en.png
doc/book/en/images/lax-book_03-list-one-blog_en.png
doc/book/en/images/lax-book_03-site-config-panel_en.png
doc/book/en/images/lax-book_03-state-submitted_en.png
doc/book/en/images/lax-book_03-transitions-view_en.png
doc/book/en/images/lax-book_04-detail-one-blog_en.png
doc/book/en/images/lax-book_05-list-two-blog_en.png
doc/book/en/images/lax-book_06-add-relation-entryof_en.png
doc/book/en/images/lax-book_06-main-template-logo_en.png
doc/book/en/images/lax-book_07-detail-one-blogentry_en.png
doc/book/en/images/lax-book_08-schema_en.png
doc/book/en/images/lax-book_09-new-view-blogentry_en.png
doc/book/en/images/lax-book_10-blog-with-two-entries_en.png
doc/book/en/images/main_template.png
doc/book/en/images/main_template.svg
doc/book/en/images/main_template_layout.png
doc/book/en/images/primaryview_template.png
doc/book/en/images/primaryview_template.svg
doc/book/en/images/request_session.png
doc/book/en/images/request_session.svg
doc/book/en/images/server-class-diagram.png
doc/book/en/images/tutos-base_blog-form_en.png
doc/book/en/images/tutos-base_blog-primary-after-post-creation_en.png
doc/book/en/images/tutos-base_blog-primary_en.png
doc/book/en/images/tutos-base_blogs-list_en.png
doc/book/en/images/tutos-base_form-generic-relations_en.png
doc/book/en/images/tutos-base_index_en.png
doc/book/en/images/tutos-base_login-form_en.png
doc/book/en/images/tutos-base_myblog-blogentry-taggable-commentable-primary_en.png
doc/book/en/images/tutos-base_myblog-community-custom-primary_en.png
doc/book/en/images/tutos-base_myblog-community-default-primary_en.png
doc/book/en/images/tutos-base_myblog-community-taggable-primary_en.png
doc/book/en/images/tutos-base_myblog-custom-footer_en.png
doc/book/en/images/tutos-base_myblog-schema_en.png
doc/book/en/images/tutos-base_myblog-siteinfo_en.png
doc/book/en/images/tutos-base_schema_en.png
doc/book/en/images/tutos-base_siteconfig_en.png
doc/book/en/images/tutos-base_user-menu_en.png
doc/book/en/images/tutos-photowebsite_background-image.png
doc/book/en/images/tutos-photowebsite_boxes.png
doc/book/en/images/tutos-photowebsite_breadcrumbs.png
doc/book/en/images/tutos-photowebsite_facets.png
doc/book/en/images/tutos-photowebsite_grey-box.png
doc/book/en/images/tutos-photowebsite_index-after.png
doc/book/en/images/tutos-photowebsite_index-before.png
doc/book/en/images/tutos-photowebsite_login-box.png
doc/book/en/images/tutos-photowebsite_prevnext.png
doc/book/en/images/tutos-photowebsite_ui1.png
doc/book/en/images/tutos-photowebsite_ui2.png
doc/book/en/images/tutos-photowebsite_ui3.png
doc/book/en/images/undo_history-view_w600.png
doc/book/en/images/undo_mesage_w600.png
doc/book/en/images/undo_startup-link_w600.png
doc/book/en/images/views-table-filter-shadow.png
doc/book/en/images/views-table-filter.png
doc/book/en/images/views-table-shadow.png
doc/book/en/images/views-table.png
doc/book/en/index.rst
doc/book/en/intro/concepts.rst
doc/book/en/intro/history.rst
doc/book/en/intro/index.rst
doc/book/en/makefile
doc/book/en/tutorials/advanced/index.rst
doc/book/en/tutorials/advanced/part01_create-cube.rst
doc/book/en/tutorials/advanced/part02_security.rst
doc/book/en/tutorials/advanced/part03_bfss.rst
doc/book/en/tutorials/advanced/part04_ui-base.rst
doc/book/en/tutorials/advanced/part05_ui-advanced.rst
doc/book/en/tutorials/base/blog-in-five-minutes.rst
doc/book/en/tutorials/base/conclusion.rst
doc/book/en/tutorials/base/customizing-the-application.rst
doc/book/en/tutorials/base/discovering-the-ui.rst
doc/book/en/tutorials/base/index.rst
doc/book/en/tutorials/index.rst
doc/book/en/tutorials/textreports/index.rst
doc/book/en/tutorials/tools/windmill.rst
doc/book/index.rst
doc/book/intro/concepts.rst
doc/book/intro/history.rst
doc/book/intro/index.rst
doc/book/mode_plan.py
doc/changes/3.14.rst
doc/changes/3.15.rst
doc/changes/3.16.rst
doc/changes/3.17.rst
doc/changes/3.18.rst
doc/changes/3.19.rst
doc/changes/3.20.rst
doc/changes/index.rst
doc/conf.py
doc/dev/documenting.rst
doc/images/03-transitions-view_en.png
doc/images/archi_globale.png
doc/images/archi_globale_en.png
doc/images/breadcrumbs_header.png
doc/images/facet_date_range.png
doc/images/facet_has_image.png
doc/images/facet_overview.png
doc/images/facet_range.png
doc/images/lax-book_00-login_en.png
doc/images/lax-book_01-start_en.png
doc/images/lax-book_02-cookie-values_en.png
doc/images/lax-book_02-create-blog_en.png
doc/images/lax-book_03-list-one-blog_en.png
doc/images/lax-book_03-site-config-panel_en.png
doc/images/lax-book_03-state-submitted_en.png
doc/images/lax-book_03-transitions-view_en.png
doc/images/lax-book_04-detail-one-blog_en.png
doc/images/lax-book_05-list-two-blog_en.png
doc/images/lax-book_06-add-relation-entryof_en.png
doc/images/lax-book_06-main-template-logo_en.png
doc/images/lax-book_07-detail-one-blogentry_en.png
doc/images/lax-book_08-schema_en.png
doc/images/lax-book_09-new-view-blogentry_en.png
doc/images/lax-book_10-blog-with-two-entries_en.png
doc/images/main_template.png
doc/images/main_template.svg
doc/images/main_template_layout.png
doc/images/primaryview_template.png
doc/images/primaryview_template.svg
doc/images/request_session.png
doc/images/request_session.svg
doc/images/server-class-diagram.png
doc/images/tutos-base_blog-form_en.png
doc/images/tutos-base_blog-primary-after-post-creation_en.png
doc/images/tutos-base_blog-primary_en.png
doc/images/tutos-base_blogs-list_en.png
doc/images/tutos-base_form-generic-relations_en.png
doc/images/tutos-base_index_en.png
doc/images/tutos-base_login-form_en.png
doc/images/tutos-base_myblog-blogentry-taggable-commentable-primary_en.png
doc/images/tutos-base_myblog-community-custom-primary_en.png
doc/images/tutos-base_myblog-community-default-primary_en.png
doc/images/tutos-base_myblog-community-taggable-primary_en.png
doc/images/tutos-base_myblog-custom-footer_en.png
doc/images/tutos-base_myblog-schema_en.png
doc/images/tutos-base_myblog-siteinfo_en.png
doc/images/tutos-base_schema_en.png
doc/images/tutos-base_siteconfig_en.png
doc/images/tutos-base_user-menu_en.png
doc/images/tutos-photowebsite_background-image.png
doc/images/tutos-photowebsite_boxes.png
doc/images/tutos-photowebsite_breadcrumbs.png
doc/images/tutos-photowebsite_facets.png
doc/images/tutos-photowebsite_grey-box.png
doc/images/tutos-photowebsite_index-after.png
doc/images/tutos-photowebsite_index-before.png
doc/images/tutos-photowebsite_login-box.png
doc/images/tutos-photowebsite_prevnext.png
doc/images/tutos-photowebsite_ui1.png
doc/images/tutos-photowebsite_ui2.png
doc/images/tutos-photowebsite_ui3.png
doc/images/undo_history-view_w600.png
doc/images/undo_mesage_w600.png
doc/images/undo_startup-link_w600.png
doc/images/views-table-filter-shadow.png
doc/images/views-table-filter.png
doc/images/views-table-shadow.png
doc/images/views-table.png
doc/index.rst
doc/tools/mode_plan.py
doc/tools/pyjsrest.py
doc/tutorials/advanced/index.rst
doc/tutorials/advanced/part01_create-cube.rst
doc/tutorials/advanced/part02_security.rst
doc/tutorials/advanced/part03_bfss.rst
doc/tutorials/advanced/part04_ui-base.rst
doc/tutorials/advanced/part05_ui-advanced.rst
doc/tutorials/base/blog-in-five-minutes.rst
doc/tutorials/base/conclusion.rst
doc/tutorials/base/customizing-the-application.rst
doc/tutorials/base/discovering-the-ui.rst
doc/tutorials/base/index.rst
doc/tutorials/index.rst
doc/tutorials/textreports/index.rst
doc/tutorials/tools/windmill.rst
--- a/.hgignore	Mon Jul 06 17:39:35 2015 +0200
+++ b/.hgignore	Thu Jan 08 22:11:06 2015 +0100
@@ -18,4 +18,7 @@
 ^doc/html/
 ^doc/doctrees/
 ^doc/book/en/devweb/js_api/
+^doc/_build
+^doc/js_api/
+data/pgdb/
 data.*/pgdb.*
--- a/doc/3.14.rst	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-Whats new in CubicWeb 3.14
-==========================
-
-First notice CW 3.14 depends on yams 0.34 (which is incompatible with prior
-cubicweb releases regarding instance re-creation).
-
-API changes
------------
-
-* `Entity.fetch_rql` `restriction` argument has been deprecated and should be
-  replaced with a call to the new `Entity.fetch_rqlst` method, get the returned
-  value (a rql `Select` node) and use the RQL syntax tree API to include the
-  above-mentionned restrictions.
-
-  Backward compat is kept with proper warning.
-
-* `Entity.fetch_order` and `Entity.fetch_unrelated_order` class methods have been
-  replaced by `Entity.cw_fetch_order` and `Entity.cw_fetch_unrelated_order` with
-  a different prototype:
-
-  - instead of taking (attr, var) as two string argument, they now take (select,
-    attr, var) where select is the rql syntax tree beinx constructed and var the
-    variable *node*.
-
-  - instead of returning some string to be inserted in the ORDERBY clause, it has
-    to modify the syntax tree
-
-  Backward compat is kept with proper warning, BESIDE cases below:
-
-  - custom order method return **something else the a variable name with or
-    without the sorting order** (e.g. cases where you sort on the value of a
-    registered procedure as it was done in the tracker for instance). In such
-    case, an error is logged telling that this sorting is ignored until API
-    upgrade.
-
-  - client code use direct access to one of those methods on an entity (no code
-    known to do that).
-
-* `Entity._rest_attr_info` class method has been renamed to
-  `Entity.cw_rest_attr_info`
-
-  No backward compat yet since this is a protected method an no code is known to
-  use it outside cubicweb itself.
-
-* `AnyEntity.linked_to` has been removed as part of a refactoring of this
-  functionality (link a entity to another one at creation step). It was replaced
-  by a `EntityFieldsForm.linked_to` property.
-
-  In the same refactoring, `cubicweb.web.formfield.relvoc_linkedto`,
-  `cubicweb.web.formfield.relvoc_init` and
-  `cubicweb.web.formfield.relvoc_unrelated` were removed and replaced by
-  RelationField methods with the same names, that take a form as a parameter.
-
-  **No backward compatibility yet**. It's still time to cry for it.
-  Cubes known to be affected: tracker, vcsfile, vcreview.
-
-* `CWPermission` entity type and its associated require_permission relation type
-  (abstract) and require_group relation definitions have been moved to a new
-  `localperms` cube. With this have gone some functions from the
-  `cubicweb.schemas` package as well as some views. This makes cubicweb itself
-  smaller while you get all the local permissions stuff into a single,
-  documented, place.
-
-  Backward compat is kept for existing instances, **though you should have
-  installed the localperms cubes**. A proper error should be displayed when
-  trying to migrate to 3.14 an instance the use `CWPermission` without the new
-  cube installed. For new instances / test, you should add a dependancy on the
-  new cube in cubes using this feature, along with a dependancy on cubicweb >=
-  3.14.
-
-* jQuery has been updated to 1.6.4 and jquery-tablesorter to 2.0.5. No backward
-  compat issue known.
-
-* Table views refactoring : new `RsetTableView` and `EntityTableView`, as well as
-  rewritten an enhanced version of `PyValTableView` on the same bases, with logic
-  moved to some column renderers and a layout. Those should be well documented
-  and deprecates former `TableView`, `EntityAttributesTableView` and `CellView`,
-  which are however kept for backward compat, with some warnings that may not be
-  very clear unfortunatly (you may see your own table view subclass name here,
-  which doesn't make the problem that clear). Notice that `_cw.view('table',
-  rset, *kwargs)` will be routed to the new `RsetTableView` or to the old
-  `TableView` depending on given extra arguments. See #1986413.
-
-* `display_name` don't call .lower() anymore. This may leads to changes in your
-  user interface. Different msgid for upper/lower cases version of entity type
-  names, as this is the only proper way to handle this with some languages.
-
-* `IEditControlAdapter` has been deprecated in favor of `EditController`
-  overloading, which was made easier by adding dedicated selectors called
-  `match_edited_type` and `match_form_id`.
-
-* Pre 3.6 API backward compat has been dropped, though *data* migration
-  compatibility has been kept. You may have to fix errors due to old API usage
-  for your instance before to be able to run migration, but then you should be
-  able to upgrade even a pre 3.6 database.
-
-* Deprecated `cubicweb.web.views.iprogress` in favor of new `iprogress` cube.
-
-* Deprecated `cubicweb.web.views.flot` in favor of new `jqplot` cube.
-
-
-Unintrusive API changes
------------------------
-
-* Refactored properties forms (eg user preferences and site wide properties) as
-  well as pagination components to ease overridding.
-
-* New `cubicweb.web.uihelper` module with high-level helpers for uicfg.
-
-* New `anonymized_request` decorator to temporary run stuff as an anonymous
-  user, whatever the currently logged in user.
-
-* New 'verbatimattr' attribute view.
-
-* New facet and form widget for Integer used to store binary mask.
-
-* New `js_href` function to generated proper javascript href.
-
-* `match_kwargs` and `match_form_params` selectors both accept a new
-  `once_is_enough` argument.
-
-* `printable_value` is now a method of request, and may be given dict of
-   formatters to use.
-
-* `[Rset]TableView` allows to set None in 'headers', meaning the label should be
-  fetched from the result set as done by default.
-
-* Field vocabulary computation on entity creation now takes `__linkto`
-  information into accounet.
-
-* Started a `cubicweb.pylintext` pylint plugin to help pylint analyzing cubes.
-
-
-RQL
----
-
-* Support for HAVING in 'SET' and 'DELETE' queries.
-
-* new `AT_TZ` function to get back a timestamp at a given time-zone.
-
-* new `WEEKDAY` date extraction function
-
-
-User interface changes
-----------------------
-
-* Datafeed source now present an history of the latest import's log, including
-  global status and debug/info/warning/error messages issued during
-  imports. Import logs older than a configurable amount of time are automatically
-  deleted.
-
-* Breadcrumbs component is properly kept when creating an entity with '__linkto'.
-
-* users and groups management now really lead to that (i.e. includes *groups*
-  management).
-
-* New 'jsonp' controller with 'jsonexport' and 'ejsonexport' views.
-
-
-Configuration
-------------
-
-* Added option 'resources-concat' to make javascript/css files concatenation
-  optional.
--- a/doc/3.15.rst	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-What's new in CubicWeb 3.15?
-============================
-
-New functionnalities
---------------------
-
-* Add Zmq server, based on the cutting edge ZMQ (http://www.zeromq.org/) socket
-  library.  This allows to access distant instance, in a similar way as Pyro.
-
-* Publish/subscribe mechanism using ZMQ for communication among cubicweb
-  instances.  The new zmq-address-sub and zmq-address-pub configuration variables
-  define where this communication occurs.  As of this release this mechanism is
-  used for entity cache invalidation.
-
-* Improved WSGI support. While there is still some caveats, most of the code
-  which was twisted only is now generic and allows related functionalities to work
-  with a WSGI front-end.
-
-* Full undo/transaction support : undo of modification has eventually been
-  implemented, and the configuration simplified (basically you activate it or not
-  on an instance basis).
-
-* Controlling HTTP status code used is not much more easier :
-
-  - `WebRequest` now has a `status_out` attribut to control the response status ;
-
-  - most web-side exceptions take an optional ``status`` argument.
-
-API changes
------------
-
-* The base registry implementation has been moved to a new
-  `logilab.common.registry` module (see #1916014). This includes code from :
-
-  * `cubicweb.vreg` (the whole things that was in there)
-  * `cw.appobject` (base selectors and all).
-
-  In the process, some renaming was done:
-
-  * the top level registry is now `RegistryStore` (was `VRegistry`), but that
-    should not impact cubicweb client code ;
-
-  * former selectors functions are now known as "predicate", though you still use
-    predicates to build an object'selector ;
-
-  * for consistency, the `objectify_selector` decoraror has hence be renamed to
-    `objectify_predicate` ;
-
-  * on the CubicWeb side, the `selectors` module has been renamed to
-    `predicates`.
-
-  Debugging refactoring dropped the more need for the `lltrace` decorator.  There
-  should be full backward compat with proper deprecation warnings.  Notice the
-  `yes` predicate and `objectify_predicate` decorator, as well as the
-  `traced_selection` function should now be imported from the
-  `logilab.common.registry` module.
-
-* All login forms are now submitted to <app_root>/login. Redirection to requested
-  page is now handled by the login controller (it was previously handle by the
-  session manager).
-
-* `Publisher.publish` has been renamed to `Publisher.handle_request`. This
-  method now contains generic version of logic previously handled by
-  Twisted. `Controller.publish` is **not** affected.
-
-Unintrusive API changes
------------------------
-
-* New 'ldapfeed' source type, designed to replace 'ldapuser' source with
-  data-feed (i.e. copy based) source ideas.
-
-* New 'zmqrql' source type, similar to 'pyrorql' but using ømq instead of Pyro.
-
-* A new registry called `services` has appeared, where you can register
-  server-side `cubicweb.server.Service` child classes. Their `call` method can be
-  invoked from a web-side AppObject instance using new `self._cw.call_service`
-  method or a server-side one using `self.session.call_service`. This is a new
-  way to call server-side methods, much cleaner than monkey patching the
-  Repository class, which becomes a deprecated way to perform similar tasks.
-
-* a new `ajax-func` registry now hosts all remote functions (i.e. functions
-  callable through the `asyncRemoteExec` JS api). A convenience `ajaxfunc`
-  decorator will let you expose your python function easily without all the
-  appobject standard boilerplate. Backward compatibility is preserved.
-
-* the 'json' controller is now deprecated in favor of the 'ajax' one.
-
-* `WebRequest.build_url` can now take a __secure__ argument. When True cubicweb
-  try to generate an https url.
-
-
-User interface changes
-----------------------
-
-A new 'undohistory' view expose the undoable transactions and give access to undo
-some of them.
--- a/doc/3.16.rst	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-What's new in CubicWeb 3.16?
-============================
-
-New functionalities
---------------------
-
-* Add a new dataimport store (`SQLGenObjectStore`). This store enables a fast
-  import of data (entity creation, link creation) in CubicWeb, by directly
-  flushing information in SQL.  This may only be used with PostgreSQL, as it
-  requires the 'COPY FROM' command.
-
-
-API changes
------------
-
-* Orm: `set_attributes` and `set_relations` are unified (and
-  deprecated) in favor of `cw_set` that works in all cases.
-
-* db-api/configuration: all the external repository connection information is
-  now in an URL (see `#2521848 <http://www.cubicweb.org/2521848>`_),
-  allowing to drop specific options of pyro nameserver host, group, etc and fix
-  broken `ZMQ <http://www.zeromq.org/>`_ source. Configuration related changes:
-
-  * Dropped 'pyro-ns-host', 'pyro-instance-id', 'pyro-ns-group' from the client side
-    configuration, in favor of 'repository-uri'. **NO MIGRATION IS DONE**,
-    supposing there is no web-only configuration in the wild.
-
-  * Stop discovering the connection method through `repo_method` class attribute
-    of the configuration, varying according to the configuration class. This is
-    a first step on the way to a simpler configuration handling.
-
-  DB-API related changes:
-
-  * Stop indicating the connection method using `ConnectionProperties`.
-
-  * Drop `_cnxtype` attribute from `Connection` and `cnxtype` from
-    `Session`. The former is replaced by a `is_repo_in_memory` property
-    and the later is totaly useless.
-
-  * Turn `repo_connect` into `_repo_connect` to mark it as a private function.
-
-  * Deprecate `in_memory_cnx` which becomes useless, use `_repo_connect` instead
-    if necessary.
-
-* the "tcp://" uri scheme used for `ZMQ <http://www.zeromq.org/>`_
-  communications (in a way reminiscent of Pyro) is now named
-  "zmqpickle-tcp://", so as to make room for future zmq-based lightweight
-  communications (without python objects pickling).
-
-* Request.base_url gets a `secure=True` optional parameter that yields
-  an https url if possible, allowing hook-generated content to send
-  secure urls (e.g. when sending mail notifications)
-
-* Dataimport ucsvreader gets a new boolean `ignore_errors`
-  parameter.
-
-
-Unintrusive API changes
------------------------
-
-* Drop of `cubicweb.web.uicfg.AutoformSectionRelationTags.bw_tag_map`,
-  deprecated since 3.6.
-
-
-User interface changes
-----------------------
-
-* The RQL search bar has now some auto-completion support. It means
-  relation types or entity types can be suggested while typing. It is
-  an awesome improvement over the current behaviour !
-
-* The `action box` associated with `table` views (from `tableview.py`)
-  has been transformed into a nice-looking series of small tabs; it
-  means that the possible actions are immediately visible and need not
-  be discovered by clicking on an almost invisible icon on the upper
-  right.
-
-* The `uicfg` module has moved to web/views/ and ui configuration
-  objects are now selectable. This will reduce the amount of
-  subclassing and whole methods replacement usually needed to
-  customize the ui behaviour in many cases.
-
-* Remove changelog view, as neither cubicweb nor known
-  cubes/applications were properly feeding related files.
-
-
-Other changes
--------------
-
-* 'pyrorql' sources will be automatically updated to use an URL to locate the source
-  rather than configuration option. 'zmqrql' sources were broken before this change,
-  so no upgrade is needed...
-
-* Debugging filters for Hooks and Operations have been added.
-
-* Some cubicweb-ctl commands used to show the output of `msgcat` and
-  `msgfmt`; they don't anymore.
--- a/doc/3.17.rst	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-What's new in CubicWeb 3.17?
-============================
-
-New functionalities
---------------------
-
-* add a command to compare db schema and file system schema
-  (see `#464991 <http://www.cubicweb.org/464991>`_)
-
-* Add CubicWebRequestBase.content with the content of the HTTP request (see #2742453)
-  (see `#2742453 <http://www.cubicweb.org/2742453>`_)
-
-* Add directive bookmark to ReST rendering
-  (see `#2545595 <http://www.cubicweb.org/ticket/2545595>`_)
-
-* Allow user defined final type
-  (see `#124342 <https://www.logilab.org/ticket/124342>`_)
-
-
-API changes
------------
-
-* drop typed_eid() in favour of int() (see `#2742462 <http://www.cubicweb.org/2742462>`_)
-
-* The SIOC views and adapters have been removed from CubicWeb and moved to the
-  `sioc` cube.
-
-* The web page embedding views and adapters have been removed from CubicWeb and
-  moved to the `embed` cube.
-
-* The email sending views and controllers have been removed from CubicWeb and
-  moved to the `massmailing` cube.
-
-* ``RenderAndSendNotificationView`` is deprecated in favor of
-  ``ActualNotificationOp`` the new operation use the more efficient *data*
-  idiom.
-
-* Looping task can now have a interval <= ``0``. Negative interval disable the
-  looping task entirely.
-
-* We now serve html instead of xhtml.
-  (see `#2065651 <http://www.cubicweb.org/ticket/2065651>`_)
-
-
-Deprecation
----------------------
-
-* ``ldapuser`` have been deprecated. It'll be fully dropped in the next
-  version. If you are still using ldapuser switch to ``ldapfeed`` **NOW**!
-
-* ``hijack_user`` have been deprecated. It will be dropped soon.
-
-Deprecated Code Drops
-----------------------
-
-* The progress views and adapters have been removed from CubicWeb. These
-  classes were deprecated since 3.14.0. They are still available in the
-  `iprogress` cube.
-
-* API deprecated since 3.7 have been dropped.
--- a/doc/3.18.rst	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-What's new in CubicWeb 3.18?
-============================
-
-The migration script does not handle sqlite nor mysql instances.
-
-
-New functionalities
---------------------
-
-* add a security debugging tool
-  (see `#2920304 <http://www.cubicweb.org/2920304>`_)
-
-* introduce an `add` permission on attributes, to be interpreted at
-  entity creation time only and allow the implementation of complex
-  `update` rules that don't block entity creation (before that the
-  `update` attribute permission was interpreted at entity creation and
-  update time)
-
-* the primary view display controller (uicfg) now has a
-  `set_fields_order` method similar to the one available for forms
-
-* new method `ResultSet.one(col=0)` to retrive a single entity and enforce the
-  result has only one row (see `#3352314 https://www.cubicweb.org/ticket/3352314`_)
-
-* new method `RequestSessionBase.find` to look for entities
-  (see `#3361290 https://www.cubicweb.org/ticket/3361290`_)
-
-* the embedded jQuery copy has been updated to version 1.10.2, and jQuery UI to
-  version 1.10.3.
-
-* initial support for wsgi for the debug mode, available through the new
-  ``wsgi`` cubicweb-ctl command, which can use either python's builtin
-  wsgi server or the werkzeug module if present.
-
-* a ``rql-table`` directive is now available in ReST fields
-
-* cubicweb-ctl upgrade can now generate the static data resource directory
-  directly, without a manual call to gen-static-datadir.
-
-API changes
------------
-
-* not really an API change, but the entity permission checks are now
-  systematically deferred to an operation, instead of a) trying in a
-  hook and b) if it failed, retrying later in an operation
-
-* The default value storage for attributes is no longer String, but
-  Bytes.  This opens the road to storing arbitrary python objects, e.g.
-  numpy arrays, and fixes a bug where default values whose truth value
-  was False were not properly migrated.
-
-* `symmetric` relations are no more handled by an rql rewrite but are
-  now handled with hooks (from the `activeintegrity` category); this
-  may have some consequences for applications that do low-level database
-  manipulations or at times disable (some) hooks.
-
-* `unique together` constraints (multi-columns unicity constraints)
-  get a `name` attribute that maps the CubicWeb contraint entities to
-  corresponding backend index.
-
-* BreadCrumbEntityVComponent's open_breadcrumbs method now includes
-  the first breadcrumbs separator
-
-* entities can be compared for equality and hashed
-
-* the ``on_fire_transition`` predicate accepts a sequence of possible
-  transition names
-
-* the GROUP_CONCAT rql aggregate function no longer repeats duplicate
-  values, on the sqlite and postgresql backends
-
-Deprecation
----------------------
-
-* ``pyrorql`` sources have been deprecated. Multisource will be fully dropped
-  in the next version. If you are still using pyrorql, switch to ``datafeed``
-  **NOW**!
-
-* the old multi-source system
-
-* `find_one_entity` and `find_entities` in favor of `find`
-  (see `#3361290 https://www.cubicweb.org/ticket/3361290`_)
-
-* the `TmpFileViewMixin` and `TmpPngView` classes (see `#3400448
-  https://www.cubicweb.org/ticket/3400448`_)
-
-Deprecated Code Drops
-----------------------
-
-* ``ldapuser`` have been dropped; use ``ldapfeed`` now
-  (see `#2936496 <http://www.cubicweb.org/2936496>`_)
-
-* action ``GotRhythm`` was removed, make sure you do not
-  import it in your cubes (even to unregister it)
-  (see `#3093362 <http://www.cubicweb.org/3093362>`_)
-
-* all 3.8 backward compat is gone
-
-* all 3.9 backward compat (including the javascript side) is gone
-
-* the ``twisted`` (web-only) instance type has been removed
--- a/doc/3.19.rst	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-What's new in CubicWeb 3.19?
-============================
-
-New functionalities
---------------------
-
-* implement Cross Origin Resource Sharing (CORS)
-  (see `#2491768 <http://www.cubicweb.org/2491768>`_)
-
-* system_source.create_eid can get a range of IDs, to reduce overhead of batch
-  entity creation
-
-Behaviour Changes
------------------
-
-* The anonymous property of Session and Connection are now computed from the
-  related user login. If it matches the ``anonymous-user`` in the config the
-  connection is anonymous. Beware that the ``anonymous-user`` config is web
-  specific. Therefore, no session may be anonymous in a repository only setup.
-
-
-New Repository Access API
--------------------------
-
-Connection replaces Session
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A new explicit Connection object replaces Session as the main repository entry
-point. Connection holds all the necessary methods to be used server-side
-(``execute``, ``commit``, ``rollback``, ``call_service``, ``entity_from_eid``,
-etc...). One obtains a new Connection object using ``session.new_cnx()``.
-Connection objects need to have an explicit begin and end. Use them as a context
-manager to never miss an end::
-
-    with session.new_cnx() as cnx:
-        cnx.execute('INSERT Elephant E, E name "Babar"')
-        cnx.commit()
-        cnx.execute('INSERT Elephant E, E name "Celeste"')
-        cnx.commit()
-    # Once you get out of the "with" clause, the connection is closed.
-
-Using the same Connection object in multiple threads will give you access to the
-same Transaction. However, Connection objects are not thread safe (hence at your
-own risks).
-
-``repository.internal_session`` is deprecated in favor of
-``repository.internal_cnx``. Note that internal connections are now `safe` by default,
-i.e. the integrity hooks are enabled.
-
-Backward compatibility is preserved on Session.
-
-
-dbapi vs repoapi
-~~~~~~~~~~~~~~~~
-
-A new API has been introduced to replace the dbapi. It is called `repoapi`.
-
-There are three relevant functions for now:
-
-* ``repoapi.get_repository`` returns a Repository object either from an
-  URI when used as ``repoapi.get_repository(uri)`` or from a config
-  when used as ``repoapi.get_repository(config=config)``.
-
-* ``repoapi.connect(repo, login, **credentials)`` returns a ClientConnection
-  associated with the user identified by the credentials. The
-  ClientConnection is associated with its own Session that is closed
-  when the ClientConnection is closed. A ClientConnection is a
-  Connection-like object to be used client side.
-
-* ``repoapi.anonymous_cnx(repo)`` returns a ClientConnection associated
-  with the anonymous user if described in the config.
-
-
-repoapi.ClientConnection replace dbapi.Connection and company
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-On the client/web side, the Request is now using a ``repoapi.ClientConnection``
-instead of a ``dbapi.connection``. The ``ClientConnection`` has multiple backward
-compatible methods to make it look like a ``dbapi.Cursor`` and ``dbapi.Connection``.
-
-Session used on the Web side are now the same than the one used Server side.
-Some backward compatibility methods have been installed on the server side Session
-to ease the transition.
-
-The authentication stack has been altered to use the ``repoapi`` instead of
-the ``dbapi``. Cubes adding new element to this stack are likely to break.
-
-Session data can be accessed using the cnx.data dictionary, while
-transaction data is available through cnx.transaction_data.  These
-replace the [gs]et_shared_data methods with optional txid kwarg.
-
-New API in tests
-~~~~~~~~~~~~~~~~
-
-All current methods and attributes used to access the repo on ``CubicWebTC`` are
-deprecated. You may now use a ``RepoAccess`` object. A ``RepoAccess`` object is
-linked to a new ``Session`` for a specified user. It is able to create
-``Connection``, ``ClientConnection`` and web side requests linked to this
-session::
-
-    access = self.new_access('babar') # create a new RepoAccess for user babar
-    with access.repo_cnx() as cnx:
-        # some work with server side cnx
-        cnx.execute(...)
-        cnx.commit()
-        cnx.execute(...)
-        cnx.commit()
-
-    with access.client_cnx() as cnx:
-        # some work with client side cnx
-        cnx.execute(...)
-        cnx.commit()
-
-    with access.web_request(elephant='babar') as req:
-        # some work with client side cnx
-        elephant_name = req.form['elephant']
-        req.execute(...)
-        req.cnx.commit()
-
-By default ``testcase.admin_access`` contains a ``RepoAccess`` object for the
-default admin session.
-
-
-API changes
------------
-
-* ``RepositorySessionManager.postlogin`` is now called with two arguments,
-  request and session. And this now happens before the session is linked to the
-  request.
-
-* ``SessionManager`` and ``AuthenticationManager`` now take a repo object at
-  initialization time instead of a vreg.
-
-* The ``async`` argument of ``_cw.call_service`` has been dropped. All calls are
-  now  synchronous. The zmq notification bus looks like a good replacement for
-  most async use cases.
-
-* ``repo.stats()`` is now deprecated. The same information is available through
-  a service (``_cw.call_service('repo_stats')``).
-
-* ``repo.gc_stats()`` is now deprecated. The same information is available through
-  a service (``_cw.call_service('repo_gc_stats')``).
-
-* ``repo.register_user()`` is now deprecated.  The functionality is now
-  available through a service (``_cw.call_service('register_user')``).
-
-* ``request.set_session`` no longer takes an optional ``user`` argument.
-
-* CubicwebTC does not have repo and cnx as class attributes anymore. They are
-  standard instance attributes. ``set_cnx`` and ``_init_repo`` class methods
-  become instance methods.
-
-* ``set_cnxset`` and ``free_cnxset`` are deprecated. cnxset are now
-  automatically managed.
-
-* The implementation of cascading deletion when deleting `composite`
-  entities has changed. There comes a semantic change: merely deleting
-  a composite relation does not entail any more the deletion of the
-  component side of the relation.
-
-* ``_cw.user_callback`` and ``_cw.user_rql_callback`` are deprecated.  Users
-  are encouraged to write an actual controller (e.g. using ``ajaxfunc``)
-  instead of storing a closure in the session data.
-
-* A new ``entity.cw_linkable_rql`` method provides the rql to fetch all entities
-  that are already or may be related to the current entity using the given
-  relation.
-
-
-Deprecated Code Drops
-----------------------
-
-* session.hijack_user mechanism has been dropped.
-
-* EtypeRestrictionComponent has been removed, its functionality has been
-  replaced by facets a while ago.
-
-* the old multi-source support has been removed.  Only copy-based sources
-  remain, such as datafeed or ldapfeed.
-
--- a/doc/3.20.rst	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-What's new in CubicWeb 3.20
-===========================
-
-New features
-------------
-
-* virtual relations: a new ComputedRelation class can be used in
-  schema.py; its `rule` attribute is an RQL snippet that defines the new
-  relation.
-
-* computed attributes: an attribute can now be defined with a `formula`
-  argument (also an RQL snippet); it will be read-only, and updated
-  automatically.
-
-  Both of these features are described in `CWEP-002`_, and the updated
-  "Data model" chapter of the CubicWeb book.
-
-* cubicweb-ctl plugins can use the ``cubicweb.utils.admincnx`` function
-  to get a Connection object from an instance name.
-
-* new 'tornado' wsgi backend
-
-* session cookies have the HttpOnly flag, so they're no longer exposed to
-  javascript
-
-* rich text fields can be formatted as markdown
-
-* the edit controller detects concurrent editions, and raises a ValidationError
-  if an entity was modified between form generation and submission
-
-* cubicweb can use a postgresql "schema" (namespace) for its tables
-
-* "cubicweb-ctl configure" can be used to set values of the admin user
-  credentials in the sources configuration file
-
-* in debug mode, setting the _cwtracehtml parameter on a request allows tracing
-  where each bit of output is produced
-
-.. _CWEP-002: http://hg.logilab.org/review/cwep/file/tip/CWEP-002.rst
-
-
-API Changes
------------
-
-* ``ucsvreader()`` and ``ucsvreader_pb()`` from the ``dataimport`` module have
-  2 new keyword arguments ``delimiter`` and ``quotechar`` to replace the
-  ``separator`` and ``quote`` arguments respectively. This makes the API match
-  that of Python's ``csv.reader()``.  The old arguments are still supported
-  though deprecated.
-
-* the migration environment's ``remove_cube`` function is now called ``drop_cube``.
-
-* cubicweb.old.css is now cubicweb.css.  The previous "new"
-  cubicweb.css, along with its cubicweb.reset.css companion, have been
-  removed.
-
-* the jquery-treeview plugin was updated to its latest version
-
-
-Deprecated Code Drops
-----------------------
-
-* most of 3.10 and 3.11 backward compat is gone; this includes:
-  - CtxComponent.box_action() and CtxComponent.build_link()
-  - cubicweb.devtools.htmlparser.XMLDemotingValidator
-  - various methods and properties on Entities, replaced by cw_edited and cw_attr_cache
-  - 'commit_event' method on hooks, replaced by 'postcommit_event'
-  - server.hook.set_operation(), replaced by Operation.get_instance(...).add_data()
-  - View.div_id(), View.div_class() and View.create_url()
-  - `*VComponent` classes
-  - in forms, Field.value() and Field.help() must take the form and the field itself as arguments
-  - form.render() must get `w` as a named argument, and renderer.render() must take `w` as first argument
-  - in breadcrumbs, the optional `recurs` argument must be a set, not False
-  - cubicweb.web.views.idownloadable.{download_box,IDownloadableLineView}
-  - primary views no longer have `render_entity_summary` and `summary` methods
-  - WFHistoryVComponent's `cell_call` method is replaced by `render_body`
-  - cubicweb.dataimport.ObjectStore.add(), replaced by create_entity
-  - ManageView.{folders,display_folders}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/Makefile	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,88 @@
+SRC=.
+
+# You can set these sphinx variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+#BUILDDIR      = build
+BUILDDIR      = _build
+CWDIR         = ..
+JSDIR         = ${CWDIR}/web/data
+JSTORST       = tools/pyjsrest.py
+BUILDJS       = js_api
+
+# Internal variables for sphinx
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d ${BUILDDIR}/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  all       to make standalone HTML files, developer manual and API doc"
+	@echo "  html      to make standalone HTML files"
+	@echo "---  "
+	@echo "  pickle    to make pickle files (usable by e.g. sphinx-web)"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview over all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+
+clean:
+	rm -f *.html
+	-rm -rf ${BUILDDIR}/html ${BUILDDIR}/doctrees
+	-rm -rf ${BUILDJS}
+
+all: html
+
+# run sphinx ###
+html: js
+	mkdir -p ${BUILDDIR}/html ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) ${BUILDDIR}/html
+	@echo
+	@echo "Build finished. The HTML pages are in ${BUILDDIR}/html."
+
+js:
+	mkdir -p ${BUILDJS}
+	$(JSTORST) -p ${JSDIR} -o ${BUILDJS}
+
+pickle:
+	mkdir -p ${BUILDDIR}/pickle ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) ${BUILDDIR}/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files or run"
+	@echo "  sphinx-web ${BUILDDIR}/pickle"
+	@echo "to start the sphinx-web server."
+
+web: pickle
+
+htmlhelp:
+	mkdir -p ${BUILDDIR}/htmlhelp ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) ${BUILDDIR}/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in ${BUILDDIR}/htmlhelp."
+
+latex:
+	mkdir -p ${BUILDDIR}/latex ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) ${BUILDDIR}/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in ${BUILDDIR}/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	mkdir -p ${BUILDDIR}/changes ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) ${BUILDDIR}/changes
+	@echo
+	@echo "The overview file is in ${BUILDDIR}/changes."
+
+linkcheck:
+	mkdir -p ${BUILDDIR}/linkcheck ${BUILDDIR}/doctrees
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) ${BUILDDIR}/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in ${BUILDDIR}/linkcheck/output.txt."
Binary file doc/_static/cubicweb.png has changed
Binary file doc/_static/logilab.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_static/sphinx-default.css	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,861 @@
+/**
+ * Sphinx Doc Design
+ */
+
+html, body {
+    background: white;
+}
+
+body {
+    font-family: Verdana, sans-serif;
+    font-size: 100%;
+    background-color: white;
+    color: black;
+    margin: 0;
+    padding: 0;
+}
+
+/* :::: LAYOUT :::: */
+
+div.logilablogo {
+    padding: 10px 10px 10px 10px;
+    height:75;
+}
+
+
+div.document {
+    background-color: white;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: white;
+    padding: 0 20px 30px 20px;
+    border-left:solid;
+    border-left-color:#e2e2e2;
+    border-left-width:thin;
+}
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.clearer {
+    clear: both;
+}
+
+div.footer {
+    color: #ff4500;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #ff4500;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #ff7700;
+    color: white;
+    width: 100%;
+    height: 30px;
+    line-height: 30px;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+div.related a {
+    color: white;
+    font-weight:bold;
+}
+
+/* ::: TOC :::: */
+
+div.sphinxsidebar {
+    border-style:solid;
+    border-color: white;
+/*    background-color:#e2e2e2;*/
+    padding-bottom:5px;
+}
+
+div.sphinxsidebar h3 {
+    font-family: Verdana, sans-serif;
+    color: black;
+    font-size: 1.2em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+    font-weight:bold;
+    font-style:italic;
+}
+
+div.sphinxsidebar h4 {
+    font-family: Verdana, sans-serif;
+    color: black;
+    font-size: 1.1em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+    font-weight:bold;
+    font-style:italic;
+}
+
+div.sphinxsidebar p {
+    color: black;
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    list-style: none;
+    color: black;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar a {
+    color: black;
+    text-decoration: none;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #e2e2e2;
+    font-family: sans-serif;
+    font-size: 1em;
+    padding-bottom: 5px;
+}
+
+/* :::: MODULE CLOUD :::: */
+div.modulecloud {
+    margin: -5px 10px 5px 10px;
+    padding: 10px;
+    line-height: 160%;
+    border: 1px solid #cbe7e5;
+    background-color: #f2fbfd;
+}
+
+div.modulecloud a {
+    padding: 0 5px 0 5px;
+}
+
+/* :::: SEARCH :::: */
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* :::: COMMON FORM STYLES :::: */
+
+div.actions {
+    padding: 5px 10px 5px 10px;
+    border-top: 1px solid #cbe7e5;
+    border-bottom: 1px solid #cbe7e5;
+    background-color: #e0f6f4;
+}
+
+form dl {
+    color: #333;
+}
+
+form dt {
+    clear: both;
+    float: left;
+    min-width: 110px;
+    margin-right: 10px;
+    padding-top: 2px;
+}
+
+input#homepage {
+    display: none;
+}
+
+div.error {
+    margin: 5px 20px 0 0;
+    padding: 5px;
+    border: 1px solid #d00;
+    font-weight: bold;
+}
+
+/* :::: INLINE COMMENTS :::: */
+
+div.inlinecomments {
+    position: absolute;
+    right: 20px;
+}
+
+div.inlinecomments a.bubble {
+    display: block;
+    float: right;
+    background-image: url(style/comment.png);
+    background-repeat: no-repeat;
+    width: 25px;
+    height: 25px;
+    text-align: center;
+    padding-top: 3px;
+    font-size: 0.9em;
+    line-height: 14px;
+    font-weight: bold;
+    color: black;
+}
+
+div.inlinecomments a.bubble span {
+    display: none;
+}
+
+div.inlinecomments a.emptybubble {
+    background-image: url(style/nocomment.png);
+}
+
+div.inlinecomments a.bubble:hover {
+    background-image: url(style/hovercomment.png);
+    text-decoration: none;
+    color: #3ca0a4;
+}
+
+div.inlinecomments div.comments {
+    float: right;
+    margin: 25px 5px 0 0;
+    max-width: 50em;
+    min-width: 30em;
+    border: 1px solid #2eabb0;
+    background-color: #f2fbfd;
+    z-index: 150;
+}
+
+div#comments {
+    border: 1px solid #2eabb0;
+    margin-top: 20px;
+}
+
+div#comments div.nocomments {
+    padding: 10px;
+    font-weight: bold;
+}
+
+div.inlinecomments div.comments h3,
+div#comments h3 {
+    margin: 0;
+    padding: 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 3px;
+}
+
+div.inlinecomments div.comments div.actions {
+    padding: 4px;
+    margin: 0;
+    border-top: none;
+}
+
+div#comments div.comment {
+    margin: 10px;
+    border: 1px solid #2eabb0;
+}
+
+div.inlinecomments div.comment h4,
+div.commentwindow div.comment h4,
+div#comments div.comment h4 {
+    margin: 10px 0 0 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 1px 4px 1px 4px;
+}
+
+div#comments div.comment h4 {
+    margin: 0;
+}
+
+div#comments div.comment h4 a {
+    color: #d5f4f4;
+}
+
+div.inlinecomments div.comment div.text,
+div.commentwindow div.comment div.text,
+div#comments div.comment div.text {
+    margin: -5px 0 -5px 0;
+    padding: 0 10px 0 10px;
+}
+
+div.inlinecomments div.comment div.meta,
+div.commentwindow div.comment div.meta,
+div#comments div.comment div.meta {
+    text-align: right;
+    padding: 2px 10px 2px 0;
+    font-size: 95%;
+    color: #538893;
+    border-top: 1px solid #cbe7e5;
+    background-color: #e0f6f4;
+}
+
+div.commentwindow {
+    position: absolute;
+    width: 500px;
+    border: 1px solid #cbe7e5;
+    background-color: #f2fbfd;
+    display: none;
+    z-index: 130;
+}
+
+div.commentwindow h3 {
+    margin: 0;
+    background-color: #2eabb0;
+    color: white;
+    border: none;
+    padding: 5px;
+    font-size: 1.5em;
+    cursor: pointer;
+}
+
+div.commentwindow div.actions {
+    margin: 10px -10px 0 -10px;
+    padding: 4px 10px 4px 10px;
+    color: #538893;
+}
+
+div.commentwindow div.actions input {
+    border: 1px solid #2eabb0;
+    background-color: white;
+    color: #135355;
+    cursor: pointer;
+}
+
+div.commentwindow div.form {
+    padding: 0 10px 0 10px;
+}
+
+div.commentwindow div.form input,
+div.commentwindow div.form textarea {
+    border: 1px solid #3c9ea2;
+    background-color: white;
+    color: black;
+}
+
+div.commentwindow div.error {
+    margin: 10px 5px 10px 5px;
+    background-color: #fbe5dc;
+    display: none;
+}
+
+div.commentwindow div.form textarea {
+    width: 99%;
+}
+
+div.commentwindow div.preview {
+    margin: 10px 0 10px 0;
+    background-color: #70d0d4;
+    padding: 0 1px 1px 25px;
+}
+
+div.commentwindow div.preview h4 {
+    margin: 0 0 -5px -20px;
+    padding: 4px 0 0 4px;
+    color: white;
+    font-size: 1.3em;
+}
+
+div.commentwindow div.preview div.comment {
+    background-color: #f2fbfd;
+}
+
+div.commentwindow div.preview div.comment h4 {
+    margin: 10px 0 0 0!important;
+    padding: 1px 4px 1px 4px!important;
+    font-size: 1.2em;
+}
+
+/* :::: SUGGEST CHANGES :::: */
+div#suggest-changes-box input, div#suggest-changes-box textarea {
+    border: 1px solid #ccc;
+    background-color: white;
+    color: black;
+}
+
+div#suggest-changes-box textarea {
+    width: 99%;
+    height: 400px;
+}
+
+
+/* :::: PREVIEW :::: */
+div.preview {
+    background-image: url(style/preview.png);
+    padding: 0 20px 20px 20px;
+    margin-bottom: 30px;
+}
+
+
+/* :::: INDEX PAGE :::: */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* :::: INDEX STYLES :::: */
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+form.pfform {
+    margin: 10px 0 20px 0;
+}
+
+/* :::: GLOBAL STYLES :::: */
+
+.docwarning {
+    background-color: #ffe4e4;
+    padding: 10px;
+    margin: 0 -20px 0 -20px;
+    border-bottom: 1px solid #f66;
+}
+
+p.subhead {
+    font-weight: bold;
+    margin-top: 20px;
+}
+
+a {
+    color: orangered;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Verdana', sans-serif;
+    background-color: white;
+    font-weight: bold;
+    color: black;
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 10pt; font-size: 150%; }
+div.body h2 { font-size: 120%; }
+div.body h3 { font-size: 100%; }
+div.body h4 { font-size: 80%; }
+div.body h5 { font-size: 600%; }
+div.body h6 { font-size: 40%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div.body td {
+    text-align: left;
+}
+
+ul.fakelist {
+    list-style: none;
+    margin: 10px 0 10px 20px;
+    padding: 0;
+}
+
+.field-list ul {
+    padding-left: 1em;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+/* "Footnotes" heading */
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+/* "Topics" */
+
+div.topic {
+    background-color: #eee;
+    border: 1px solid #ccc;
+    padding: 0 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* Admonitions */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+div.admonition p {
+    display: inline;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+table.docutils {
+    border: 0;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 0;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+dl {
+    margin-bottom: 15px;
+    clear: both;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+.refcount {
+    color: #060;
+}
+
+dt:target,
+.highlight {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+pre {
+    padding: 5px;
+    background-color: #efc;
+    color: #333;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+    overflow: auto;
+}
+
+td.linenos pre {
+    padding: 5px 0px;
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    margin-left: 0.5em;
+}
+
+table.highlighttable td {
+    padding: 0 0.5em 0 0.5em;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+.footnote:target  { background-color: #ffa }
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+form.comment {
+    margin: 0;
+    padding: 10px 30px 10px 30px;
+    background-color: #eee;
+}
+
+form.comment h3 {
+    background-color: #326591;
+    color: white;
+    margin: -10px -30px 10px -30px;
+    padding: 5px;
+    font-size: 1.4em;
+}
+
+form.comment input,
+form.comment textarea {
+    border: 1px solid #ccc;
+    padding: 2px;
+    font-family: sans-serif;
+    font-size: 100%;
+}
+
+form.comment input[type="text"] {
+    width: 240px;
+}
+
+form.comment textarea {
+    width: 100%;
+    height: 200px;
+    margin-bottom: 10px;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+/* :::: PRINT :::: */
+@media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0;
+        width : 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    div#comments div.new-comment-box,
+    #top-link {
+        display: none;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_templates/layout.html	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,196 @@
+{%- block doctype -%}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+{%- endblock %}
+{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
+{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
+{%- macro relbar() %}
+    <div class="related">
+      <h3>Navigation</h3>
+      <ul>
+        {%- for rellink in rellinks %}
+        <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
+          <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags }}"
+             accesskey="{{ rellink[2] }}">{{ rellink[3] }}</a>
+          {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
+        {%- endfor %}
+        {%- block rootrellink %}
+        <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
+        {%- endblock %}
+        {%- for parent in parents %}
+          <li><a href="{{ parent.link|e }}" accesskey="U">{{ parent.title }}</a>{{ reldelim1 }}</li>
+        {%- endfor %}
+        {%- block relbaritems %}{% endblock %}
+      </ul>
+    </div>
+{%- endmacro %}
+{%- macro sidebar() %}
+      {%- if builder != 'htmlhelp' %}
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+          {%- block sidebarlogo %}
+          {%- if logo %}
+            <p class="logo"><img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/></p>
+          {%- endif %}
+          {%- endblock %}
+          {%- block sidebartoc %}
+          {%- if display_toc %}
+            <h3>Table Of Contents</h3>
+            {{ toc }}
+          {%- endif %}
+          {%- endblock %}
+          {%- block sidebarrel %}
+          {%- if prev %}
+            <h4>Previous topic</h4>
+            <p class="topless"><a href="{{ prev.link|e }}" title="previous chapter">{{ prev.title }}</a></p>
+          {%- endif %}
+          {%- if next %}
+            <h4>Next topic</h4>
+            <p class="topless"><a href="{{ next.link|e }}" title="next chapter">{{ next.title }}</a></p>
+          {%- endif %}
+          {%- endblock %}
+          {%- if sourcename %}
+            <!--<h3>This Page</h3>
+            <ul class="this-page-menu">
+            {%- if builder == 'web' %}
+              <li><a href="#comments">Comments ({{ comments|length }} so far)</a></li>
+              <li><a href="{{ pathto('@edit/' + sourcename)|e }}">Suggest Change</a></li>
+              <li><a href="{{ pathto('@source/' + sourcename)|e }}">Show Source</a></li>
+            {%- elif builder == 'html' %}
+              <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}">Show Source</a></li>
+            {%- endif %}
+            </ul>-->
+          {%- endif %}
+          {%- if customsidebar %}
+          {{ rendertemplate(customsidebar) }}
+          {%- endif %}
+          {%- block sidebarsearch %}
+          {%- if pagename != "search" %}
+            <h3>{{ builder == 'web' and 'Keyword' or 'Quick' }} search</h3>
+            <form class="search" action="{{ pathto('search') }}" method="get">
+              <input type="text" name="q" size="18" /> <input type="submit" value="Go" />
+              <input type="hidden" name="check_keywords" value="yes" />
+              <input type="hidden" name="area" value="default" />
+            </form>
+            {%- if builder == 'web' %}
+            <p style="font-size: 90%">Enter a module, class or function name.</p>
+            {%- endif %}
+          {%- endif %}
+          {%- endblock %}
+        </div>
+      </div>
+      {%- endif %}
+{%- endmacro -%}
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    {%- if builder != 'htmlhelp' %}
+      {%- set titlesuffix = " &mdash; " + docstitle %}
+    {%- endif %}
+    <title>{{ title|striptags }}{{ titlesuffix }}</title>
+    {%- if builder == 'web' %}
+    <link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
+      if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
+    {%- for link, type, title in page_links %}
+    <link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
+    {%- endfor %}
+    {%- else %}
+    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+    <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+    {%- endif %}
+    {%- if builder != 'htmlhelp' %}
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '{{ pathto("", 1) }}',
+          VERSION:     '{{ release }}',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '{{ file_suffix }}'
+      };
+    </script>
+    <script type="text/javascript" src="{{ pathto('_static/jquery.js', 1) }}"></script>
+    <script type="text/javascript" src="{{ pathto('_static/interface.js', 1) }}"></script>
+    <script type="text/javascript" src="{{ pathto('_static/doctools.js', 1) }}"></script>
+    <script type="text/javascript" src="{{ pathto('_static/searchtools.js', 1) }}"></script>
+    {%- if use_opensearch %}
+    <link rel="search" type="application/opensearchdescription+xml"
+          title="Search within {{ docstitle }}"
+          href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+    {%- endif %}
+    {%- if favicon %}
+    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
+    {%- endif %}
+    {%- endif %}
+{%- block rellinks %}
+    {%- if hasdoc('about') %}
+    <link rel="author" title="About these documents" href="{{ pathto('about') }}" />
+    {%- endif %}
+    <link rel="contents" title="Global table of contents" href="{{ pathto('contents') }}" />
+    <link rel="index" title="Global index" href="{{ pathto('genindex') }}" />
+    <link rel="search" title="Search" href="{{ pathto('search') }}" />
+    {%- if hasdoc('copyright') %}
+    <link rel="copyright" title="Copyright" href="{{ pathto('copyright') }}" />
+    {%- endif %}
+    <link rel="top" title="{{ docstitle }}" href="{{ pathto('index') }}" />
+    {%- if parents %}
+    <link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
+    {%- endif %}
+    {%- if next %}
+    <link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
+    {%- endif %}
+    {%- if prev %}
+    <link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
+    {%- endif %}
+{%- endblock %}
+{%- block extrahead %}{% endblock %}
+  </head>
+  <body>
+
+{% block logilablogo %}
+<div class="logilablogo">
+	<a class="logogo" href="http://www.cubicweb.org"><img border="0" src="{{ pathto('_static/cubicweb.png', 1) }}"/></a>
+  </div>
+{% endblock %}
+
+{%- block relbar1 %}{{ relbar() }}{% endblock %}
+
+{%- block sidebar1 %}{# possible location for sidebar #}{% endblock %}
+
+{%- block document %}
+    <div class="document">
+      <div class="documentwrapper">
+      {%- if builder != 'htmlhelp' %}
+        <div class="bodywrapper">
+      {%- endif %}
+          <div class="body">
+            {% block body %}{% endblock %}
+          </div>
+      {%- if builder != 'htmlhelp' %}
+        </div>
+      {%- endif %}
+      </div>
+{%- endblock %}
+
+{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
+      <div class="clearer"></div>
+    </div>
+
+{%- block relbar2 %}{{ relbar() }}{% endblock %}
+
+{%- block footer %}
+    <div class="footer">
+    {%- if hasdoc('copyright') %}
+      &copy; <a href="{{ pathto('copyright') }}">Copyright</a> {{ copyright }}.
+    {%- else %}
+      &copy; Copyright {{ copyright }}.
+    {%- endif %}
+    {%- if last_updated %}
+      Last updated on {{ last_updated }}.
+    {%- endif %}
+    {%- if show_sphinx %}
+      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
+    {%- endif %}
+    </div>
+{%- endblock %}
+  </body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_themes/cubicweb/layout.html	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,61 @@
+{% extends "basic/layout.html" %}
+
+{%- block extrahead %}
+<!--[if lte IE 6]>
+<link rel="stylesheet" href="{{ pathto('_static/ie6.css', 1) }}" type="text/css" media="screen" charset="utf-8" />
+<![endif]-->
+{%- if theme_favicon %}
+<link rel="shortcut icon" href="{{ pathto('_static/'+theme_favicon, 1) }}"/>
+{%- endif %}
+
+{%- if theme_canonical_url %}
+<link rel="canonical" href="{{ theme_canonical_url }}{{ pagename }}.html"/>
+{%- endif %}
+{% endblock %}
+
+{% block header %}
+
+{% if theme_in_progress|tobool %}
+    <img style="position: fixed; display: block; width: 165px; height: 165px; bottom: 60px; right: 0; border: 0;" src="{{ pathto('_static/in_progress.png', 1) }}" alt="Documentation in progress" />
+{% endif %}
+
+{% if theme_outdated|tobool %}
+    <div style="bottom: 60px; right: 20px;position: fixed;"><a href="{{ latest_url }}" class="btn btn-large btn-danger"><strong>&gt;</strong> Read the latest version of this page</a></div>
+{% endif %}
+
+<div class="header-small">
+	{%- if theme_logo %}
+	{% set img, ext = theme_logo.split('.', -1) %}
+	<div class="logo-small">
+		<a href="{{ pathto(master_doc) }}">
+      		<img class="logo" src="{{ pathto('_static/%s-small.%s' % (img, ext), 1)}}" alt="Logo"/>
+		</a>
+  	</div>
+  	{%- endif %}
+</div>
+{% endblock %}
+
+{%- macro relbar() %}
+<div class="related">
+	<h3>{{ _('Navigation') }}</h3>
+	<ul>
+		{%- for rellink in rellinks %}
+		<li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
+			<a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
+			{{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
+			{%- if not loop.first %}{{ reldelim2 }}{% endif %}
+		</li>
+		{%- endfor %}
+    	{%- block rootrellink %}
+    	<li><a href="{{ pathto(master_doc) }}">{{ docstitle|e }}</a>{{ reldelim1 }}</li>
+    	{%- endblock %}
+    	{%- for parent in parents %}
+          <li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
+        {%- endfor %}
+        {%- block relbaritems %} {% endblock %}
+  	</ul>
+</div>
+{%- endmacro %}
+
+{%- block sidebarlogo %}{%- endblock %}
+{%- block sidebarsourcelink %}{%- endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_themes/cubicweb/static/cubicweb.css_t	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * cubicweb.css_t
+ * ~~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- cubicweb theme.
+ *
+ * :copyright: Copyright 2014 by the Cubicweb team, see AUTHORS.
+ * :license: LGPL, see LICENSE for details.
+ *
+ */
+ 
+@import url("pyramid.css");
+
+div.header-small {
+  background-image: linear-gradient(white, #e2e2e2);
+  border-bottom: 1px solid #bbb;
+}
+
+div.logo-small {
+  padding: 10px;
+}
+
+img.logo {
+  width: 150px;
+}
+
+div.related a {
+  color: #e6820e;
+}
+
+a, a .pre {
+  color: #e6820e;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_themes/cubicweb/static/cubicweb.ico	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,1 @@
+../../../../../../web/data/favicon.ico
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_themes/cubicweb/static/logo-cubicweb-small.svg	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,1 @@
+logo-cubicweb.svg
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_themes/cubicweb/static/logo-cubicweb.svg	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,1 @@
+../../../../../../web/data/logo-cubicweb.svg
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/_themes/cubicweb/theme.conf	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,12 @@
+[theme]
+inherit = pyramid
+pygments_style = sphinx.pygments_styles.PyramidStyle
+stylesheet = cubicweb.css
+
+
+[options]
+logo = logo-cubicweb.svg
+favicon = cubicweb.ico
+in_progress = false
+outdated = false
+canonical_url = 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/MERGE_ME-tut-create-app.en.txt	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,386 @@
+.. -*- coding: utf-8 -*-
+
+
+Tutoriel : créer votre première application web pour Google AppEngine
+=====================================================================
+
+[TRANSLATE ME TO FRENCH]
+
+This tutorial will guide you step by step to build a blog application 
+and discover the unique features of `LAX`. It assumes that you followed
+the :ref:`installation` guidelines and that both the `AppEngine SDK` and the
+`LAX` framework are setup on your computer.
+
+Creating a new application
+--------------------------
+
+We choosed in this tutorial to develop a blog as an example of web application
+and will go through each required steps/actions to have it running with `LAX`.
+When you installed `LAX`, you saw a directory named ``skel``. Make a copy of
+this directory and call it ``BlogDemo``.
+
+The location of this directory does not matter. But once decided, make sure your ``PYTHONPATH`` is properly set (:ref:`installation`).
+
+
+Defining a schema
+-----------------
+
+With `LAX`, the schema/datamodel is the core of the application. This is where
+you will define the type of content you have to hanlde in your application.
+
+Let us start with something simple and improve on it iteratively. 
+
+In schema.py, we define two entities: ``Blog`` and ``BlogEntry``.
+
+::
+
+  class Blog(EntityType):
+      title = String(maxsize=50, required=True)
+      description = String()
+
+  class BlogEntry(EntityType):
+      title = String(maxsize=100, required=True)
+      publish_date = Date(default='TODAY')
+      text = String(fulltextindexed=True)
+      category = String(vocabulary=('important','business'))
+      entry_of = SubjectRelation('Blog', cardinality='?*')
+
+A Blog has a title and a description. The title is a string that is
+required 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 text. The title is a
+string that is required and must be less than 100 characters. The
+publish_date is a Date with a default value of TODAY, meaning that
+when a BlogEntry is created, its publish_date will be the current day
+unless it is modified. The text is a string that will be indexed in
+the full-text index and has no constraint.
+
+A BlogEntry also has a relationship ``entry_of`` that link it to a
+Blog. The cardinality ``?*`` means that a BlogEntry can be part of
+zero or one Blog (``?`` means `zero or one`) and that a Blog can
+have any number of BlogEntry (``*`` means `any number including
+zero`). For completeness, remember that ``+`` means `one or more`.
+
+Running the application
+-----------------------
+
+Defining this simple schema is enough to get us started. Make sure you
+followed the setup steps described in detail in the installation
+chapter (especially visiting http://localhost:8080/_load as an
+administrator), then launch the application with the command::
+
+   python dev_appserver.py BlogDemo
+
+and point your browser at http://localhost:8080/ (if it is easier for
+you, use the on-line demo at http://lax.appspot.com/).
+
+.. image:: images/lax-book.00-login.en.png
+   :alt: login screen
+
+After you log in, you will see the home page of your application. It
+lists the entity types: Blog and BlogEntry. If these links read
+``blog_plural`` and ``blogentry_plural`` it is because
+internationalization (i18n) is not working for you yet. Please ignore
+this for now.
+
+.. image:: images/lax-book.01-start.en.png
+   :alt: home page
+
+Creating system entities
+------------------------
+You can only create new users if you decided not to use google authentication.
+
+
+[WRITE ME : create users manages permissions etc]
+
+
+
+Creating application entites
+----------------------------
+
+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/lax-book.02-create-blog.en.png
+   :alt: from to create blog
+
+Click on the logo at top left to get back to the home page, then
+follow the Blog link 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/lax-book.03-list-one-blog.en.png
+   :alt: displaying a list of a single blog
+
+Clicking on this item will get you to its detailed description except
+that in this case, there is not much to display besides the name and
+the phrase ``everything about technology``.
+
+.. image:: images/lax-book.04-detail-one-blog.en.png
+  :alt: displaying the detailed view of a blog
+
+Now get back to the home page by clicking on the top-left logo, then
+create a new Blog called ``MyLife`` and get back to the home page
+again to follow the Blog link for the second time. The list now
+has two items.
+
+.. image:: images/lax-book.05-list-two-blog.en.png
+   :alt: displaying a list of two blogs
+
+
+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/lax-book.06-add-relation-entryof.en.png
+   :alt: editing a blog entry to add a relation to a blog
+
+Validate the changes by clicking ``Validate``. The entity BlogEntry
+that is displayed now includes a link to the entity Blog named
+``MyLife``.
+
+.. image:: images/lax-book.07-detail-one-blogentry.en.png
+   :alt: displaying the detailed view of a blogentry
+
+Remember that all of this was handled by the framework and that the
+only input that was provided so far is the schema. To get a graphical
+view of the schema, run the ``laxctl genschema BlogDemo`` command as
+explained in the installation section and point your browser to the
+URL http://localhost:8080/schema
+
+.. image:: images/lax-book.08-schema.en.png
+   :alt: graphical view of the schema (aka data-model)
+
+Site configuration
+------------------
+
+.. 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]
+
+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('CWGroup', 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.
+
+Change view permission
+~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+Conclusion
+----------
+
+Exercise
+~~~~~~~~
+
+Create new blog entries in ``Tech-blog``.
+
+What we learned
+~~~~~~~~~~~~~~~
+
+Creating a simple schema was enough to set up a new application that
+can store blogs and blog entries. 
+
+What is next ?
+~~~~~~~~~~~~~~
+
+Although the application is fully functionnal, its look is very
+basic. In the following section we will learn to create views to
+customize how data is displayed.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/MERGE_ME-tut-create-gae-app.en.txt	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+.. _tutorielGAE:
+
+Tutoriel : créer votre première application web pour Google AppEngine
+=====================================================================
+
+Ce tutoriel va vous guider pas à pas a construire une apllication web 
+de gestion de Blog afin de vous faire découvrir les fonctionnalités de
+*CubicWeb*.
+
+Nous supposons que vous avec déjà suivi le guide :ref:`installationGAE`.
+
+
+Créez une nouvelle application
+------------------------------
+
+Nous choisissons dans ce tutoriel de développer un blog comme un exemple
+d'application web et nous allons expliciter toutes les étapes nécessaires
+à sa réalisation.  
+
+::
+  
+  cubicweb-ctl newgapp blogdemo
+
+`newgapp` est la commande permettant de créer une instance *CubicWeb* pour
+le datastore.
+
+Assurez-vous que votre variable d'environnement ``PYTHONPATH`` est correctement
+initialisée (:ref:`installationGAE`)
+
+Définissez un schéma
+--------------------
+
+Le modèle de données ou schéma est au coeur d'une application *CubicWeb*.
+C'est là où vous allez devoir définir le type de contenu que votre application
+devra gérer.
+
+Commençons par un schéma simple que nous améliorerons progressivemment.
+
+Une fois votre instance ``blogdemo`` crée, vous trouverez un fichier ``schema.py``
+contenant la définition des entités suivantes : ``Blog`` and ``BlogEntry``.
+
+::
+
+  class Blog(EntityType):
+      title = String(maxsize=50, required=True)
+      description = String()
+
+  class BlogEntry(EntityType):
+      title = String(maxsize=100, required=True)
+      publish_date = Date(default='TODAY')
+      text = String(fulltextindexed=True)
+      category = String(vocabulary=('important','business'))
+      entry_of = SubjectRelation('Blog', cardinality='?*')
+
+
+Un ``Blog`` a un titre et une description. Le titre est une chaîne 
+de caractères requise par la classe parente EntityType and ne doit
+pas excéder 50 caractères. La description est une chaîne de 
+caractères sans contraintes.
+
+Une ``BlogEntry`` a un titre, une date de publication et du texte
+étant son contenu. Le titre est une chaîne de caractères qui ne 
+doit pas excéder 100 caractères. La date de publication est de type Date et a
+pour valeur par défaut TODAY, ce qui signifie que lorsqu'une 
+``BlogEntry`` sera créée, sa date de publication sera la date
+courante a moins de modifier ce champ. Le texte est une chaîne de
+caractères qui sera indexée en plein texte et sans contraintes.
+
+Une ``BlogEntry`` a aussi une relation nommée ``entry_of`` qui la
+relie à un ``Blog``. La cardinalité ``?*`` signifie que BlogEntry
+peut faire partie de zero a un Blog (``?`` signifie `zero ou un`) et
+qu'un Blog peut avoir une infinité de BlogEntry (``*`` signifie
+`n'importe quel nombre incluant zero`). 
+Par soucis de complétude, nous rappellerons que ``+`` signifie
+`un ou plus`.
+
+Lancez l'application
+--------------------
+
+Définir ce simple schéma est suffisant pour commencer. Assurez-vous 
+que vous avez suivi les étapes décrites dans la section installation
+(en particulier visitez http://localhost:8080/_load en tant qu'administrateur
+afin d'initialiser le datastore), puis lancez votre application avec la commande ::
+   
+   python dev_appserver.py BlogDemo
+
+puis dirigez vous vers http://localhost:8080/ (ou si c'est plus facile
+vous pouvez utiliser la démo en ligne http://lax.appspot.com/).
+[FIXME] -- changer la demo en ligne en quelque chose qui marche (!)
+
+.. image:: images/lax-book.00-login.en.png
+   :alt: login screen
+
+Après vous être authentifié, vous arrivez sur la page d'accueil de votre 
+application. Cette page liste les types d'entités accessibles dans votre
+application, en l'occurrence : Blog et Articles. Si vous lisez ``blog_plural``
+et ``blogentry_plural`` cela signifie que l'internationalisation (i18n)
+n'a pas encore fonctionné. Ignorez cela pour le moment.
+
+.. image:: images/lax-book.01-start.en.png
+   :alt: home page
+
+Créez des entités système
+-------------------------
+
+Vous ne pourrez créer de nouveaux utilisateurs que dans le cas où vous
+avez choisi de ne pas utiliser l'authentification Google.
+
+
+[WRITE ME : create users manages permissions etc]
+
+
+
+Créez des entités applicatives
+------------------------------
+
+Créez un Blog
+~~~~~~~~~~~~~
+
+Créons à présent quelques entités. Cliquez sur `[+]` sur la
+droite du lien Blog. Appelez cette nouvelle entité Blog ``Tech-Blog``
+et tapez pour la description ``everything about technology``,
+puis validez le formulaire d'édition en cliquant sur le bouton
+``Validate``.
+
+
+.. image:: images/lax-book.02-create-blog.en.png
+   :alt: from to create blog
+
+En cliquant sur le logo situé dans le coin gauche de la fenêtre,
+vous allez être redirigé vers la page d'accueil. Ensuite, si vous allez 
+sur le lien Blog, vous devriez voir la liste des entités Blog, en particulier
+celui que vous venez juste de créer ``Tech-Blog``.
+
+.. image:: images/lax-book.03-list-one-blog.en.png
+   :alt: displaying a list of a single blog
+
+Si vous cliquez sur ``Tech-Blog`` vous devriez obtenir une description
+détaillée, ce qui dans notre cas, n'est rien de plus que le titre
+et la phrase ``everything about technology``
+
+
+.. image:: images/lax-book.04-detail-one-blog.en.png
+   :alt: displaying the detailed view of a blog
+
+Maintenant retournons sur la page d'accueil et créons un nouveau
+Blog ``MyLife`` et retournons sur la page d'accueil, puis suivons
+le lien Blog et nous constatons qu'à présent deux blogs sont listés.
+
+.. image:: images/lax-book.05-list-two-blog.en.png
+   :alt: displaying a list of two blogs
+
+Créons un article
+~~~~~~~~~~~~~~~~~
+
+Revenons sur la page d'accueil et cliquons sur `[+]` à droite du lien
+`articles`. Appellons cette nouvelle entité ``Hello World`` et introduisons
+un peut de texte avant de ``Valider``. Vous venez d'ajouter un article
+sans avoir précisé à quel Blog il appartenait. Dans la colonne de gauche
+se trouve une boite intitulé ``actions``, cliquez sur le menu ``modifier``.
+Vous êtes de retour sur le formulaire d'édition de l'article que vous 
+venez de créer, à ceci près que ce formulaire a maintenant une nouvelle
+section intitulée ``ajouter relation``. Choisissez ``entry_of`` dans ce menu,
+cela va faire apparaitre une deuxième menu déroulant dans lequel vous
+allez pouvoir séléctionner le Blog ``MyLife``.
+
+Vous auriez pu aussi, au moment où vous avez crée votre article, sélectionner
+``appliquer`` au lieu de ``valider`` et le menu ``ajouter relation`` serait apparu.
+
+.. image:: images/lax-book.06-add-relation-entryof.en.png
+   :alt: editing a blog entry to add a relation to a blog
+
+Validez vos modifications en cliquant sur ``Valider``. L'entité article
+qui est listée contient maintenant un lien vers le Blog auquel il 
+appartient, ``MyLife``.
+
+.. image:: images/lax-book.07-detail-one-blogentry.en.png
+   :alt: displaying the detailed view of a blogentry
+
+Rappelez-vous que pour le moment, tout a été géré par la plate-forme
+*CubicWeb* et que la seule chose qui a été fournie est le schéma de
+données. D'ailleurs pour obtenir une vue graphique du schéma, exécutez
+la commande ``laxctl genschema blogdemo`` et vous pourrez visualiser
+votre schéma a l'URL suivante : http://localhost:8080/schema
+
+.. image:: images/lax-book.08-schema.en.png
+   :alt: graphical view of the schema (aka data-model)
+
+
+Change view permission
+~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+Conclusion
+----------
+
+Exercise
+~~~~~~~~
+
+Create new blog entries in ``Tech-blog``.
+
+What we learned
+~~~~~~~~~~~~~~~
+
+Creating a simple schema was enough to set up a new application that
+can store blogs and blog entries. 
+
+What is next ?
+~~~~~~~~~~~~~~
+
+Although the application is fully functionnal, its look is very
+basic. In the following section we will learn to create views to
+customize how data is displayed.
+
+
--- a/doc/book/README	Mon Jul 06 17:39:35 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-====
-Book
-====
-
-----
-Part
-----
-
-Chapter
-=======
-
-.. _Level1AnchorForLaterReference:
-
-Level 1 section
----------------
-
-Level 2 section
-~~~~~~~~~~~~~~~
-
-Level 3 section
-```````````````
-
-
-
-*CubicWeb*
-
-
-inline directives:
-  :file:`directory/file`
-  :envvar:`AN_ENV_VARIABLE`
-  :command:`command --option arguments`
-
-  :ref:, :mod:
-
-
-.. sourcecode:: python
-
-   class SomePythonCode:
-     ...
-
-.. XXX a comment, wont be rendered
-
-
-a [foot note]_
-
-.. [foot note] the foot note content
-
-
-Boxes
-=====
-
-- warning box: 
-    .. warning::
-
-       Warning content
-- note box:
-    .. note::
-
-       Note content
-
-
-
-Cross references
-================
-
-To arbitrary section
---------------------
-
-:ref:`identifier` ou :ref:`label <identifier>`
-
-Label required of referencing node which as no title, else the node's title will be used.
-
-
-To API objects
---------------
-See the autodoc sphinx extension documentation. Quick overview:
-
-* ref to a class: :class:`cubicweb.devtools.testlib.AutomaticWebTest`
-
-* if you can to see only the class name in the generated documentation, add a ~:
-  :class:`~cubicweb.devtools.testlib.AutomaticWebTest`
-
-* you can also use :mod: (module), :exc: (exception), :func: (function), :meth: (method)...
-
-* syntax explained above to specify label explicitly may also be used
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/additionnal_services/index.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,14 @@
+Additional services
+===================
+
+In this chapter, we introduce services crossing the *web -
+repository - administration* organisation of the first parts of the
+CubicWeb book. Those services can be either proper services (like the
+undo functionality) or mere *topical cross-sections* across CubicWeb.
+
+.. toctree::
+   :maxdepth: 2
+
+   undo
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/additionnal_services/undo.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,337 @@
+Undoing changes in CubicWeb
+---------------------------
+
+Many desktop applications offer the possibility for the user to
+undo its last changes : this *undo feature* has now been
+integrated into the CubicWeb framework. This document will
+introduce you to the *undo feature* both from the end-user and the
+application developer point of view.
+
+But because a semantic web application and a common desktop
+application are not the same thing at all, especially as far as
+undoing is concerned, we will first introduce *what* is the *undo
+feature* for now.
+
+What's *undoing* in a CubicWeb application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+What is an *undo feature* is quite intuitive in the context of a
+desktop application. But it is a bit subtler in the context of a
+Semantic Web application. This section introduces some of the main
+differences between a classical desktop and a Semantic Web
+applications to keep in mind in order to state precisely *what we
+want*.
+
+The notion transactions
+```````````````````````
+
+A CubicWeb application acts upon an *Entity-Relationship* model,
+described by a schema. This allows to ensure some data integrity
+properties. It also implies that changes are made by all-or-none
+groups called *transactions*, such that the data integrity is
+preserved whether the transaction is completely applied *or* none
+of it is applied.
+
+A transaction can thus include more actions than just those
+directly required by the main purpose of the user.  For example,
+when a user *just* writes a new blog entry, the underlying
+*transaction* holds several *actions* as illustrated below :
+
+* By admin on 2012/02/17 15:18 - Created Blog entry : Torototo
+
+  #. Created Blog entry : Torototo
+  #. Added relation : Torototo owned by admin
+  #. Added relation : Torototo blog entry of Undo Blog
+  #. Added relation : Torototo in state draft (draft)
+  #. Added relation : Torototo created by admin
+
+Because of the very nature (all-or-none) of the transactions, the
+"undoable stuff" are the transactions and not the actions !
+
+Public and private actions within a transaction
+```````````````````````````````````````````````
+
+Actually, within the *transaction* "Created Blog entry :
+Torototo", two of those *actions* are said to be *public* and
+the others are said to be *private*. *Public* here means that the
+public actions (1 and 3) were directly requested by the end user ;
+whereas *private* means that the other actions (2, 4, 5) were
+triggered "under the hood" to fulfill various requirements for the
+user operation (ensuring integrity, security, ... ).
+
+And because quite a lot of actions can be triggered by a "simple"
+end-user request, most of which the end-user is not (and does not
+need or wish to be) aware, only the so-called public actions will
+appear [1]_ in the description of the an undoable transaction.
+
+* By admin on 2012/02/17 15:18 - Created Blog entry : Torototo
+
+  #. Created Blog entry : Torototo
+  #. Added relation : Torototo blog entry of Undo Blog
+
+But note that both public and private actions will be undone
+together when the transaction is undone.
+
+(In)dependent transactions : the simple case
+````````````````````````````````````````````
+
+A CubicWeb application can be used *simultaneously* by different users
+(whereas a single user works on an given office document at a
+given time), so that there is not always a single history
+time-line in the CubicWeb case. Moreover CubicWeb provides
+security through the mechanism of *permissions* granted to each
+user. This can lead to some transactions *not* being undoable in
+some contexts.
+
+In the simple case two (unprivileged) users Alice and Bob make
+relatively independent changes : then both Alice and Bob can undo
+their changes. But in some case there is a clean dependency
+between Alice's and Bob's actions or between actions of one of
+them. For example let's suppose that :
+
+- Alice has created a blog,
+- then has published a first post inside,
+- then Bob has published a second post in the same blog,
+- and finally Alice has updated its post contents.
+
+Then it is clear that Alice can undo her contents changes and Bob
+can undo his post creation independently. But Alice can not undo
+her post creation while she has not first undone her changes.
+It is also clear that Bob should *not* have the
+permissions to undo any of Alice's transactions.
+
+
+More complex dependencies between transactions
+``````````````````````````````````````````````
+
+But more surprising things can quickly happen. Going back to the
+previous example, Alice *can* undo the creation of the blog after
+Bob has published its post in it ! But this is possible only
+because the schema does not *require* for a post to be in a
+blog. Would the *blog entry of* relation have been mandatory, then
+Alice could not have undone the blog creation because it would
+have broken integrity constraint for Bob's post.
+
+When a user attempts to undo a transaction the system will check
+whether a later transaction has explicit dependency on the
+would-be-undone transaction. In this case the system will not even
+attempt the undo operation and inform the user.
+
+If no such dependency is detected the system will attempt the undo
+operation but it can fail, typically because of integrity
+constraint violations. In such a case the undo operation is
+completely [3]_ rollbacked.
+
+
+The *undo feature* for CubicWeb end-users
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The exposition of the undo feature to the end-user through a Web
+interface is still quite basic and will be improved toward a
+greater usability. But it is already fully functional.  For now
+there are two ways to access the *undo feature* as long as the it
+has been activated in the instance configuration file with the
+option *undo-support=yes*.
+
+Immediately after having done the change to be canceled through
+the **undo** link in the message. This allows to undo an
+hastily action immediately. For example, just after having
+validated the creation of the blog entry *A second blog entry* we
+get the following message, allowing to undo the creation.
+
+.. image:: /images/undo_mesage_w600.png
+   :width: 600px
+   :alt: Screenshot of the undo link in the message
+   :align: center
+
+At any time we can access the **undo-history view** accessible from the
+start-up page.
+
+.. image:: /images/undo_startup-link_w600.png
+   :width: 600px
+   :alt: Screenshot of the startup menu with access to the history view
+   :align: center
+
+This view will provide inspection of the transaction and their (public)
+actions. Each transaction provides its own **undo** link. Only the
+transactions the user has permissions to see and undo will be shown.
+
+.. image:: /images/undo_history-view_w600.png
+   :width: 600px
+   :alt: Screenshot of the undo history main view
+   :align: center
+
+If the user attempts to undo a transaction which can't be undone or
+whose undoing fails, then a message will explain the situation and
+no partial undoing will be left behind.
+
+This is all for the end-user side of the undo mechanism : this is
+quite simple indeed ! Now, in the following section, we are going
+to introduce the developer side of the undo mechanism.
+
+The *undo feature* for CubicWeb application developers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A word of warning : this section is intended for developers,
+already having some knowledge of what's under CubicWeb's hood. If
+it is not *yet* the case, please refer to CubicWeb documentation
+http://docs.cubicweb.org/ .
+
+Overview
+````````
+
+The core of the undo mechanisms is at work in the *native source*,
+beyond the RQL. This does mean that *transactions* and *actions*
+are *no entities*. Instead they are represented at the SQL level
+and exposed through the *DB-API* supported by the repository
+*Connection* objects.
+
+Once the *undo feature* has been activated in the instance
+configuration file with the option *undo-support=yes*, each
+mutating operation (cf. [2]_) will be recorded in some special SQL
+table along with its associated transaction. Transaction are
+identified by a *txuuid* through which the functions of the
+*DB-API* handle them.
+
+On the web side the last commited transaction *txuuid* is
+remembered in the request's data to allow for imediate undoing
+whereas the *undo-history view* relies upon the *DB-API* to list
+the accessible transactions. The actual undoing is performed by
+the *UndoController* accessible at URL of the form
+`www.my.host/my/instance/undo?txuuid=...`
+
+The repository side
+```````````````````
+
+Please refer to the file `cubicweb/server/sources/native.py` and
+`cubicweb/transaction.py` for the details.
+
+The undoing information is mainly stored in three SQL tables:
+
+`transactions`
+    Stores the txuuid, the user eid and the date-and-time of
+    the transaction. This table is referenced by the two others.
+
+`tx_entity_actions`
+    Stores the undo information for actions on entities.
+
+`tx_relation_actions`
+    Stores the undo information for the actions on relations.
+
+When the undo support is activated, entries are added to those
+tables for each mutating operation on the data repository, and are
+deleted on each transaction undoing.
+
+Those table are accessible through the following methods of the
+repository `Connection` object :
+
+`undoable_transactions`
+    Returns a list of `Transaction` objects accessible to the user
+    and according to the specified filter(s) if any.
+
+`tx_info`
+    Returns a `Transaction` object from a `txuuid`
+
+`undo_transaction`
+    Returns the list of `Action` object for the given `txuuid`.
+
+    NB:  By default it only return *public* actions.
+
+The web side
+````````````
+
+The exposure of the *undo feature* to the end-user through the Web
+interface relies on the *DB-API* introduced above. This implies
+that the *transactions* and *actions* are not *entities* linked by
+*relations* on which the usual views can be applied directly.
+
+That's why the file `cubicweb/web/views/undohistory.py` defines
+some dedicated views to access the undo information :
+
+`UndoHistoryView`
+    This is a *StartupView*, the one accessible from the home
+    page of the instance which list all transactions.
+
+`UndoableTransactionView`
+    This view handles the display of a single `Transaction` object.
+
+`UndoableActionBaseView`
+    This (abstract) base class provides private methods to build
+    the display of actions whatever their nature.
+
+`Undoable[Add|Remove|Create|Delete|Update]ActionView`
+    Those views all inherit from `UndoableActionBaseView` and
+    each handles a specific kind of action.
+
+`UndoableActionPredicate`
+    This predicate is used as a *selector* to pick the appropriate
+    view for actions.
+
+Apart from this main *undo-history view* a `txuuid` is stored in
+the request's data `last_undoable_transaction` in order to allow
+immediate undoing of a hastily validated operation. This is
+handled in `cubicweb/web/application.py` in the `main_publish` and
+`add_undo_link_to_msg` methods for the storing and displaying
+respectively.
+
+Once the undo information is accessible, typically through a
+`txuuid` in an *undo* URL, the actual undo operation can be
+performed by the `UndoController` defined in
+`cubicweb/web/views/basecontrollers.py`. This controller basically
+extracts the `txuuid` and performs a call to `undo_transaction` and
+in case of an undo-specific error, lets the top level publisher
+handle it as a validation error.
+
+
+Conclusion
+~~~~~~~~~~
+
+The undo mechanism relies upon a low level recording of the
+mutating operation on the repository. Those records are accessible
+through some method added to the *DB-API* and exposed to the
+end-user either through a whole history view of through an
+immediate undoing link in the message box.
+
+The undo feature is functional but the interface and configuration
+options are still quite reduced. One major improvement would be to
+be able to filter with a finer grain which transactions or actions
+one wants to see in the *undo-history view*. Another critical
+improvement would be to enable the undo feature on a part only of
+the entity-relationship schema to avoid storing too much useless
+data and reduce the underlying overhead.
+
+But both functionality are related to the strong design choice not
+to represent transactions and actions as entities and
+relations. This has huge benefits in terms of safety and conceptual
+simplicity but prevents from using lots of convenient CubicWeb
+features such as *facets* to access undo information.
+
+Before developing further the undo feature or eventually revising
+this design choice, it appears that some return of experience is
+strongly needed. So don't hesitate to try the undo feature in your
+application and send us some feedback.
+
+
+Notes
+~~~~~
+
+.. [1] The end-user Web interface could be improved to enable
+       user to choose whether he wishes to see private actions.
+
+.. [2] There is only five kind of elementary actions (beyond
+       merely accessing data for reading):
+
+       * **C** : creating an entity
+       * **D** : deleting an entity
+       * **U** : updating an entity attributes
+       * **A** : adding a relation
+       * **R** : removing a relation
+
+.. [3] Meaning none of the actions in the transaction is
+       undone. Depending upon the application, it might make sense
+       to enable *partial* undo. That is to say undo in which some
+       actions could not be undo without preventing to undo the
+       others actions in the transaction (as long as it does not
+       break schema integrity). This is not forbidden by the
+       back-end but is deliberately not supported by the front-end
+       (for now at least).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/additional-tips.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,64 @@
+
+.. _Additional Tips:
+
+Backups (mostly with postgresql)
+--------------------------------
+
+It is always a good idea to backup. If your system does not do that,
+you should set it up. Note that whenever you do an upgrade,
+`cubicweb-ctl` offers you to backup your database.  There are a number
+of ways for doing backups.
+
+Using postgresql (and only that)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before you
+go ahead, make sure the following permissions are correct ::
+
+   # chgrp postgres /var/lib/cubicweb/backup
+   # chmod g+ws /var/lib/cubicweb/backup
+   # chgrp postgres /etc/cubicweb.d/*<instance>*/sources
+   # chmod g+r /etc/cubicweb.d/*<instance>*/sources
+
+Simply use the pg_dump in a cron installed for `postgres` user on the database server::
+
+    # m h  dom mon dow   command
+    0 2 * * * pg_dump -Fc --username=cubicweb --no-owner <instance> > /var/backups/<instance>-$(date '+%Y-%m-%d_%H:%M:%S').dump
+
+Using :command:`cubicweb-ctl db-dump`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The CubicWeb way is to use the :command:`db-dump` command. For that,
+you have to put your passwords in a user-only-readable file at the
+home directory of root user.  The file is `.pgpass` (`chmod 0600`), in
+this case for a socket run connection to PostgreSQL ::
+
+    /var/run/postgresql:5432:<instance>:<database user>:<database password>
+
+The postgres documentation for the `.pgpass` format can be found `here`_
+
+Then add the following command to the crontab of the user (`crontab -e`)::
+
+    # m h  dom mon dow   command
+    0 2 * * * cubicweb-ctl db-dump <instance>
+
+
+Backup ninja
+~~~~~~~~~~~~
+
+You can use a combination `backup-ninja`_ (which has a postgres script in the
+example directory), `backuppc`)_ (for versionning).
+
+Please note that in the *CubicWeb way* it adds a second location for your
+password which is error-prone.
+
+.. _`here` : http://www.postgresql.org/docs/current/static/libpq-pgpass.html
+.. _`backup-ninja` : https://labs.riseup.net/code/projects/show/backupninja/
+.. _`backuppc` : http://backuppc.sourceforge.net/
+
+.. warning::
+
+  Remember that these indications will fail you whenever you use
+  another database backend than postgres. Also it does properly handle
+  externally managed data such as files (using the Bytes File System
+  Storage).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/config.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,229 @@
+.. -*- coding: utf-8 -*-
+
+.. _ConfigEnv:
+
+Set-up of a *CubicWeb* environment
+==================================
+
+You can `configure the database`_ system of your choice:
+
+  - `PostgreSQL configuration`_
+  - `MySql configuration`_
+  - `SQLServer configuration`_
+  - `SQLite configuration`_
+
+For advanced features, have a look to:
+
+  - `Cubicweb resources configuration`_
+
+.. _`configure the database`: DatabaseInstallation_
+.. _`PostgreSQL configuration`: PostgresqlConfiguration_
+.. _`MySql configuration`: MySqlConfiguration_
+.. _`SQLServer configuration`: SQLServerConfiguration_
+.. _`SQLite configuration`: SQLiteConfiguration_
+.. _`Cubicweb resources configuration`: RessourcesConfiguration_
+
+
+
+.. _RessourcesConfiguration:
+
+Cubicweb resources configuration
+--------------------------------
+
+.. autodocstring:: cubicweb.cwconfig
+
+
+.. _DatabaseInstallation:
+
+Databases configuration
+-----------------------
+
+Each instance can be configured with its own database connection information,
+that will be stored in the instance's :file:`sources` file. The database to use
+will be chosen when creating the instance. CubicWeb is known to run with
+Postgresql (recommended), SQLServer and SQLite, and may run with MySQL.
+
+Other possible sources of data include CubicWeb, Subversion, LDAP and Mercurial,
+but at least one relational database is required for CubicWeb to work. You do
+not need to install a backend that you do not intend to use for one of your
+instances. SQLite is not fit for production use, but it works well for testing
+and ships with Python, which saves installation time when you want to get
+started quickly.
+
+.. _PostgresqlConfiguration:
+
+PostgreSQL
+~~~~~~~~~~
+
+Many Linux distributions ship with the appropriate PostgreSQL packages.
+Basically, you need to install the following packages:
+
+* `postgresql` and `postgresql-client`, which will pull the respective
+  versioned packages (e.g. `postgresql-9.1` and `postgresql-client-9.1`) and,
+  optionally,
+* a `postgresql-plpython-X.Y` package with a version corresponding to that of
+  the aforementioned packages (e.g. `postgresql-plpython-9.1`).
+
+If you run postgres version prior to 8.3, you'll also need the
+`postgresql-contrib-8.X` package for full-text search extension.
+
+If you run postgres on another host than the |cubicweb| repository, you should
+install the `postgresql-client` package on the |cubicweb| host, and others on the
+database host.
+
+For extra details concerning installation, please refer to the `PostgreSQL
+project online documentation`_.
+
+.. _`PostgreSQL project online documentation`: http://www.postgresql.org/docs
+
+
+Database cluster
+++++++++++++++++
+
+If you already have an existing cluster and PostgreSQL server running, you do
+not need to execute the initilization step of your PostgreSQL database unless
+you want a specific cluster for |cubicweb| databases or if your existing
+cluster doesn't use the UTF8 encoding (see note below).
+
+To initialize a PostgreSQL cluster, use the command ``initdb``::
+
+    $ initdb -E UTF8 -D /path/to/pgsql
+
+Notice the encoding specification. This is necessary since |cubicweb| usually
+want UTF8 encoded database. If you use a cluster with the wrong encoding, you'll
+get error like::
+
+  new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)
+  HINT:  Use the same encoding as in the template database, or use template0 as template.
+
+Once initialized, start the database server PostgreSQL with the command::
+
+  $ postgres -D /path/to/psql
+
+If you cannot execute this command due to permission issues, please make sure
+that your username has write access on the database.  ::
+
+  $ chown username /path/to/pgsql
+
+Database authentication
++++++++++++++++++++++++
+
+The database authentication is configured in `pg_hba.conf`. It can be either set
+to `ident sameuser` or `md5`.  If set to `md5`, make sure to use an existing
+user of your database.  If set to `ident sameuser`, make sure that your client's
+operating system user name has a matching user in the database. If not, please
+do as follow to create a user::
+
+  $ su
+  $ su - postgres
+  $ createuser -s -P username
+
+The option `-P` (for password prompt), will encrypt the password with the
+method set in the configuration file :file:`pg_hba.conf`.  If you do not use this
+option `-P`, then the default value will be null and you will need to set it
+with::
+
+  $ su postgres -c "echo ALTER USER username WITH PASSWORD 'userpasswd' | psql"
+
+The above login/password will be requested when you will create an instance with
+`cubicweb-ctl create` to initialize the database of your instance.
+
+Notice that the `cubicweb-ctl db-create` does database initialization that
+may requires a postgres superuser. That's why a login/password is explicitly asked
+at this step, so you can use there a superuser without using this user when running
+the instance. Things that require special privileges at this step:
+
+* database creation, require the 'create database' permission
+* install the plpython extension language (require superuser)
+* install the tsearch extension for postgres version prior to 8.3 (require superuser)
+
+To avoid using a super user each time you create an install, a nice trick is to
+install plpython (and tsearch when needed) on the special `template1` database,
+so they will be installed automatically when cubicweb databases are created
+without even with needs for special access rights. To do so, run ::
+
+  # Installation of plpythonu language by default ::
+  $ createlang -U pgadmin plpythonu template1
+  $ psql -U pgadmin template1
+  template1=# update pg_language set lanpltrusted=TRUE where lanname='plpythonu';
+
+Where `pgadmin` is a postgres superuser. The last command is necessary since by
+default plpython is an 'untrusted' language and as such can't be used by non
+superuser. This update fix that problem by making it trusted.
+
+To install the tsearch plain-text index extension on postgres prior to 8.3, run::
+
+    cat /usr/share/postgresql/8.X/contrib/tsearch2.sql | psql -U username template1
+
+
+.. _MySqlConfiguration:
+
+MySql
+~~~~~
+.. warning::
+    CubicWeb's MySQL support is not commonly used, so things may or may not work properly.
+
+You must add the following lines in ``/etc/mysql/my.cnf`` file::
+
+    transaction-isolation=READ-COMMITTED
+    default-storage-engine=INNODB
+    default-character-set=utf8
+    max_allowed_packet = 128M
+
+.. Note::
+    It is unclear whether mysql supports indexed string of arbitrary length or
+    not.
+
+
+.. _SQLServerConfiguration:
+
+SQLServer
+~~~~~~~~~
+
+As of this writing, support for SQLServer 2005 is functional but incomplete. You
+should be able to connect, create a database and go quite far, but some of the
+SQL generated from RQL queries is still currently not accepted by the
+backend. Porting to SQLServer 2008 is also an item on the backlog.
+
+The `source` configuration file may look like this (specific parts only are
+shown)::
+
+  [system]
+  db-driver=sqlserver2005
+  db-user=someuser
+  # database password not needed
+  #db-password=toto123
+  #db-create/init may ask for a pwd: just say anything
+  db-extra-arguments=Trusted_Connection
+  db-encoding=utf8
+
+
+You need to change the default settings on the database by running::
+
+ ALTER DATABASE <databasename> SET READ_COMMITTED_SNAPSHOT ON;
+
+The ALTER DATABASE command above requires some permissions that your
+user may not have. In that case you will have to ask your local DBA to
+run the query for you.
+
+You can check that the setting is correct by running the following
+query which must return '1'::
+
+   SELECT is_read_committed_snapshot_on
+     FROM sys.databases WHERE name='<databasename>';
+
+
+
+.. _SQLiteConfiguration:
+
+SQLite
+~~~~~~
+
+SQLite has the great advantage of requiring almost no configuration. Simply
+use 'sqlite' as db-driver, and set path to the dabase as db-name. Don't specify
+anything for db-user and db-password, they will be ignore anyway.
+
+.. Note::
+  SQLite is great for testing and to play with cubicweb but is not suited for
+  production environments.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/create-instance.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,100 @@
+.. -*- coding: utf-8 -*-
+
+Creation of your first instance
+===============================
+
+Instance creation
+-----------------
+
+Now that we created a cube, we can create an instance and access it via a web
+browser. We will use a `all-in-one` configuration to simplify things ::
+
+  cubicweb-ctl create -c all-in-one mycube myinstance
+
+.. note::
+  Please note that we created a new cube for a demo purposes but
+  you could have used an existing cube available in our standard library
+  such as blog or person for example.
+
+A series of questions will be prompted to you, the default answer is usually
+sufficient. You can anyway modify the configuration later on by editing
+configuration files. When a login/password are requested to access the database
+please use the credentials you created at the time you configured the database
+(:ref:`PostgresqlConfiguration`).
+
+It is important to distinguish here the user used to access the database and the
+user used to login to the cubicweb instance. When an instance starts, it uses
+the login/password for the database to get the schema and handle low level
+transaction. But, when :command:`cubicweb-ctl create` asks for a manager
+login/psswd of *CubicWeb*, it refers to the user you will use during the
+development to administrate your web instance. It will be possible, later on,
+to use this user to create other users for your final web instance.
+
+
+Instance administration
+-----------------------
+
+start / stop
+~~~~~~~~~~~~
+
+When this command is completed, the definition of your instance is
+located in :file:`~/etc/cubicweb.d/myinstance/*`. To launch it, you
+just type ::
+
+  cubicweb-ctl start -D myinstance
+
+The option `-D` specifies the *debug mode* : the instance is not
+running in server mode and does not disconnect from the terminal,
+which simplifies debugging in case the instance is not properly
+launched. You can see how it looks by visiting the URL
+`http://localhost:8080` (the port number depends of your
+configuration). To login, please use the cubicweb administrator
+login/password you defined when you created the instance.
+
+To shutdown the instance, Crtl-C in the terminal window is enough.
+If you did not use the option `-D`, then type ::
+
+  cubicweb-ctl stop myinstance
+
+This is it! All is settled down to start developping your data model...
+
+.. note::
+
+  The output of `cubicweb-ctl start -D myinstance` can be
+  overwhelming. It is possible to reduce the log level with the
+  `--loglevel` parameter as in `cubicweb-ctl start -D myinstance -l
+  info` to filter out all logs under `info` gravity.
+
+upgrade
+~~~~~~~
+
+A manual upgrade step is necessary whenever a new version of CubicWeb or
+a cube is installed, in order to synchronise the instance's
+configuration and schema with the new code.  The command is::
+
+  cubicweb-ctl upgrade myinstance
+
+A series of questions will be asked. It always starts with a proposal
+to make a backup of your sources (where it applies). Unless you know
+exactly what you are doing (i.e. typically fiddling in debug mode, but
+definitely NOT migrating a production instance), you should answer YES
+to that.
+
+The remaining questions concern the migration steps of |cubicweb|,
+then of the cubes that form the whole application, in reverse
+dependency order.
+
+In principle, if the migration scripts have been properly written and
+tested, you should answer YES to all questions.
+
+Somtimes, typically while debugging a migration script, something goes
+wrong and the migration fails. Unfortunately the databse may be in an
+incoherent state. You have two options here:
+
+* fix the bug, restore the database and restart the migration process
+  from scratch (quite recommended in a production environement)
+
+* try to replay the migration up to the last successful commit, that
+  is answering NO to all questions up to the step that failed, and
+  finish by answering YES to the remaining questions.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/cubicweb-ctl.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,111 @@
+.. -*- coding: utf-8 -*-
+
+.. _cubicweb-ctl:
+
+``cubicweb-ctl`` tool
+=====================
+
+`cubicweb-ctl` is the swiss knife to manage *CubicWeb* instances.
+The general syntax is ::
+
+  cubicweb-ctl <command> [options command] <arguments commands>
+
+To view available commands ::
+
+  cubicweb-ctl
+  cubicweb-ctl --help
+
+Please note that the commands available depends on the *CubicWeb* packages
+and cubes that have been installed.
+
+To view the help menu on specific command ::
+
+  cubicweb-ctl <command> --help
+
+Listing available cubes and instance
+-------------------------------------
+
+* ``list``, provides a list of the available configuration, cubes
+  and instances.
+
+
+Creation of a new cube
+-----------------------
+
+Create your new cube cube ::
+
+   cubicweb-ctl newcube
+
+This will create a new cube in
+``/path/to/grshell-cubicweb/cubes/<mycube>`` for a Mercurial
+installation, or in ``/usr/share/cubicweb/cubes`` for a debian
+packages installation.
+
+Create an instance
+-------------------
+
+You must ensure `~/etc/cubicweb.d/` exists prior to this. On windows, the
+'~' part will probably expand to 'Documents and Settings/user'.
+
+To create an instance from an existing cube, execute the following
+command ::
+
+   cubicweb-ctl create <cube_name> <instance_name>
+
+This command will create the configuration files of an instance in
+``~/etc/cubicweb.d/<instance_name>``.
+
+The tool ``cubicweb-ctl`` executes the command ``db-create`` and
+``db-init`` when you run ``create`` so that you can complete an
+instance creation in a single command. But of course it is possible
+to issue these separate commands separately, at a later stage.
+
+Command to create/initialize an instance database
+-------------------------------------------------
+
+* ``db-create``, creates the system database of an instance (tables and
+  extensions only)
+* ``db-init``, initializes the system database of an instance
+  (schema, groups, users, workflows...)
+
+Commands to control instances
+-----------------------------
+
+* ``start``, starts one or more or all instances
+
+of special interest::
+
+  start -D
+
+will start in debug mode (under windows, starting without -D will not
+work; you need instead to setup your instance as a service).
+
+* ``stop``, stops one or more or all instances
+* ``restart``, restarts one or more or all instances
+* ``status``, returns the status of the instance(s)
+
+Commands to maintain instances
+------------------------------
+
+* ``upgrade``, launches the existing instances migration when a new version
+  of *CubicWeb* or the cubes installed is available
+* ``shell``, opens a (Python based) migration shell for manual maintenance of the instance
+* ``db-dump``, creates a dump of the system database
+* ``db-restore``, restores a dump of the system database
+* ``db-check``, checks data integrity of an instance. If the automatic correction
+  is activated, it is recommanded to create a dump before this operation.
+* ``schema-sync``, synchronizes the persistent schema of an instance with
+  the instance schema. It is recommanded to create a dump before this operation.
+
+Commands to maintain i18n catalogs
+----------------------------------
+* ``i18ncubicweb``, regenerates messages catalogs of the *CubicWeb* library
+* ``i18ncube``, regenerates the messages catalogs of a cube
+* ``i18ninstance``, recompiles the messages catalogs of an instance.
+  This is automatically done while upgrading.
+
+See also chapter :ref:`internationalization`.
+
+Other commands
+--------------
+* ``delete``, deletes an instance (configuration files and database)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/index.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,28 @@
+.. -*- coding: utf-8 -*-
+
+.. _Part3:
+
+--------------
+Administration
+--------------
+
+This part is for installation and administration of the *CubicWeb* framework and
+instances based on that framework.
+
+.. toctree::
+   :maxdepth: 1
+   :numbered:
+
+   setup
+   setup-windows
+   config
+   cubicweb-ctl
+   create-instance
+   instance-config
+   site-config
+   multisources
+   ldap
+   migration
+   additional-tips
+   rql-logs
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/instance-config.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,200 @@
+.. -*- coding: utf-8 -*-
+
+
+Configure an instance
+=====================
+
+While creating an instance, a configuration file is generated in::
+
+    $ (CW_INSTANCES_DIR) / <instance> / <configuration name>.conf
+
+For example::
+
+    /etc/cubicweb.d/myblog/all-in-one.conf
+
+It is a simple text file in the INI format
+(http://en.wikipedia.org/wiki/INI_file). In the following description,
+each option name is prefixed with its own section and followed by its
+default value if necessary, e.g. "`<section>.<option>` [value]."
+
+.. _`WebServerConfig`:
+
+Configuring the Web server
+--------------------------
+:`web.auth-model` [cookie]:
+    authentication mode, cookie or http
+:`web.realm`:
+    realm of the instance in http authentication mode
+:`web.http-session-time` [0]:
+    period of inactivity of an HTTP session before it closes automatically.
+    Duration in seconds, 0 meaning no expiration (or more exactly at the
+    closing of the browser client)
+
+:`main.anonymous-user`, `main.anonymous-password`:
+    login and password to use to connect to the RQL server with
+    HTTP anonymous connection. CWUser account should exist.
+
+:`main.base-url`:
+    url base site to be used to generate the urls of web pages
+
+Https configuration
+```````````````````
+It is possible to make a site accessible for anonymous http connections
+and https for authenticated users. This requires to
+use apache (for example) for redirection and the variable `main.https-url`
+of configuration file.
+
+For this to work you have to activate the following apache modules :
+
+* rewrite
+* proxy
+* http_proxy
+
+The command on Debian based systems for that is ::
+
+  a2enmod rewrite http_proxy proxy
+  /etc/init.d/apache2 restart
+
+:Example:
+
+   For an apache redirection of a site accessible via `http://localhost/demo`
+   and `https://localhost/demo` and actually running on port 8080, it
+   takes to the http:::
+
+     ProxyPreserveHost On
+     RewriteEngine On
+     RewriteCond %{REQUEST_URI} ^/demo
+     RewriteRule ^/demo$ /demo/
+     RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
+
+   and for the https:::
+
+     ProxyPreserveHost On
+     RewriteEngine On
+     RewriteCond %{REQUEST_URI} ^/ demo
+     RewriteRule ^/demo$/demo/
+     RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
+
+
+   and we will file in the all-in-one.conf of the instance:::
+
+     base-url = http://localhost/demo
+     https-url = https://localhost/demo
+
+Notice that if you simply want a site accessible through https, not *both* http
+and https, simply set `base-url` to the https url and the first section into your
+apache configuration (as you would have to do for an http configuration with an
+apache front-end).
+
+Setting up the web client
+-------------------------
+:`web.embed-allowed`:
+    regular expression matching sites which could be "embedded" in
+    the site (controllers 'embed')
+:`web.submit-url`:
+    url where the bugs encountered in the instance can be mailed to
+
+
+RQL server configuration
+------------------------
+:`main.host`:
+    host name if it can not be detected correctly
+:`main.pid-file`:
+    file where will be written the server pid
+:`main.uid`:
+    user account to use for launching the server when it is
+    root launched by init
+:`main.session-time [30*60]`:
+    timeout of a RQL session
+:`main.query-log-file`:
+    file where all requests RQL executed by the server are written
+
+
+Configuring e-mail
+------------------
+RQL and web server side:
+
+:`email.mangle-mails [no]`:
+    indicates whether the email addresses must be displayed as is or
+    transformed
+
+RQL server side:
+
+:`email.smtp-host [mail]`:
+    hostname hosting the SMTP server to use for outgoing mail
+:`email.smtp-port [25]`:
+    SMTP server port to use for outgoing mail
+:`email.sender-name`:
+    name to use for outgoing mail of the instance
+:`email.sender-addr`:
+    address for outgoing mail of the instance
+:`email.default dest-addrs`:
+    destination addresses by default, if used by the configuration of the
+    dissemination of the model (separated by commas)
+:`email.supervising-addrs`:
+    destination addresses of e-mails of supervision (separated by
+    commas)
+
+
+Configuring logging
+-------------------
+:`main.log-threshold`:
+    level of filtering messages (DEBUG, INFO, WARNING, ERROR)
+:`main.log-file`:
+    file to write messages
+
+
+.. _PersistentProperties:
+
+Configuring persistent properties
+---------------------------------
+Other configuration settings are in the form of entities `CWProperty`
+in the database. It must be edited via the web interface or by
+RQL queries.
+
+:`ui.encoding`:
+    Character encoding to use for the web
+:`navigation.short-line-size`:
+    number of characters for "short" display
+:`navigation.page-size`:
+    maximum number of entities to show per results page
+:`navigation.related-limit`:
+    number of related entities to show up on primary entity view
+:`navigation.combobox-limit`:
+    number of entities unrelated to show up on the drop-down lists of
+    the sight on an editing entity view
+
+Cross-Origin Resource Sharing
+-----------------------------
+
+CubicWeb provides some support for the CORS_ protocol. For now, the
+provided implementation only deals with access to a CubicWeb instance
+as a whole. Support for a finer granularity may be considered in the
+future.
+
+Specificities of the provided implementation:
+
+- ``Access-Control-Allow-Credentials`` is always true
+- ``Access-Control-Allow-Origin`` header in response will never be
+  ``*``
+- ``Access-Control-Expose-Headers`` can be configured globally (see below)
+- ``Access-Control-Max-Age`` can be configured globally (see below)
+- ``Access-Control-Allow-Methods`` can be configured globally (see below)
+- ``Access-Control-Allow-Headers`` can be configured globally (see below)
+
+
+A few parameters can be set to configure the CORS_ capabilities of CubicWeb.
+
+.. _CORS: http://www.w3.org/TR/cors/
+
+:`access-control-allow-origin`:
+   comma-separated list of allowed origin domains or "*" for any domain
+:`access-control-allow-methods`:
+   comma-separated list of allowed HTTP methods
+:`access-control-max-age`:
+   maximum age of cross-origin resource sharing (in seconds)
+:`access-control-allow-headers`:
+   comma-separated list of allowed HTTP custom headers (used in simple requests)
+:`access-control-expose-headers`:
+   comma-separated list of allowed HTTP custom headers (used in preflight requests)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/ldap.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,134 @@
+.. _LDAP:
+
+LDAP integration
+================
+
+Overview
+--------
+
+Using LDAP as a source for user credentials and information is quite
+easy. The most difficult part lies in building an LDAP schema or
+using an existing one.
+
+At cube creation time, one is asked if more sources are wanted. LDAP
+is one possible option at this time. Of course, it is always possible
+to set it up later using the `CWSource` entity type, which we discuss
+there.
+
+It is possible to add as many LDAP sources as wanted, which translates
+in as many `CWSource` entities as needed.
+
+The general principle of the LDAP source is, given a proper
+configuration, to create local users matching the users available in
+the directory and deriving local user attributes from directory users
+attributes. Then a periodic task ensures local user information
+synchronization with the directory.
+
+Users handled by such a source should not be edited directly from
+within the application instance itself. Rather, updates should happen
+at the LDAP server level.
+
+Credential checks are _always_ done against the LDAP server.
+
+.. Note::
+
+  There are currently two ldap source types: the older `ldapuser` and
+  the newer `ldapfeed`. The older will be deprecated anytime soon, as
+  the newer has now gained all the features of the old and does not
+  suffer from some of its illnesses.
+
+  The ldapfeed creates real `CWUser` entities, and then
+  activate/deactivate them depending on their presence/absence in the
+  corresponding LDAP source. Their attribute and state
+  (activated/deactivated) are hence managed by the source mechanism;
+  they should not be altered by other means (as such alterations may
+  be overridden in some subsequent source synchronisation).
+
+
+Configuration of an LDAPfeed source
+-----------------------------------
+
+Additional sources are created at cube creation time or later through the
+user interface.
+
+Configure an `ldapfeed` source from the user interface under `Manage` then
+`data sources`:
+
+* At this point `type` has been set to `ldapfeed`.
+
+* The `parser` attribute shall be set to `ldapfeed`.
+
+* The `url` attribute shall be set to an URL such as ldap://ldapserver.domain/.
+
+* The `configuration` attribute contains many options. They are described in
+  detail in the next paragraph.
+
+
+Options of an LDAPfeed source
+-----------------------------
+
+Let us enumerate the options by categories (LDAP server connection,
+LDAP schema mapping information).
+
+LDAP server connection options:
+
+* `auth-mode`, (choices are simple, cram_md5, digest_md5, gssapi, support
+  for the later being partial as of now)
+
+* `auth-realm`, realm to use when using gssapi/kerberos authentication
+
+* `data-cnx-dn`, user dn to use to open data connection to the ldap (eg
+  used to respond to rql queries)
+
+* `data-cnx-password`, password to use to open data connection to the
+  ldap (eg used to respond to rql queries)
+
+If the LDAP server accepts anonymous binds, then it is possible to
+leave data-cnx-dn and data-cnx-password empty. This is, however, quite
+unlikely in practice. Beware that the LDAP server might hide attributes
+such as "userPassword" while the rest of the attributes remain visible
+through an anonymous binding.
+
+LDAP schema mapping options:
+
+* `user-base-dn`, base DN to lookup for users
+
+* `user-scope`, user search scope (valid values: "BASE", "ONELEVEL",
+  "SUBTREE")
+
+* `user-classes`, classes of user (with Active Directory, you want to
+  say "user" here)
+
+* `user-filter`, additional filters to be set in the ldap query to
+  find valid users
+
+* `user-login-attr`, attribute used as login on authentication (with
+  Active Directory, you want to use "sAMAccountName" here)
+
+* `user-default-group`, name of a group in which ldap users will be by
+  default. You can set multiple groups by separating them by a comma
+
+* `user-attrs-map`, map from ldap user attributes to cubicweb
+  attributes (with Active Directory, you want to use
+  sAMAccountName:login,mail:email,givenName:firstname,sn:surname)
+
+
+Other notes
+-----------
+
+* Cubicweb is able to start if ldap cannot be reached, even on
+  cubicweb-ctl start ... If some source ldap server cannot be used
+  while an instance is running, the corresponding users won't be
+  authenticated but their status will not change (e.g. they will not
+  be deactivated)
+
+* The user-base-dn is a key that helps cubicweb map CWUsers to LDAP
+  users: beware updating it
+
+* When a user is removed from an LDAP source, it is deactivated in the
+  CubicWeb instance; when a deactivated user comes back in the LDAP
+  source, it (automatically) is activated again
+
+* You can use the :class:`CWSourceHostConfig` to have variants for a source
+  configuration according to the host the instance is running on. To do so
+  go on the source's view from the sources management view.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/migration.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,38 @@
+.. -*- coding: utf-8 -*-
+
+Migrating cubicweb instances - benefits from a distributed architecture
+=======================================================================
+
+Migrate apache & cubicweb
+-------------------------
+
+**Aim** : do the migration for N cubicweb instances hosted on a server to another with no downtime.
+
+**Prerequisites** : have an explicit definition of the database host (not default or localhost). In our case, the database is hosted on another host.
+
+**Steps** :
+
+1. *on new machine* : install your environment (*pseudocode*) ::
+
+     apt-get install cubicweb cubicweb-applications apache2
+
+2. *on old machine* : copy your cubicweb and apache configuration to the new machine ::
+
+    scp /etc/cubicweb.d/ newmachine:/etc/cubicweb.d/
+    scp /etc/apache2/sites-available/ newmachine:/etc/apache2/sites-available/
+
+3. *on new machine* : start your instances ::
+
+     cubicweb start
+
+4. *on new machine* : enable sites and modules for apache and start it, test it using by modifying your /etc/host file.
+
+5. change dns entry from your oldmachine to newmachine
+
+6. shutdown your *old machine* (if it doesn't host other services or your database)
+
+7. That's it.
+
+**Possible enhancements** : use right from the start a pound server behind your apache, that way you can add backends and smoothily migrate by shuting down backends that pound will take into account.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/multisources.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,6 @@
+Multiple sources of data
+========================
+
+Data sources include SQL, LDAP, RQL, mercurial and subversion.
+
+.. XXX feed me
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/pyro.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,62 @@
+.. _UsingPyro:
+
+Working with a distributed client (using Pyro)
+==============================================
+
+In some circumstances, it is practical to split the repository and
+web-client parts of the application for load-balancing reasons. Or
+one wants to access the repository from independant scripts to consult
+or update the database.
+
+Prerequisites
+-------------
+
+For this to work, several steps have to be taken in order.
+
+You must first ensure that the appropriate software is installed and
+running (see :ref:`ConfigEnv`)::
+
+  pyro-nsd -x -p 6969
+
+Then you have to set appropriate options in your configuration. For
+instance::
+
+  pyro-server=yes
+  pyro-ns-host=localhost:6969
+
+  pyro-instance-id=myinstancename
+
+Connect to the CubicWeb repository from a python script
+-------------------------------------------------------
+
+Assuming pyro-nsd is running and your instance is configured with ``pyro-server=yes``,
+you will be able to use :mod:`cubicweb.dbapi` api to initiate the connection.
+
+.. note::
+    Regardless of whether your instance is pyro activated or not, you can still
+    achieve this by using cubicweb-ctl shell scripts in a simpler way, as by default
+    it creates a repository 'in-memory' instead of connecting through pyro. That
+    also means you've to be on the host where the instance is running.
+
+Finally, the client (for instance a python script) must connect specifically
+as in the following example code:
+
+.. sourcecode:: python
+
+    from cubicweb import dbapi
+
+    cnx = dbapi.connect(database='instance-id', user='admin', password='admin')
+    cnx.load_appobjects()
+    cur = cnx.cursor()
+    for name in (u'Personal', u'Professional', u'Computers'):
+        cur.execute('INSERT Tag T: T name %(n)s', {'n': name})
+    cnx.commit()
+
+Calling :meth:`cubicweb.dbapi.load_appobjects`, will populate the
+cubicweb registries (see :ref:`VRegistryIntro`) with the application
+objects installed on the host where the script runs. You'll then be
+allowed to use the ORM goodies and custom entity methods and views. Of
+course this is optional, without it you can still get the repository
+data through the connection but in a roughly way: only RQL cursors
+will be available, e.g. you can't even build entity objects from the
+result set.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/rql-logs.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,14 @@
+.. -*- coding: utf-8 -*-
+
+RQL logs
+========
+
+You can configure the *CubicWeb* instance to keep a log
+of the queries executed against your database. To do so,
+edit the configuration file of your instance
+``.../etc/cubicweb.d/myapp/all-in-one.conf`` and uncomment the
+variable ``query-log-file``::
+
+  # web instance query log file
+  query-log-file=/tmp/rql-myapp.log
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/setup-windows.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,146 @@
+.. -*- coding: utf-8 -*-
+
+.. _SetUpWindowsEnv:
+
+Installing a development environement on Windows
+================================================
+
+Setting up a Windows development environment is not too complicated
+but it requires a series of small steps.
+
+We propose an example of a typical |cubicweb| installation on Windows
+from sources. We assume everything goes into ``C:\\`` and for any
+package, without version specification, "the latest is
+the greatest".
+
+Mind that adjusting the installation drive should be straightforward.
+
+
+
+Install the required elements
+-----------------------------
+
+|cubicweb| requires some base elements that must be installed to run
+correctly. So, first of all, you must install them :
+
+* python >= 2.6 and < 3
+  (`Download Python <http://www.python.org/download/>`_).
+  You can also consider the Python(x,y) distribution
+  (`Download Python(x,y) <http://code.google.com/p/pythonxy/wiki/Downloads>`_)
+  as it makes things easier for Windows user by wrapping in a single installer
+  python 2.7 plus numerous useful third-party modules and
+  applications (including Eclipse + pydev, which is an arguably good
+  IDE for Python under Windows).
+
+* `Twisted <http://twistedmatrix.com/trac/>`_ is an event-driven
+  networking engine
+  (`Download Twisted <http://twistedmatrix.com/trac/>`_)
+
+* `lxml <http://codespeak.net/lxml/>`_ library
+  (version >=2.2.1) allows working with XML and HTML
+  (`Download lxml <http://pypi.python.org/pypi/lxml/2.2.1>`_)
+
+* `Postgresql <http://www.postgresql.org/>`_,
+  an object-relational database system
+  (`Download Postgresql <http://www.enterprisedb.com/products/pgdownload.do#windows>`_)
+  and its python drivers
+  (`Download psycopg <http://www.stickpeople.com/projects/python/win-psycopg/#Version2>`_)
+
+* A recent version of `gettext`
+  (`Download gettext <http://download.logilab.org/pub/gettext/gettext-0.17-win32-setup.exe>`_).
+
+* `rql <http://www.logilab.org/project/rql>`_,
+  the recent version of the Relationship Query Language parser.
+
+Install optional elements
+-------------------------
+
+We recommend you to install the following elements. They are not
+mandatory but they activate very interesting features in |cubicweb|:
+
+* `python-ldap <http://pypi.python.org/pypi/python-ldap>`_
+  provides access to LDAP/Active directory directories
+  (`Download python-ldap <http://www.osuch.org/python-ldap>`_).
+
+* `graphviz <http://www.graphviz.org/>`_
+  which allow schema drawings.
+  (`Download graphviz <http://www.graphviz.org/Download_windows.php>`_).
+  It is quite recommended (albeit not mandatory).
+
+Other elements will activate more features once installed. Take a look
+at :ref:`InstallDependencies`.
+
+Useful tools
+------------
+
+Some additional tools could be useful to develop :ref:`cubes <AvailableCubes>`
+with the framework.
+
+* `mercurial <http://mercurial.selenic.com/>`_ and its standard windows GUI
+  (`TortoiseHG <http://tortoisehg.bitbucket.org/>`_) allow you to get the source
+  code of |cubicweb| from control version repositories. So you will be able to
+  get the latest development version and pre-release bugfixes in an easy way
+  (`Download mercurial <http://bitbucket.org/tortoisehg/stable/wiki/download>`_).
+
+* You can also consider the ssh client `Putty` in order to peruse
+  mercurial over ssh (`Download <http://www.putty.org/>`_).
+
+* If you are an Eclipse user, mercurial can be integrated using the
+  `MercurialEclipse` plugin
+  (`Home page <http://www.vectrace.com/mercurialeclipse/>`_).
+
+Getting the sources
+-------------------
+
+There are two ways to get the sources of |cubicweb| and its
+:ref:`cubes <AvailableCubes>`:
+
+* download the latest release (:ref:`SourceInstallation`)
+* get the development version using Mercurial
+  (:ref:`MercurialInstallation`)
+
+Environment variables
+---------------------
+
+You will need some convenience environment variables once all is set up. These
+variables are settable through the GUI by getting at the `System properties`
+window (by righ-clicking on `My Computer` -> `properties`).
+
+In the `advanced` tab, there is an `Environment variables` button. Click on
+it. That opens a small window allowing edition of user-related and system-wide
+variables.
+
+We will consider only user variables. First, the ``PATH`` variable. Assuming
+you are logged as user *Jane*, add the following paths, separated by
+semi-colons::
+
+  C:\Documents and Settings\Jane\My Documents\Python\cubicweb\cubicweb\bin
+  C:\Program Files\Graphviz2.24\bin
+
+The ``PYTHONPATH`` variable should also contain::
+
+  C:\Documents and Settings\Jane\My Documents\Python\cubicweb\
+
+From now, on a fresh `cmd` shell, you should be able to type::
+
+  cubicweb-ctl list
+
+... and get a meaningful output.
+
+Running an instance as a service
+--------------------------------
+
+This currently assumes that the instances configurations is located at
+``C:\\etc\\cubicweb.d``. For a cube 'my_instance', you will find
+``C:\\etc\\cubicweb.d\\my_instance\\win32svc.py``.
+
+Now, register your instance as a windows service with::
+
+  win32svc install
+
+Then start the service with::
+
+  net start cubicweb-my_instance
+
+In case this does not work, you should be able to see error reports in
+the application log, using the windows event log viewer.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/setup.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,269 @@
+.. -*- coding: utf-8 -*-
+
+.. _SetUpEnv:
+
+Installation of a *CubicWeb* environment
+========================================
+
+Official releases are available from the `CubicWeb.org forge`_ and from
+`PyPI`_. Since CubicWeb is developed using `Agile software development
+<http://en.wikipedia.org/wiki/Agile_software_development>`_ techniques, releases
+happen frequently. In a version numbered X.Y.Z, X changes after a few years when
+the API breaks, Y changes after a few weeks when features are added and Z
+changes after a few days when bugs are fixed.
+
+Depending on your needs, you will chose a different way to install CubicWeb on
+your system:
+
+- `Installation on Debian/Ubuntu`_
+- `Installation on Windows`_
+- `Installation in a virtualenv`_
+- `Installation with pip`_
+- `Installation with easy_install`_
+- `Installation from tarball`_
+
+If you are a power-user and need the very latest features, you will
+
+- `Install from version control`_
+
+Once the software is installed, move on to :ref:`ConfigEnv` for better control
+and advanced features of |cubicweb|.
+
+.. _`Installation on Debian/Ubuntu`: DebianInstallation_
+.. _`Installation on Windows`: WindowsInstallation_
+.. _`Installation in a virtualenv`: VirtualenvInstallation_
+.. _`Installation with pip`: PipInstallation_
+.. _`Installation with easy_install`: EasyInstallInstallation_
+.. _`Installation from tarball`: TarballInstallation_
+.. _`Install from version control`: MercurialInstallation_
+
+
+.. _DebianInstallation:
+
+Debian/Ubuntu install
+---------------------
+
+|cubicweb| is packaged for Debian/Ubuntu (and derived
+distributions). Their integrated package-management system make
+installation and upgrade much easier for users since
+dependencies (like databases) are automatically installed.
+
+Depending on the distribution you are using, add the appropriate line to your
+`list of sources` (for example by editing ``/etc/apt/sources.list``).
+
+For Debian 7.0 Wheezy (stable)::
+
+  deb http://download.logilab.org/production/ wheezy/
+
+For Debian Sid (unstable)::
+
+  deb http://download.logilab.org/production/ sid/
+
+For Ubuntu 12.04 Precise Pangolin (Long Term Support) and newer::
+
+  deb http://download.logilab.org/production/ precise/
+
+The repositories are signed with the `Logilab's gnupg key`_. You can download
+and register the key to avoid warnings::
+
+  wget -q http://download.logilab.org/logilab-dists-key.asc -O- | sudo apt-key add -
+
+Update your list of packages and perform the installation::
+
+  apt-get update
+  apt-get install cubicweb cubicweb-dev
+
+``cubicweb`` installs the framework itself, allowing you to create new
+instances. ``cubicweb-dev`` installs the development environment
+allowing you to develop new cubes.
+
+There is also a wide variety of :ref:`cubes <AvailableCubes>`. You can access a
+list of available cubes using ``apt-cache search cubicweb`` or at the
+`CubicWeb.org forge`_.
+
+.. note::
+
+  `cubicweb-dev` will install basic sqlite support. You can easily setup
+  :ref:`cubicweb with other database <DatabaseInstallation>` using the following
+  virtual packages :
+
+  * `cubicweb-postgresql-support` contains the necessary dependencies for
+    using :ref:`cubicweb with postgresql datatabase <PostgresqlConfiguration>`
+
+  * `cubicweb-mysql-support` contains the necessary dependencies for using
+    :ref:`cubicweb with mysql database <MySqlConfiguration>`.
+
+.. _`list of sources`: http://wiki.debian.org/SourcesList
+.. _`Logilab's gnupg key`: http://download.logilab.org/logilab-dists-key.asc
+.. _`CubicWeb.org Forge`: http://www.cubicweb.org/project/
+
+.. _WindowsInstallation:
+
+Windows Install
+---------------
+
+You need to have `python`_ version >= 2.5 and < 3 installed.
+
+If you want an automated install, your best option is probably the
+:ref:`EasyInstallInstallation`. EasyInstall is a tool that helps users to
+install python packages along with their dependencies, searching for suitable
+pre-compiled binaries on the `The Python Package Index`_.
+
+If you want better control over the process as well as a suitable development
+environment or if you are having problems with `easy_install`, read on to
+:ref:`SetUpWindowsEnv`.
+
+.. _python:  http://www.python.org/
+.. _`The Python Package Index`: http://pypi.python.org
+
+.. _VirtualenvInstallation:
+
+`Virtualenv` install
+--------------------
+
+|cubicweb| can be safely installed, used and contained inside a
+`virtualenv`_. You can use either :ref:`pip <PipInstallation>` or
+:ref:`easy_install <EasyInstallInstallation>` to install |cubicweb|
+inside an activated virtual environment.
+
+.. _PipInstallation:
+
+`pip` install
+-------------
+
+`pip <http://pip.openplans.org/>`_ is a python tool that helps downloading,
+building, installing, and managing Python packages and their dependencies. It
+is fully compatible with `virtualenv`_ and installs the packages from sources
+published on the `The Python Package Index`_.
+
+.. _`virtualenv`: http://virtualenv.openplans.org/
+
+A working compilation chain is needed to build the modules that include C
+extensions. If you really do not want to compile anything, installing `lxml <http://lxml.de/>`_,
+`Twisted Web <http://twistedmatrix.com/trac/wiki/Downloads/>`_ and `libgecode
+<http://www.gecode.org/>`_ will help.
+
+For Debian, these minimal dependencies can be obtained by doing::
+
+  apt-get install gcc python-pip python-dev python-lxml
+
+or, if you prefer to get as much as possible from pip::
+
+  apt-get install gcc python-pip python-dev libxslt1-dev libxml2-dev
+
+For Windows, you can install pre-built packages (possible `source
+<http://www.lfd.uci.edu/~gohlke/pythonlibs/>`_). For a minimal setup, install:
+
+- pip http://www.lfd.uci.edu/~gohlke/pythonlibs/#pip
+- setuptools http://www.lfd.uci.edu/~gohlke/pythonlibs/#setuptools
+- libxml-python http://www.lfd.uci.edu/~gohlke/pythonlibs/#libxml-python>
+- lxml http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml and
+- twisted http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
+
+Make sure to choose the correct architecture and version of Python.
+
+Finally, install |cubicweb| and its dependencies, by running::
+
+  pip install cubicweb
+
+Many other :ref:`cubes <AvailableCubes>` are available. A list is available at
+`PyPI <http://pypi.python.org/pypi?%3Aaction=search&term=cubicweb&submit=search>`_
+or at the `CubicWeb.org forge`_.
+
+For example, installing the *blog cube* is achieved by::
+
+  pip install cubicweb-blog
+
+.. _EasyInstallInstallation:
+
+`easy_install` install
+----------------------
+
+.. note::
+
+   If you are not a Windows user and you have a compilation environment, we
+   recommend you to use the PipInstallation_.
+
+`easy_install`_ is a python utility that helps downloading, installing, and
+managing python packages and their dependencies.
+
+Install |cubicweb| and its dependencies, run::
+
+  easy_install cubicweb
+
+There is also a wide variety of :ref:`cubes <AvailableCubes>`. You can access a
+list of available cubes on `PyPI
+<http://pypi.python.org/pypi?%3Aaction=search&term=cubicweb&submit=search>`_
+or at the `CubicWeb.org Forge`_.
+
+For example, installing the *blog cube* is achieved by::
+
+  easy_install cubicweb-blog
+
+.. note::
+
+  If you encounter problem with :ref:`cubes <AvailableCubes>` installation,
+  consider using :ref:`PipInstallation` which is more stable
+  but can not installed pre-compiled binaries.
+
+.. _`easy_install`: http://packages.python.org/distribute/easy_install.html
+
+
+.. _SourceInstallation:
+
+Install from source
+-------------------
+
+.. _TarballInstallation:
+
+You can download the archive containing the sources from
+`http://download.logilab.org/pub/cubicweb/ <http://download.logilab.org/pub/cubicweb/>`_.
+
+Make sure you also have all the :ref:`InstallDependencies`.
+
+Once uncompressed, you can install the framework from inside the uncompressed
+folder with::
+
+  python setup.py install
+
+Or you can run |cubicweb| directly from the source directory by
+setting the :ref:`resource mode <RessourcesConfiguration>` to `user`. This will
+ease the development with the framework.
+
+There is also a wide variety of :ref:`cubes <AvailableCubes>`. You can access a
+list of availble cubes at the `CubicWeb.org Forge`_.
+
+
+.. _MercurialInstallation:
+
+Install from version control system
+-----------------------------------
+
+To keep-up with on-going development, clone the :ref:`Mercurial
+<MercurialPresentation>` repository::
+
+  hg clone -u stable http://hg.logilab.org/cubicweb # stable branch
+  hg clone http://hg.logilab.org/cubicweb # development branch
+
+To get many of CubicWeb's dependencies and a nice set of base cubes, run the
+`clone_deps.py` script located in `cubicweb/bin/`::
+
+  python cubicweb/bin/clone_deps.py
+
+(Windows users should replace slashes with antislashes).
+
+This script will clone a set of mercurial repositories into the
+directory containing the ``cubicweb`` repository, and update them to the
+latest published version tag (if any).
+
+.. note::
+
+  In every cloned repositories, a `hg tags` will display a list of
+  tags in reverse chronological order. One reasonnable option is to go to a
+  tagged version: the latest published version or example, as done by
+  the `clone_deps` script)::
+
+   hg update cubicweb-version-3.12.2
+
+Make sure you also have all the :ref:`InstallDependencies`.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/admin/site-config.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,94 @@
+.. -*- coding: utf-8 -*-
+
+User interface for web site configuration
+=========================================
+
+.. image:: ../images/lax-book_03-site-config-panel_en.png
+
+This panel allows you to configure the appearance of your instance 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 instance 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
+instance 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 instance 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/annexes/depends.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,58 @@
+.. -*- coding: utf-8 -*-
+
+.. _InstallDependencies:
+
+Installation dependencies
+=========================
+
+When you run CubicWeb from source, either by downloading the tarball or
+cloning the mercurial tree, here is the list of tools and libraries you need
+to have installed in order for CubicWeb to work:
+
+* yapps - http://theory.stanford.edu/~amitp/yapps/ -
+  http://pypi.python.org/pypi/Yapps2
+
+* pygraphviz - http://networkx.lanl.gov/pygraphviz/ -
+  http://pypi.python.org/pypi/pygraphviz
+
+* docutils - http://docutils.sourceforge.net/ - http://pypi.python.org/pypi/docutils
+
+* lxml - http://codespeak.net/lxml - http://pypi.python.org/pypi/lxml
+
+* twisted - http://twistedmatrix.com/ - http://pypi.python.org/pypi/Twisted
+
+* logilab-common - http://www.logilab.org/project/logilab-common -
+  http://pypi.python.org/pypi/logilab-common/
+
+* logilab-database - http://www.logilab.org/project/logilab-database -
+  http://pypi.python.org/pypi/logilab-database/
+
+* logilab-constraint - http://www.logilab.org/project/logilab-constraint -
+  http://pypi.python.org/pypi/constraint/
+
+* logilab-mtconverter - http://www.logilab.org/project/logilab-mtconverter -
+  http://pypi.python.org/pypi/logilab-mtconverter
+
+* rql - http://www.logilab.org/project/rql - http://pypi.python.org/pypi/rql
+
+* yams - http://www.logilab.org/project/yams - http://pypi.python.org/pypi/yams
+
+* indexer - http://www.logilab.org/project/indexer -
+  http://pypi.python.org/pypi/indexer
+
+* passlib - https://code.google.com/p/passlib/ -
+  http://pypi.python.org/pypi/passlib
+
+If you're using a Postgresql database (recommended):
+
+* psycopg2 - http://initd.org/projects/psycopg2 - http://pypi.python.org/pypi/psycopg2
+* plpythonu extension
+
+Other optional packages:
+
+* fyzz - http://www.logilab.org/project/fyzz -
+  http://pypi.python.org/pypi/fyzz *to activate Sparql querying*
+
+
+Any help with the packaging of CubicWeb for more than Debian/Ubuntu (including
+eggs, buildouts, etc) will be greatly appreciated.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/docstrings-conventions.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,106 @@
+Javascript docstrings
+=====================
+
+Whereas in Python source code we only need to include a module docstrings
+using the directive `.. automodule:: mypythonmodule`, we will have to
+explicitely define Javascript modules and functions in the doctrings since
+there is no native directive to include Javascript files.
+
+Rest generation
+---------------
+
+`pyjsrest` is a small utility parsing Javascript doctrings and generating the
+corresponding Restructured file used by Sphinx to generate HTML documentation.
+This script will have the following structure::
+
+  ===========
+  filename.js
+  ===========
+  .. module:: filename.js
+
+We use the `.. module::` directive to register a javascript library
+as a Python module for Sphinx. This provides an entry in the module index.
+
+The contents of the docstring found in the javascript file will be added as is
+following the module declaration. No treatment will be done on the doctring.
+All the documentation structure will be in the docstrings and will comply
+with the following rules.
+
+Docstring structure
+-------------------
+
+Basically we document javascript with RestructuredText docstring
+following the same convention as documenting Python code.
+
+The doctring in Javascript files must be contained in standard
+Javascript comment signs, starting with `/**` and ending with `*/`,
+such as::
+
+ /**
+  * My comment starts here.
+  * This is the second line prefixed with a `*`.
+  * ...
+  * ...
+  * All the follwing line will be prefixed with a `*` followed by a space.
+  * ...
+  * ...
+  */
+
+
+Comments line prefixed by `//` will be ignored. They are reserved for source
+code comments dedicated to developers.
+
+
+Javscript functions docstring
+-----------------------------
+
+By default, the `function` directive describes a module-level function.
+
+`function` directive
+~~~~~~~~~~~~~~~~~~~~
+
+Its purpose is to define the function prototype such as::
+
+    .. function:: loadxhtml(url, data, reqtype, mode)
+
+If any namespace is used, we should add it in the prototype for now,
+until we define an appropriate directive::
+
+    .. function:: jQuery.fn.loadxhtml(url, data, reqtype, mode)
+
+Function parameters
+~~~~~~~~~~~~~~~~~~~
+
+We will define function parameters as a bulleted list, where the
+parameter name will be backquoted and followed by its description.
+
+Example of a javascript function docstring::
+
+    .. function:: loadxhtml(url, data, reqtype, mode)
+
+    cubicweb loadxhtml plugin to make jquery handle xhtml response
+
+    fetches `url` and replaces this's content with the result
+
+    Its arguments are:
+
+    * `url`
+
+    * `mode`, how the replacement should be done (default is 'replace')
+       Possible values are :
+           - 'replace' to replace the node's content with the generated HTML
+           - 'swap' to replace the node itself with the generated HTML
+           - 'append' to append the generated HTML to the node's content
+
+
+Optional parameter specification
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Javascript functions handle arguments not listed in the function signature.
+In the javascript code, they will be flagged using `/* ... */`. In the docstring,
+we flag those optional arguments the same way we would define it in
+Python::
+
+    .. function:: asyncRemoteExec(fname, arg1=None, arg2=None)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/faq.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,437 @@
+.. -*- coding: utf-8 -*-
+
+Frequently Asked Questions (FAQ)
+================================
+
+
+Generalities
+````````````
+
+Why do you use the LGPL license to prevent me from doing X ?
+------------------------------------------------------------
+
+LGPL means that *if* you redistribute your application, you need to
+redistribute the changes you made to CubicWeb under the LGPL licence.
+
+Publishing a web site has nothing to do with redistributing source
+code according to the terms of the LGPL. A fair amount of companies
+use modified LGPL code for internal use. And someone could publish a
+*CubicWeb* component under a BSD licence for others to plug into a
+LGPL framework without any problem. The only thing we are trying to
+prevent here is someone taking the framework and packaging it as
+closed source to his own clients.
+
+Why does not CubicWeb have a template language ?
+------------------------------------------------
+
+There are enough template languages out there. You can use your
+preferred template language if you want. [explain how to use a
+template language]
+
+*CubicWeb* does not define its own templating language as this was
+not our goal. Based on our experience, we realized that
+we could gain productivity by letting designers use design tools
+and developpers develop without the use of the templating language
+as an intermediary that could not be anyway efficient for both parties.
+Python is the templating language that we use in *CubicWeb*, but again,
+it does not prevent you from using a templating language.
+
+Moreover, CubicWeb currently supports `simpletal`_ out of the box and
+it is also possible to use the `cwtags`_ library to build html trees
+using the `with statement`_ with more comfort than raw strings.
+
+.. _`simpletal`: http://www.owlfish.com/software/simpleTAL/
+.. _`cwtags`: http://www.cubicweb.org/project/cwtags
+.. _`with statement`: http://www.python.org/dev/peps/pep-0343/
+
+Why do you think using pure python is better than using a template language ?
+-----------------------------------------------------------------------------
+
+Python is an Object Oriented Programming language and as such it
+already provides a consistent and strong architecture and syntax
+a templating language would not reach.
+
+Using Python instead of a template langage for describing the user interface
+makes it to maintain with real functions/classes/contexts without the need of
+learning a new dialect. By using Python, we use standard OOP techniques and
+this is a key factor in a robust application.
+
+CubicWeb looks pretty recent. Is it stable ?
+--------------------------------------------
+
+It is constantly evolving, piece by piece.  The framework has evolved since
+2001 and data has been migrated from one schema to the other ever since. There
+is a well-defined way to handle data and schema migration.
+
+You can see the roadmap there:
+http://www.cubicweb.org/project/cubicweb?tab=projectroadmap_tab.
+
+
+Why is the RQL query language looking similar to X ?
+----------------------------------------------------
+
+It may remind you of SQL but it is higher level than SQL, more like
+SPARQL. Except that SPARQL did not exist when we started the project.
+With version 3.4, CubicWeb has support for SPARQL.
+
+The RQL language is what is going to make a difference with django-
+like frameworks for several reasons.
+
+1. accessing data is *much* easier with it. One can write complex
+   queries with RQL that would be tedious to define and hard to maintain
+   using an object/filter suite of method calls.
+
+2. it offers an abstraction layer allowing your applications to run
+   on multiple back-ends. That means not only various SQL backends
+   (postgresql, sqlite, sqlserver, mysql), but also non-SQL data stores like
+   LDAP directories and subversion/mercurial repositories (see the `vcsfile`
+   component).
+
+Which ajax library is CubicWeb using ?
+--------------------------------------
+
+CubicWeb uses jQuery_ and provides a few helpers on top of that. Additionally,
+some jQuery plugins are provided (some are provided in specific cubes).
+
+.. _jQuery: http://jquery.com
+
+
+Development
+```````````
+
+How to change the instance logo ?
+---------------------------------
+
+The logo is managed by css. You must provide a custom css that will contain
+the code below: 
+
+::
+   
+     #logo {
+        background-image: url("logo.jpg");
+     }
+
+
+``logo.jpg`` is in ``mycube/data`` directory.
+
+How to create an anonymous user ?
+---------------------------------
+
+This allows to browse the site without being authenticated. In the
+``all-in-one.conf`` file of your instance, define the anonymous user
+as follows ::
+
+  # login of the CubicWeb user account to use for anonymous user (if you want to
+  # allow anonymous)
+  anonymous-user=anon
+
+  # password of the CubicWeb user account matching login
+  anonymous-password=anon
+
+You also must ensure that this `anon` user is a registered user of
+the DB backend. If not, you can create through the administation
+interface of your instance by adding a user with in the group `guests`.
+
+.. note::
+    While creating a new instance, you can decide to allow access
+    to anonymous user, which will automatically execute what is
+    decribed above.
+
+How to load data from a python script ?
+---------------------------------------
+Please, refer to :ref:`UsingPyro`.
+
+
+How to format an entity date attribute ?
+----------------------------------------
+
+If your schema has an attribute of type `Date` or `Datetime`, you usually want to
+format it when displaying it. First, you should define your preferred format
+using the site configuration panel
+``http://appurl/view?vid=systempropertiesform`` and then set ``ui.date`` and/or
+``ui.datetime``.  Then in the view code, use:
+
+.. sourcecode:: python
+
+    entity.printable_value(date_attribute)
+
+which will always return a string whatever the attribute's type (so it's
+recommended also for other attribute types). By default it expects to generate
+HTML, so it deals with rich text formating, xml escaping...
+
+How to update a database after a schema modification ?
+------------------------------------------------------
+
+It depends on what has been modified in the schema.
+
+* update the permissions and properties of an entity or a relation:
+  ``sync_schema_props_perms('MyEntityOrRelation')``.
+
+* add an attribute: ``add_attribute('MyEntityType', 'myattr')``.
+
+* add a relation: ``add_relation_definition('SubjRelation', 'MyRelation', 'ObjRelation')``.
+
+I get `NoSelectableObject` exceptions, how do I debug selectors ?
+-----------------------------------------------------------------
+
+You just need to put the appropriate context manager around view/component
+selection. One standard place for components is in cubicweb/vregistry.py: 
+
+.. sourcecode:: python
+
+    def possible_objects(self, *args, **kwargs):
+        """return an iterator on possible objects in this registry for the given
+        context
+        """
+        from logilab.common.registry import traced_selection
+        with traced_selection():
+            for appobjects in self.itervalues():
+                try:
+                    yield self._select_best(appobjects, *args, **kwargs)
+                except NoSelectableObject:
+                    continue
+
+This will yield additional WARNINGs, like this::
+
+    2009-01-09 16:43:52 - (cubicweb.selectors) WARNING: selector one_line_rset returned 0 for <class 'cubicweb.web.views.basecomponents.WFHistoryVComponent'>
+
+For views, you can put this context in `cubicweb/web/views/basecontrollers.py` in
+the `ViewController`:
+
+.. sourcecode:: python
+
+    def _select_view_and_rset(self, rset):
+        ...
+        try:
+            from logilab.common.registry import traced_selection
+            with traced_selection():
+                view = self._cw.vreg['views'].select(vid, req, rset=rset)
+        except ObjectNotFound:
+            self.warning("the view %s could not be found", vid)
+            req.set_message(req._("The view %s could not be found") % vid)
+            vid = vid_from_rset(req, rset, self._cw.vreg.schema)
+            view = self._cw.vreg['views'].select(vid, req, rset=rset)
+        ...
+
+I get "database is locked" when executing tests
+-----------------------------------------------
+
+If you have "database is locked" as error when you are executing security tests,
+it is usually because commit or rollback are missing before login() calls.
+
+You can also use a context manager, to avoid such errors, as described
+here: :ref:`securitytest`.
+
+
+What are hooks used for ?
+-------------------------
+
+Hooks are executed around (actually before or after) events.  The most common
+events are data creation, update and deletion.  They permit additional constraint
+checking (those not expressible at the schema level), pre and post computations
+depending on data movements.
+
+As such, they are a vital part of the framework.
+
+Other kinds of hooks, called Operations, are available
+for execution just before commit.
+
+For more information, read :ref:`hooks` section.
+
+
+Configuration
+`````````````
+
+How to configure a LDAP source ?
+--------------------------------
+
+See :ref:`LDAP`.
+
+How to import LDAP users in |cubicweb| ?
+----------------------------------------
+
+  Here is a useful script which enables you to import LDAP users
+  into your *CubicWeb* instance by running the following:
+
+.. sourcecode:: python
+
+    import os
+    import pwd
+    import sys
+
+    from logilab.database import get_connection
+
+    def getlogin():
+        """avoid using os.getlogin() because of strange tty/stdin problems
+        (man 3 getlogin)
+        Another solution would be to use $LOGNAME, $USER or $USERNAME
+        """
+        return pwd.getpwuid(os.getuid())[0]
+
+
+    try:
+        database = sys.argv[1]
+    except IndexError:
+        print 'USAGE: python ldap2system.py <database>'
+        sys.exit(1)
+
+    if raw_input('update %s db ? [y/n]: ' % database).strip().lower().startswith('y'):
+        cnx = get_connection(user=getlogin(), database=database)
+        cursor = cnx.cursor()
+
+        insert = ('INSERT INTO euser (creation_date, eid, modification_date, login, '
+                  ' firstname, surname, last_login_time, upassword) '
+                  "VALUES (%(mtime)s, %(eid)s, %(mtime)s, %(login)s, %(firstname)s, "
+                  "%(surname)s, %(mtime)s, './fqEz5LeZnT6');")
+        update = "UPDATE entities SET source='system' WHERE eid=%(eid)s;"
+        cursor.execute("SELECT eid,type,source,extid,mtime FROM entities WHERE source!='system'")
+        for eid, type, source, extid, mtime in cursor.fetchall():
+            if type != 'CWUser':
+                print "don't know what to do with entity type", type
+                continue
+            if source != 'ldapuser':
+                print "don't know what to do with source type", source
+                continue
+            ldapinfos = dict(x.strip().split('=') for x in extid.split(','))
+            login = ldapinfos['uid']
+            firstname = ldapinfos['uid'][0].upper()
+            surname = ldapinfos['uid'][1:].capitalize()
+            if login != 'jcuissinat':
+                args = dict(eid=eid, type=type, source=source, login=login,
+                            firstname=firstname, surname=surname, mtime=mtime)
+                print args
+                cursor.execute(insert, args)
+                cursor.execute(update, args)
+
+        cnx.commit()
+        cnx.close()
+
+
+Security
+````````
+
+How to reset the password for user joe ?
+----------------------------------------
+
+If you want to reset the admin password for ``myinstance``, do::
+
+    $ cubicweb-ctl reset-admin-pwd myinstance
+
+You need to generate a new encrypted password::
+
+    $ python
+    >>> from cubicweb.server.utils import crypt_password
+    >>> crypt_password('joepass')
+    'qHO8282QN5Utg'
+    >>>
+
+and paste it in the database::
+
+    $ psql mydb
+    mydb=> update cw_cwuser set cw_upassword='qHO8282QN5Utg' where cw_login='joe';
+    UPDATE 1
+
+if you're running over SQL Server, you need to use the CONVERT
+function to convert the string to varbinary(255). The SQL query is
+therefore::
+
+    update cw_cwuser set cw_upassword=CONVERT(varbinary(255), 'qHO8282QN5Utg') where cw_login='joe';
+
+Be careful, the encryption algorithm is different on Windows and on
+Unix. You cannot therefore use a hash generated on Unix to fill in a
+Windows database, nor the other way round.
+
+
+You can prefer use a migration script similar to this shell invocation instead::
+
+    $ cubicweb-ctl shell <instance>
+    >>> from cubicweb import Binary
+    >>> from cubicweb.server.utils import crypt_password
+    >>> crypted = crypt_password('joepass')
+    >>> rset = rql('Any U WHERE U is CWUser, U login "joe"')
+    >>> joe = rset.get_entity(0,0)
+    >>> joe.cw_set(upassword=Binary(crypted))
+
+Please, refer to the script example is provided in the `misc/examples/chpasswd.py` file.
+
+The more experimented people would use RQL request directly::
+
+    >>> rql('SET X upassword %(a)s WHERE X is CWUser, X login "joe"',
+    ...     {'a': crypted})
+
+I've just created a user in a group and it doesn't work !
+---------------------------------------------------------
+
+You are probably getting errors such as ::
+
+  remove {'PR': 'Project', 'C': 'CWUser'} from solutions since your_user has no read access to cost
+
+This is because you have to put your user in the "users" group. The user has to
+be in both groups.
+
+How is security implemented ?
+------------------------------
+
+The basis for security is a mapping from operations to groups or
+arbitrary RQL expressions. These mappings are scoped to entities and
+relations.
+
+This is an example for an Entity Type definition:
+
+.. sourcecode:: python
+
+    class Version(EntityType):
+        """a version is defining the content of a particular project's
+        release"""
+        # definition of attributes is voluntarily missing
+        __permissions__ = {'read': ('managers', 'users', 'guests',),
+                           'update': ('managers', 'logilab', 'owners'),
+                           'delete': ('managers',),
+                           'add': ('managers', 'logilab',
+                                   ERQLExpression('X version_of PROJ, U in_group G, '
+                                                  'PROJ require_permission P, '
+                                                  'P name "add_version", P require_group G'),)}
+
+The above means that permission to read a Version is granted to any
+user that is part of one of the groups 'managers', 'users', 'guests'.
+The 'add' permission is granted to users in group 'managers' or
+'logilab' or to users in group G, if G is linked by a permission
+entity named "add_version" to the version's project.
+
+An example for a Relation Definition (RelationType both defines a
+relation type and implicitly one relation definition, on which the
+permissions actually apply):
+
+.. sourcecode:: python
+
+    class version_of(RelationType):
+        """link a version to its project. A version is necessarily linked
+        to one and only one project. """
+        # some lines voluntarily missing
+        __permissions__ = {'read': ('managers', 'users', 'guests',),
+                           'delete': ('managers', ),
+                           'add': ('managers', 'logilab',
+                                   RRQLExpression('O require_permission P, P name "add_version", '
+                                                  'U in_group G, P require_group G'),) }
+
+The main difference lies in the basic available operations (there is
+no 'update' operation) and the usage of an RRQLExpression (rql
+expression for a relation) instead of an ERQLExpression (rql
+expression for an entity).
+
+You can find additional information in the section :ref:`securitymodel`.
+
+Is it possible to bypass security from the UI (web front) part ?
+----------------------------------------------------------------
+
+No. Only Hooks/Operations can do that.
+
+Can PostgreSQL and CubicWeb authentication work with kerberos ?
+----------------------------------------------------------------
+
+If you have PostgreSQL set up to accept kerberos authentication, you can set
+the db-host, db-name and db-user parameters in the `sources` configuration
+file while leaving the password blank. It should be enough for your
+instance to connect to postgresql with a kerberos ticket.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/index.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,19 @@
+.. -*- coding: utf-8 -*-
+
+.. _Part4:
+
+----------
+Appendixes
+----------
+
+The following chapters are reference material.
+
+.. toctree::
+   :maxdepth: 1
+   :numbered:
+
+   faq
+   rql/index
+   mercurial
+   depends
+   docstrings-conventions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/mercurial.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,131 @@
+.. -*- coding: utf-8 -*-
+
+.. _MercurialPresentation:
+
+Introducing Mercurial
+=====================
+
+Introduction
+````````````
+Mercurial_ manages a distributed repository containing revisions
+trees (each revision indicates the changes required to obtain the
+next, and so on). Locally, we have a repository containing revisions
+tree, and a working directory. It is possible
+to put in its working directory, one of the versions of its local repository,
+modify and then push it in its repository.
+It is also possible to get revisions from another repository or to export
+its own revisions from the local repository to another repository.
+
+.. _Mercurial: http://www.selenic.com/mercurial/
+
+In contrast to CVS/Subversion, we usually create a repository per
+project to manage.
+
+In a collaborative development, we usually create a central repository
+accessible to all developers of the project. These central repository is used
+as a reference. According to their needs, everyone can have a local repository,
+that they will have to synchronize with the central repository from time to time.
+
+
+Major commands
+``````````````
+* Create a local repository::
+
+     hg clone ssh://myhost//home/src/repo
+
+* See the contents of the local repository (graphical tool in Qt)::
+
+     hgview
+
+* Add a sub-directory or file in the current directory::
+
+     hg add subdir
+
+* Move to the working directory a specific revision (or last
+  revision) from the local repository::
+
+     hg update [identifier-revision]
+     hg up [identifier-revision]
+
+* Get in its local repository, the tree of revisions contained in a
+  remote repository (this does not change the local directory)::
+
+     hg pull ssh://myhost//home/src/repo
+     hg pull -u ssh://myhost//home/src/repo # equivalent to pull + update
+
+* See what are the heads of branches of the local repository if a `pull`
+  returned a new branch::
+
+     hg heads
+
+* Submit the working directory in the local repository (and create a new
+  revision)::
+
+     hg commit
+     hg ci
+
+* Merge with the mother revision of local directory, another revision from
+  the local respository (the new revision will be then two mothers
+  revisions)::
+
+     hg merge identifier-revision
+
+* Export to a remote repository, the tree of revisions in its content
+  local respository (this does not change the local directory)::
+
+     hg push ssh://myhost//home/src/repo
+
+* See what local revisions are not in another repository::
+
+     hg outgoing ssh://myhost//home/src/repo
+
+* See what are the revisions of a repository not found locally::
+
+     hg incoming ssh://myhost//home/src/repo
+
+* See what is the revision of the local repository which has been taken out
+  from the working directory and amended::
+
+     hg parent
+
+* See the differences between the working directory and the mother revision
+  of the local repository, possibly to submit them in the local repository::
+
+     hg diff
+     hg commit-tool
+     hg ct
+
+
+Best Practices
+``````````````
+* Remember to `hg pull -u` regularly, and particularly before
+   a `hg commit`.
+
+* Remember to `hg push` when your repository contains a version
+  relatively stable of your changes.
+
+* If a `hg pull -u` created a new branch head:
+
+   1. find its identifier with `hg head`
+   2. merge with `hg merge`
+   3. `hg ci`
+   4. `hg push`
+
+Installation of the guestrepo extension
+```````````````````````````````````````
+
+Set up the guestrepo extension by getting a copy of the sources
+from https://bitbucket.org/selinc/guestrepo and adding the following
+lines to your ``~/.hgrc``: ::
+
+   [extensions]
+   guestrepo=/path/to/guestrepo/guestrepo
+
+
+More information
+````````````````
+
+For more information about Mercurial, please refer to the Mercurial project online documentation_.
+
+.. _documentation: http://www.selenic.com/mercurial/wiki/
+
Binary file doc/book/annexes/rql/Graph-ex.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/rql/debugging.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,55 @@
+.. -*- coding: utf-8 -*-
+
+.. _DEBUGGING:
+
+Debugging RQL
+-------------
+
+Available levels
+~~~~~~~~~~~~~~~~
+
+Server debugging flags. They may be combined using binary operators.
+
+.. autodata:: cubicweb.server.DBG_NONE
+.. autodata:: cubicweb.server.DBG_RQL
+.. autodata:: cubicweb.server.DBG_SQL
+.. autodata:: cubicweb.server.DBG_REPO
+.. autodata:: cubicweb.server.DBG_MS
+.. autodata:: cubicweb.server.DBG_HOOKS
+.. autodata:: cubicweb.server.DBG_OPS
+.. autodata:: cubicweb.server.DBG_MORE
+.. autodata:: cubicweb.server.DBG_ALL
+
+
+Enable verbose output
+~~~~~~~~~~~~~~~~~~~~~
+
+To debug your RQL statements, it can be useful to enable a verbose output:
+
+.. sourcecode:: python
+
+    from cubicweb import server
+    server.set_debug(server.DBG_RQL|server.DBG_SQL|server.DBG_ALL)
+
+.. autofunction:: cubicweb.server.set_debug
+
+Another example showing how to debug hooks at a specific code site:
+
+.. sourcecode:: python
+
+    from cubicweb.server import debugged, DBG_HOOKS
+    with debugged(DBG_HOOKS):
+        person.cw_set(works_for=company)
+
+
+Detect largest RQL queries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+See `Profiling and performance` chapter (see :ref:`PROFILING`).
+
+
+API
+~~~
+
+.. autoclass:: cubicweb.server.debugged
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/rql/implementation.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,159 @@
+
+
+Implementation
+--------------
+
+BNF grammar
+~~~~~~~~~~~
+
+The terminal elements are in capital letters, non-terminal in lowercase.
+The value of the terminal elements (between quotes) is a Python regular
+expression.
+::
+
+     statement ::= (select | delete | insert | update) ';'
+
+
+     # select specific rules
+     select      ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
+
+     selected_terms ::= expression ( ',' expression)*
+
+     group       ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)*
+
+     sort        ::= 'ORDERBY' sort_term ( ',' sort_term)*
+
+     sort_term   ::=  VARIABLE sort_method =?
+
+     sort_method ::= 'ASC' | 'DESC'
+
+
+     # delete specific rules
+     delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
+
+
+     # insert specific rules
+     insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction?
+
+
+     # update specific rules
+     update ::= 'SET' relations_declaration restriction
+
+
+     # common rules
+     variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
+
+     relations_declaration ::= simple_relation (',' simple_relation)*
+
+     simple_relation ::= VARIABLE R_TYPE expression
+
+     restriction ::= 'WHERE' relations
+
+     relations   ::= relation (LOGIC_OP relation)*
+                   | '(' relations')'
+
+     relation    ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
+                   | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
+
+     expression  ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
+                   | '(' expression ')'
+
+     var_or_func_or_const ::= VARIABLE | function | constant
+
+     function    ::= FUNCTION '(' expression ( ',' expression) * ')'
+
+     constant    ::= KEYWORD | STRING | FLOAT | INT
+
+     # tokens
+     LOGIC_OP ::= ',' | 'OR' | 'AND'
+     MATH_OP  ::= '+' | '-' | '/' | '*'
+     COMP_OP  ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE'
+
+     FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER'
+
+     VARIABLE ::= '[A-Z][A-Z0-9]*'
+     E_TYPE   ::= '[A-Z]\w*'
+     R_TYPE   ::= '[a-z_]+'
+
+     KEYWORD  ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
+     STRING   ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"'
+     FLOAT    ::= '\d+\.\d*'
+     INT      ::= '\d+'
+
+
+Internal representation (syntactic tree)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The tree research does not contain the selected variables
+(e.g. there is only what follows "WHERE").
+
+The insertion tree does not contain the variables inserted or relations
+defined on these variables (e.g. there is only what follows "WHERE").
+
+The removal tree does not contain the deleted variables and relations
+(e.g. there is only what follows the "WHERE").
+
+The update tree does not contain the variables and relations updated
+(e.g. there is only what follows the "WHERE").
+
+::
+
+     Select         ((Relationship | And | Or)?, Group?, Sort?)
+     Insert         (Relations | And | Or)?
+     Delete         (Relationship | And | Or)?
+     Update         (Relations | And | Or)?
+
+     And            ((Relationship | And | Or), (Relationship | And | Or))
+     Or             ((Relationship | And | Or), (Relationship | And | Or))
+
+     Relationship   ((VariableRef, Comparison))
+
+     Comparison     ((Function | MathExpression | Keyword | Constant | VariableRef) +)
+
+     Function       (())
+     MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef))
+
+     Group          (VariableRef +)
+     Sort           (SortTerm +)
+     SortTerm       (VariableRef +)
+
+     VariableRef    ()
+     Variable       ()
+     Keyword        ()
+     Constant       ()
+
+
+Known limitations
+~~~~~~~~~~~~~~~~~
+
+- The current implementation does not support linking two relations of type 'is'
+  with an OR. I do not think that the negation is supported on this type of
+  relation (XXX to be confirmed).
+
+- missing COALESCE and certainly other things...
+
+- writing an rql query requires knowledge of the used schema (with real relation
+  names and entities, not those viewed in the user interface). On the other
+  hand, we cannot really bypass that, and it is the job of a user interface to
+  hide the RQL.
+
+
+Topics
+~~~~~~
+
+It would be convenient to express the schema matching
+relations (non-recursive rules)::
+
+     Document class Type <-> Document occurence_of Fiche class Type
+     Sheet class Type    <-> Form collection Collection class Type
+
+Therefore 1. becomes::
+
+     Document X where
+     X class C, C name 'Cartoon'
+     X owned_by U, U login 'syt'
+     X available true
+
+I'm not sure that we should handle this at RQL level ...
+
+There should also be a special relation 'anonymous'.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/rql/index.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,14 @@
+.. _RQLChapter:
+
+Relation Query Language (RQL)
+=============================
+
+This chapter describes the Relation Query Language syntax and its implementation in CubicWeb.
+
+.. toctree::
+   :maxdepth: 2
+
+   intro
+   language
+   debugging
+   implementation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/rql/intro.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,162 @@
+
+.. _rql_intro:
+
+Introduction
+------------
+
+Goals of RQL
+~~~~~~~~~~~~
+
+The goal is to have a semantic language in order to:
+
+- query relations in a clear syntax
+- empowers access to data repository manipulation
+- making attributes/relations browsing easy
+
+As such, attributes will be regarded as cases of special relations (in
+terms of usage, the user should see no syntactic difference between an
+attribute and a relation).
+
+Comparison with existing languages
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SQL
+```
+
+RQL may remind of SQL but works at a higher abstraction level (the *CubicWeb*
+framework generates SQL from RQL to fetch data from relation databases). RQL is
+focused on browsing relations. The user needs only to know about the *CubicWeb*
+data model he is querying, but not about the underlying SQL model.
+
+Sparql
+``````
+
+The query language most similar to RQL is SPARQL_, defined by the W3C to serve
+for the semantic web.
+
+Versa
+`````
+
+We should look in more detail, but here are already some ideas for the moment
+... Versa_ is the language most similar to what we wanted to do, but the model
+underlying data being RDF, there are some things such as namespaces or
+handling of the RDF types which does not interest us. On the functionality
+level, Versa_ is very comprehensive including through many functions of
+conversion and basic types manipulation, which we may want to look at one time
+or another.  Finally, the syntax is a little esoteric.
+
+Datalog
+```````
+
+Datalog_ is a prolog derived query langage which applies to relational
+databases. It is more expressive than RQL in that it accepts either
+extensional_ and intensional_ predicates (or relations). As of now,
+RQL only deals with intensional relations.
+
+The different types of queries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Search (`Any`)
+   Extract entities and attributes of entities.
+
+Insert entities (`INSERT`)
+   Insert new entities or relations in the database.
+   It can also directly create relationships for the newly created entities.
+
+Update entities, create relations (`SET`)
+   Update existing entities in the database,
+   or create relations between existing entities.
+
+Delete entities or relationship (`DELETE`)
+   Remove entities or relations existing in the database.
+
+
+RQL relation expressions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+RQL expressions apply to a live database defined by a
+:ref:`datamodel_definition`. Apart from the main type, or head, of the
+expression (search, insert, etc.) the most common constituent of an
+RQL expression is a (set of) relation expression(s).
+
+An RQL relation expression contains three components:
+
+* the subject, which is an entity type
+* the predicate, which is a relation definition (an arc of the schema)
+* the object, which is either an attribute or a relation to another entity
+
+.. image:: Graph-ex.gif
+    :alt: <subject> <predicate> <object>
+    :align: center
+
+.. warning::
+
+ A relation is always expressed in the order: ``subject``,
+ ``predicate``, ``object``.
+
+ It is important to determine if the entity type is subject or object
+ to construct a valid expression. Inverting the subject/object is an
+ error since the relation cannot be found in the schema.
+
+ If one does not have access to the code, one can find the order by
+ looking at the schema image in manager views (the subject is located
+ at the beginning of the arrow).
+
+An example of two related relation expressions::
+
+  P works_for C, P name N
+
+RQL variables represent typed entities. The type of entities is
+either automatically inferred (by looking at the possible relation
+definitions, see :ref:`RelationDefinition`) or explicitely constrained
+using the ``is`` meta relation.
+
+In the example above, we barely need to look at the schema. If
+variable names (in the RQL expression) and relation type names (in the
+schema) are expresssively designed, the human reader can infer as much
+as the |cubicweb| querier.
+
+The ``P`` variable is used twice but it always represent the same set
+of entities. Hence ``P works_for C`` and ``P name N`` must be
+compatible in the sense that all the Ps (which *can* refer to
+different entity types) must accept the ``works_for`` and ``name``
+relation types. This does restrict the set of possible values of P.
+
+Adding another relation expression::
+
+  P works_for C, P name N, C name "logilab"
+
+This further restricts the possible values of P through an indirect
+constraint on the possible values of ``C``. The RQL-level unification_
+happening there is translated to one (or several) joins_ at the
+database level.
+
+.. note::
+
+ In |cubicweb|, the term `relation` is often found without ambiguity
+ instead of `predicate`.  This predicate is also known as the
+ `property` of the triple in `RDF concepts`_
+
+
+RQL Operators
+~~~~~~~~~~~~~
+
+An RQL expression's head can be completed using various operators such
+as ``ORDERBY``, ``GROUPBY``, ``HAVING``, ``LIMIT`` etc.
+
+RQL relation expressions can be grouped with ``UNION`` or
+``WITH``. Predicate oriented keywords such as ``EXISTS``, ``OR``,
+``NOT`` are available.
+
+The complete zoo of RQL operators is described extensively in the
+following chapter (:ref:`RQL`).
+
+.. _RDF concepts: http://www.w3.org/TR/rdf-concepts/
+.. _Versa: http://wiki.xml3k.org/Versa
+.. _SPARQL: http://www.w3.org/TR/rdf-sparql-query/
+.. _unification: http://en.wikipedia.org/wiki/Unification_(computing)
+.. _joins: http://en.wikipedia.org/wiki/Join_(SQL)
+.. _Datalog: http://en.wikipedia.org/wiki/Datalog
+.. _intensional: http://en.wikipedia.org/wiki/Intensional_definition
+.. _extensional: http://en.wikipedia.org/wiki/Extension_(predicate_logic)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/annexes/rql/language.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,804 @@
+.. -*- coding: utf-8 -*-
+
+.. _RQL:
+
+RQL syntax
+----------
+
+.. _RQLKeywords:
+
+Reserved keywords
+~~~~~~~~~~~~~~~~~
+
+::
+
+  AND, ASC, BEING, DELETE, DESC, DISTINCT, EXISTS, FALSE, GROUPBY,
+  HAVING, ILIKE, INSERT, LIKE, LIMIT, NOT, NOW, NULL, OFFSET,
+  OR, ORDERBY, SET, TODAY, TRUE, UNION, WHERE, WITH
+
+The keywords are not case sensitive. You should not use them when defining your
+schema, or as RQL variable names.
+
+
+.. _RQLCase:
+
+Case
+~~~~
+
+* Variables should be all upper-cased.
+
+* Relation should be all lower-cased and match exactly names of relations defined
+  in the schema.
+
+* Entity types should start with an upper cased letter and be followed by at least
+  a lower cased latter.
+
+
+.. _RQLVariables:
+
+Variables and typing
+~~~~~~~~~~~~~~~~~~~~
+
+Entities and values to browse and/or select are represented in the query by
+*variables* that must be written in capital letters.
+
+With RQL, we do not distinguish between entities and attributes. The value of an
+attribute is considered as an entity of a particular type (see below), linked to
+one (real) entity by a relation called the name of the attribute, where the
+entity is the subject and the attribute the object.
+
+The possible type(s) for each variable is derived from the schema according to
+the constraints expressed above and thanks to the relations between each
+variable.
+
+We can restrict the possible types for a variable using the special relation
+**is** in the restrictions.
+
+
+.. _VirtualRelations:
+
+Virtual relations
+~~~~~~~~~~~~~~~~~
+
+Those relations may only be used in RQL query but are not actual attributes of
+your entities.
+
+* `has_text`: relation to use to query the full text index (only for entities
+  having fulltextindexed attributes).
+
+* `identity`: relation to use to tell that a RQL variable is the same as another
+  when you've to use two different variables for querying purpose. On the
+  opposite it's also useful together with the ``NOT`` operator to tell that two
+  variables should not identify the same entity
+
+
+.. _RQLLiterals:
+
+Literal expressions
+~~~~~~~~~~~~~~~~~~~
+
+Bases types supported by RQL are those supported by yams schema. Literal values
+are expressed as explained below:
+
+* string should be between double or single quotes. If the value contains a
+  quote, it should be preceded by a backslash '\\'
+
+* floats separator is dot '.'
+
+* boolean values are ``TRUE`` and ``FALSE`` keywords
+
+* date and time should be expressed as a string with ISO notation : YYYY/MM/DD
+  [hh:mm], or using keywords ``TODAY`` and ``NOW``
+
+You may also use the ``NULL`` keyword, meaning 'unspecified'.
+
+
+.. _RQLOperators:
+
+Operators
+~~~~~~~~~
+
+.. _RQLLogicalOperators:
+
+Logical operators
+`````````````````
+::
+
+     AND, OR, NOT, ','
+
+',' is equivalent to 'AND' but with the smallest among the priority of logical
+operators (see :ref:`RQLOperatorsPriority`).
+
+.. _RQLMathematicalOperators:
+
+Mathematical operators
+``````````````````````
+
++----------+---------------------+-----------+--------+
+| Operator |    Description      | Example   | Result |
++==========+=====================+===========+========+
+|  `+`     | addition            | 2 + 3     | 5      |
++----------+---------------------+-----------+--------+
+|  `-`     | subtraction         | 2 - 3     | -1     |
++----------+---------------------+-----------+--------+
+|  `*`     | multiplication      | 2 * 3     | 6      |
++----------+---------------------+-----------+--------+
+|  /       | division            | 4 / 2     | 2      |
++----------+---------------------+-----------+--------+
+|  %       | modulo (remainder)  | 5 % 4     | 1      |
++----------+---------------------+-----------+--------+
+|  ^       | exponentiation      | 2.0 ^ 3.0 | 8      |
++----------+---------------------+-----------+--------+
+|  &       | bitwise AND         | 91 & 15   | 11     |
++----------+---------------------+-----------+--------+
+|  `|`     | bitwise OR          | 32 | 3    | 35     |
++----------+---------------------+-----------+--------+
+|  #       | bitwise XOR         | 17 # 5    | 20     |
++----------+---------------------+-----------+--------+
+|  ~       | bitwise NOT         | ~1        | -2     |
++----------+---------------------+-----------+--------+
+|  <<      | bitwise shift left  | 1 << 4    | 16     |
++----------+---------------------+-----------+--------+
+|  >>      | bitwise shift right | 8 >> 2    | 2      |
++----------+---------------------+-----------+--------+
+
+
+Notice integer division truncates results depending on the backend behaviour. For
+instance, postgresql does.
+
+
+.. _RQLComparisonOperators:
+
+Comparison operators
+````````````````````
+ ::
+
+     =, !=, <, <=, >=, >, IN
+
+
+The syntax to use comparison operators is:
+
+    `VARIABLE attribute <operator> VALUE`
+
+The `=` operator is the default operator and can be omitted, i.e. :
+
+    `VARIABLE attribute = VALUE`
+
+is equivalent to
+
+    `VARIABLE attribute VALUE`
+
+
+The operator `IN` provides a list of possible values:
+
+.. sourcecode:: sql
+
+    Any X WHERE X name IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
+
+
+.. _RQLStringOperators:
+
+String operators
+````````````````
+::
+
+  LIKE, ILIKE, ~=, REGEXP
+
+The ``LIKE`` string operator can be used with the special character `%` in
+a string as wild-card:
+
+.. sourcecode:: sql
+
+     -- match every entity whose name starts with 'Th'
+     Any X WHERE X name ~= 'Th%'
+     -- match every entity whose name endswith 'lt'
+     Any X WHERE X name LIKE '%lt'
+     -- match every entity whose name contains a 'l' and a 't'
+     Any X WHERE X name LIKE '%l%t%'
+
+``ILIKE`` is the case insensitive version of ``LIKE``. It's not
+available on all backend (e.g. sqlite doesn't support it). If not available for
+your backend, ``ILIKE`` will behave like ``LIKE``.
+
+`~=` is a shortcut version of ``ILIKE``, or of ``LIKE`` when the
+former is not available on the back-end.
+
+
+The ``REGEXP`` is an alternative to ``LIKE`` that supports POSIX
+regular expressions:
+
+.. sourcecode:: sql
+
+   -- match entities whose title starts with a digit
+   Any X WHERE X title REGEXP "^[0-9].*"
+
+
+The underlying SQL operator used is back-end-dependent :
+
+- the ``~`` operator is used for postgresql,
+- the ``REGEXP`` operator for mysql and sqlite.
+
+Other back-ends are not supported yet.
+
+
+.. _RQLOperatorsPriority:
+
+Operators priority
+``````````````````
+
+#. `(`, `)`
+#. `^`, `<<`, `>>`
+#. `*`, `/`, `%`, `&`
+#. `+`, `-`, `|`, `#`
+#. `NOT`
+#. `AND`
+#. `OR`
+#. `,`
+
+
+.. _RQLSearchQuery:
+
+Search Query
+~~~~~~~~~~~~
+
+Simplified grammar of search query: ::
+
+   [ `DISTINCT`] `Any` V1 (, V2) \*
+   [ `GROUPBY` V1 (, V2) \*] [ `ORDERBY` <orderterms>]
+   [ `LIMIT` <value>] [ `OFFSET` <value>]
+   [ `WHERE` <triplet restrictions>]
+   [ `WITH` V1 (, V2)\* BEING (<query>)]
+   [ `HAVING` <other restrictions>]
+   [ `UNION` <query>]
+
+Selection
+`````````
+
+The fist occuring clause is the selection of terms that should be in the result
+set.  Terms may be variable, literals, function calls, arithmetic, etc. and each
+term is separated by a comma.
+
+There will be as much column in the result set as term in this clause, respecting
+order.
+
+Syntax for function call is somewhat intuitive, for instance:
+
+.. sourcecode:: sql
+
+    Any UPPER(N) WHERE P firstname N
+
+
+Grouping and aggregating
+````````````````````````
+
+The ``GROUPBY`` keyword is followed by a list of terms on which results
+should be grouped. They are usually used with aggregate functions, responsible to
+aggregate values for each group (see :ref:`RQLAggregateFunctions`).
+
+For grouped queries, all selected variables must be either aggregated (i.e. used
+by an aggregate function) or grouped (i.e. listed in the ``GROUPBY``
+clause).
+
+
+Sorting
+```````
+
+The ``ORDERBY`` keyword if followed by the definition of the selection
+order: variable or column number followed by sorting method (``ASC``,
+``DESC``), ``ASC`` being the default. If the sorting method is not
+specified, then the sorting is ascendant (`ASC`).
+
+
+Pagination
+``````````
+
+The ``LIMIT`` and ``OFFSET`` keywords may be respectively used to
+limit the number of results and to tell from which result line to start (for
+instance, use `LIMIT 20` to get the first 20 results, then `LIMIT 20 OFFSET 20`
+to get the next 20.
+
+
+Restrictions
+````````````
+
+The ``WHERE`` keyword introduce one of the "main" part of the query, where
+you "define" variables and add some restrictions telling what you're interested
+in.
+
+It's a list of triplets "subject relation object", e.g. `V1 relation
+(V2 | <static value>)`. Triplets are separated using :ref:`RQLLogicalOperators`.
+
+.. note::
+
+  About the negation operator (``NOT``):
+
+  * ``NOT X relation Y`` is equivalent to ``NOT EXISTS(X relation Y)``
+
+  * ``Any X WHERE NOT X owned_by U`` means "entities that have no relation
+    ``owned_by``".
+
+  * ``Any X WHERE NOT X owned_by U, U login "syt"`` means "the entity have no
+     relation ``owned_by`` with the user syt". They may have a relation "owned_by"
+     with another user.
+
+In this clause, you can also use ``EXISTS`` when you want to know if some
+expression is true and do not need the complete set of elements that make it
+true. Testing for existence is much faster than fetching the complete set of
+results, especially when you think about using ``OR`` against several expressions. For instance
+if you want to retrieve versions which are in state "ready" or tagged by
+"priority", you should write :
+
+.. sourcecode:: sql
+
+    Any X ORDERBY PN,N
+    WHERE X num N, X version_of P, P name PN,
+          EXISTS(X in_state S, S name "ready")
+          OR EXISTS(T tags X, T name "priority")
+
+not
+
+.. sourcecode:: sql
+
+    Any X ORDERBY PN,N
+    WHERE X num N, X version_of P, P name PN,
+          (X in_state S, S name "ready")
+          OR (T tags X, T name "priority")
+
+Both queries aren't at all equivalent :
+
+* the former will retrieve all versions, then check for each one which are in the
+  matching state of or tagged by the expected tag,
+
+* the later will retrieve all versions, state and tags (cartesian product!),
+  compute join and then exclude each row which are in the matching state or
+  tagged by the expected tag. This implies that you won't get any result if the
+  in_state or tag tables are empty (ie there is no such relation in the
+  application). This is usually NOT what you want.
+
+Another common case where you may want to use ``EXISTS`` is when you
+find yourself using ``DISTINCT`` at the beginning of your query to
+remove duplicate results. The typical case is when you have a
+multivalued relation such as Version version_of Project and you want
+to retrieve projects which have a version:
+
+.. sourcecode:: sql
+
+  Any P WHERE V version_of P
+
+will return each project number of versions times. So you may be
+tempted to use:
+
+.. sourcecode:: sql
+
+  DISTINCT ANY P WHERE V version_of P
+
+This will work, but is not efficient, as it will use the ``SELECT
+DISTINCT`` SQL predicate, which needs to retrieve all projects, then
+sort them and discard duplicates, which can have a very high cost for
+large result sets. So the best way to write this is:
+
+.. sourcecode:: sql
+
+  ANY P WHERE EXISTS V version_of P
+
+
+You can also use the question mark (`?`) to mark optional relations. This allows
+you to select entities related **or not** to another. It is a similar concept
+to `Left outer join`_:
+
+    the result of a left outer join (or simply left join) for table A and B
+    always contains all records of the "left" table (A), even if the
+    join-condition does not find any matching record in the "right" table (B).
+
+You must use the `?` behind a variable to specify that the relation to
+that variable is optional. For instance:
+
+- Bugs of a project attached or not to a version
+
+   .. sourcecode:: sql
+
+       Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
+
+  You will get a result set containing all the project's tickets, with either the
+  version in which it's fixed or None for tickets not related to a version.
+
+
+- All cards and the project they document if any
+
+  .. sourcecode:: sql
+
+       Any C, P WHERE C is Card, P? documented_by C
+
+Notice you may also use outer join:
+
+- on the RHS of attribute relation, e.g.
+
+  .. sourcecode:: sql
+
+       Any X WHERE X ref XR, Y name XR?
+
+  so that Y is outer joined on X by ref/name attributes comparison
+
+
+- on any side of an ``HAVING`` expression, e.g.
+
+  .. sourcecode:: sql
+
+       Any X WHERE X creation_date XC, Y creation_date YC
+       HAVING YEAR(XC)=YEAR(YC)?
+
+  so that Y is outer joined on X by comparison of the year extracted from their
+  creation date.
+
+  .. sourcecode:: sql
+
+       Any X WHERE X creation_date XC, Y creation_date YC
+       HAVING YEAR(XC)?=YEAR(YC)
+
+  would outer join X on Y instead.
+
+
+Having restrictions
+```````````````````
+
+The ``HAVING`` clause, as in SQL, may be used to restrict a query
+according to value returned by an aggregate function, e.g.
+
+.. sourcecode:: sql
+
+    Any X GROUPBY X WHERE X relation Y HAVING COUNT(Y) > 10
+
+It may however be used for something else: In the ``WHERE`` clause, we are
+limited to triplet expressions, so some things may not be expressed there. Let's
+take an example : if you want to get people whose upper-cased first name equals to
+another person upper-cased first name. There is no proper way to express this
+using triplet, so you should use something like:
+
+.. sourcecode:: sql
+
+    Any X WHERE X firstname XFN, Y firstname YFN, NOT X identity Y HAVING UPPER(XFN) = UPPER(YFN)
+
+Another example: imagine you want person born in 2000:
+
+.. sourcecode:: sql
+
+    Any X WHERE X birthday XB HAVING YEAR(XB) = 2000
+
+Notice that while we would like this to work without the HAVING clause, this
+can't be currently be done because it introduces an ambiguity in RQL's grammar
+that can't be handled by Yapps_, the parser's generator we're using.
+
+
+Sub-queries
+```````````
+
+The ``WITH`` keyword introduce sub-queries clause. Each sub-query has the
+form:
+
+  V1(,V2) BEING (rql query)
+
+Variables at the left of the ``BEING`` keyword defines into which
+variables results from the sub-query will be mapped to into the outer query.
+Sub-queries are separated from each other using a comma.
+
+Let's say we want to retrieve for each project its number of versions and its
+number of tickets. Due to the nature of relational algebra behind the scene, this
+can't be achieved using a single query. You have to write something along the
+line of:
+
+.. sourcecode:: sql
+
+  Any X, VC, TC WHERE X identity XX
+  WITH X, VC BEING (Any X, COUNT(V) GROUPBY X WHERE V version_of X),
+       XX, TC BEING (Any X, COUNT(T) GROUPBY X WHERE T ticket_of X)
+
+Notice that we can't reuse a same variable name as alias for two different
+sub-queries, hence the usage of 'X' and 'XX' in this example, which are then
+unified using the special `identity` relation (see :ref:`VirtualRelations`).
+
+.. warning::
+
+  Sub-queries define a new variable scope, so even if a variable has the same name
+  in the outer query and in the sub-query, they technically **aren't** the same
+  variable. So:
+
+  .. sourcecode:: sql
+
+     Any W, REF WITH W, REF BEING
+         (Any W, REF WHERE W is Workcase, W ref REF,
+                           W concerned_by D, D name "Logilab")
+
+  could be written:
+
+  .. sourcecode:: sql
+
+     Any W, REF WITH W, REF BEING
+        (Any W1, REF1 WHERE W1 is Workcase, W1 ref REF1,
+                            W1 concerned_by D, D name "Logilab")
+
+  Also, when a variable is coming from a sub-query, you currently can't reference
+  its attribute or inlined relations in the outer query, you've to fetch them in
+  the sub-query. For instance, let's say we want to sort by project name in our
+  first example, we would have to write:
+
+  .. sourcecode:: sql
+
+
+    Any X, VC, TC ORDERBY XN WHERE X identity XX
+    WITH X, XN, VC BEING (Any X, COUNT(V) GROUPBY X,XN WHERE V version_of X, X name XN),
+         XX, TC BEING (Any X, COUNT(T) GROUPBY X WHERE T ticket_of X)
+
+  instead of:
+
+  .. sourcecode:: sql
+
+    Any X, VC, TC ORDERBY XN WHERE X identity XX, X name XN,
+    WITH X, XN, VC BEING (Any X, COUNT(V) GROUPBY X WHERE V version_of X),
+         XX, TC BEING (Any X, COUNT(T) GROUPBY X WHERE T ticket_of X)
+
+  which would result in a SQL execution error.
+
+
+Union
+`````
+
+You may get a result set containing the concatenation of several queries using
+the ``UNION``. The selection of each query should have the same number of
+columns.
+
+.. sourcecode:: sql
+
+    (Any X, XN WHERE X is Person, X surname XN) UNION (Any X,XN WHERE X is Company, X name XN)
+
+
+.. _RQLFunctions:
+
+Available functions
+~~~~~~~~~~~~~~~~~~~
+
+Below is the list of aggregate and transformation functions that are supported
+nativly by the framework. Notice that cubes may define additional functions.
+
+.. _RQLAggregateFunctions:
+
+Aggregate functions
+```````````````````
++------------------------+----------------------------------------------------------+
+| ``COUNT(Any)``         | return the number of rows                                |
++------------------------+----------------------------------------------------------+
+| ``MIN(Any)``           | return the minimum value                                 |
++------------------------+----------------------------------------------------------+
+| ``MAX(Any)``           | return the maximum value                                 |
++------------------------+----------------------------------------------------------+
+| ``AVG(Any)``           | return the average value                                 |
++------------------------+----------------------------------------------------------+
+| ``SUM(Any)``           | return the sum of values                                 |
++------------------------+----------------------------------------------------------+
+| ``COMMA_JOIN(String)`` | return each value separated by a comma (for string only) |
++------------------------+----------------------------------------------------------+
+
+All aggregate functions above take a single argument. Take care some aggregate
+functions (e.g. ``MAX``, ``MIN``) may return `None` if there is no
+result row.
+
+.. _RQLStringFunctions:
+
+String transformation functions
+```````````````````````````````
+
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``UPPER(String)``                             | upper case the string                                           |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``LOWER(String)``                             | lower case the string                                           |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``LENGTH(String)``                            | return the length of the string                                 |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``SUBSTRING(String, start, length)``          | extract from the string a string starting at given index and of |
+|                                               | given length                                                    |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``LIMIT_SIZE(String, max size)``              | if the length of the string is greater than given max size,     |
+|                                               | strip it and add ellipsis ("..."). The resulting string will    |
+|                                               | hence have max size + 3 characters                              |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``TEXT_LIMIT_SIZE(String, format, max size)`` | similar to the above, but allow to specify the MIME type of the |
+|                                               | text contained by the string. Supported formats are text/html,  |
+|                                               | text/xhtml and text/xml. All others will be considered as plain |
+|                                               | text. For non plain text format, sgml tags will be first removed|
+|                                               | before limiting the string.                                     |
++-----------------------------------------------+-----------------------------------------------------------------+
+
+.. _RQLDateFunctions:
+
+Date extraction functions
+`````````````````````````
+
++----------------------+----------------------------------------+
+| ``YEAR(Date)``       | return the year of a date or datetime  |
++----------------------+----------------------------------------+
+| ``MONTH(Date)``      | return the month of a date or datetime |
++----------------------+----------------------------------------+
+| ``DAY(Date)``        | return the day of a date or datetime   |
++----------------------+----------------------------------------+
+| ``HOUR(Datetime)``   | return the hours of a datetime         |
++----------------------+----------------------------------------+
+| ``MINUTE(Datetime)`` | return the minutes of a datetime       |
++----------------------+----------------------------------------+
+| ``SECOND(Datetime)`` | return the seconds of a datetime       |
++----------------------+----------------------------------------+
+| ``WEEKDAY(Date)``    | return the day of week of a date or    |
+|                      | datetime.  Sunday == 1, Saturday == 7. |
++----------------------+----------------------------------------+
+
+.. _RQLOtherFunctions:
+
+Other functions
+```````````````
++-------------------+--------------------------------------------------------------------+
+| ``ABS(num)``      |  return the absolute value of a number                             |
++-------------------+--------------------------------------------------------------------+
+| ``RANDOM()``      | return a pseudo-random value from 0.0 to 1.0                       |
++-------------------+--------------------------------------------------------------------+
+| ``FSPATH(X)``     | expect X to be an attribute whose value is stored in a             |
+|                   | :class:`BFSStorage` and return its path on the file system         |
++-------------------+--------------------------------------------------------------------+
+| ``FTIRANK(X)``    | expect X to be an entity used in a has_text relation, and return a |
+|                   | number corresponding to the rank order of each resulting entity    |
++-------------------+--------------------------------------------------------------------+
+| ``CAST(Type, X)`` | expect X to be an attribute and return it casted into the given    |
+|                   | final type                                                         |
++-------------------+--------------------------------------------------------------------+
+
+
+.. _RQLExamples:
+
+Examples
+~~~~~~~~
+
+- *Search for the object of identifier 53*
+
+  .. sourcecode:: sql
+
+        Any X WHERE X eid 53
+
+- *Search material such as comics, owned by syt and available*
+
+  .. sourcecode:: sql
+
+        Any X WHERE X is Document,
+                    X occurence_of F, F class C, C name 'Comics',
+                    X owned_by U, U login 'syt',
+                    X available TRUE
+
+- *Looking for people working for eurocopter interested in training*
+
+  .. sourcecode:: sql
+
+        Any P WHERE P is Person, P work_for S, S name 'Eurocopter',
+                    P interested_by T, T name 'training'
+
+- *Search note less than 10 days old written by jphc or ocy*
+
+  .. sourcecode:: sql
+
+        Any N WHERE N is Note, N written_on D, D day> (today -10),
+                    N written_by P, P name 'jphc' or P name 'ocy'
+
+- *Looking for people interested in training or living in Paris*
+
+  .. sourcecode:: sql
+
+        Any P WHERE P is Person, EXISTS(P interested_by T, T name 'training') OR
+                    (P city 'Paris')
+
+- *The surname and firstname of all people*
+
+  .. sourcecode:: sql
+
+        Any N, P WHERE X is Person, X name N, X firstname P
+
+  Note that the selection of several entities generally force
+  the use of "Any" because the type specification applies otherwise
+  to all the selected variables. We could write here
+
+  .. sourcecode:: sql
+
+        String N, P WHERE X is Person, X name N, X first_name P
+
+
+  Note: You can not specify several types with * ... where X is FirstType or X is SecondType*.
+  To specify several types explicitly, you have to do
+
+
+  .. sourcecode:: sql
+
+        Any X WHERE X is IN (FirstType, SecondType)
+
+
+.. _RQLInsertQuery:
+
+Insertion query
+~~~~~~~~~~~~~~~
+
+    `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
+    [ `WHERE` <restriction>]
+
+:assignments:
+   list of relations to assign in the form `V1 relationship V2 | <static value>`
+
+The restriction can define variables used in assignments.
+
+Caution, if a restriction is specified, the insertion is done for
+*each line result returned by the restriction*.
+
+- *Insert a new person named 'foo'*
+
+  .. sourcecode:: sql
+
+        INSERT Person X: X name 'foo'
+
+- *Insert a new person named 'foo', another called 'nice' and a 'friend' relation
+  between them*
+
+  .. sourcecode:: sql
+
+        INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
+
+- *Insert a new person named 'foo' and a 'friend' relation with an existing
+  person called 'nice'*
+
+  .. sourcecode:: sql
+
+        INSERT Person X: X name 'foo', X friend  Y WHERE Y name 'nice'
+
+.. _RQLSetQuery:
+
+Update and relation creation queries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    `SET` <assignements>
+    [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the update is done *for
+each result line returned by the restriction*.
+
+- *Renaming of the person named 'foo' to 'bar' with the first name changed*
+
+  .. sourcecode:: sql
+
+        SET X name 'bar', X firstname 'original' WHERE X is Person, X name 'foo'
+
+- *Insert a relation of type 'know' between objects linked by
+  the relation of type 'friend'*
+
+  .. sourcecode:: sql
+
+        SET X know Y  WHERE X friend Y
+
+
+.. _RQLDeleteQuery:
+
+Deletion query
+~~~~~~~~~~~~~~
+
+    `DELETE` (<entity type> V) | (V1 relation v2 ),...
+    [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the deletion is made *for
+each line result returned by the restriction*.
+
+- *Deletion of the person named 'foo'*
+
+  .. sourcecode:: sql
+
+        DELETE Person X WHERE X name 'foo'
+
+- *Removal of all relations of type 'friend' from the person named 'foo'*
+
+  .. sourcecode:: sql
+
+        DELETE X friend Y WHERE X is Person, X name 'foo'
+
+
+.. _Yapps: http://theory.stanford.edu/~amitp/yapps/
+.. _Left outer join: http://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/cubes/available-cubes.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,66 @@
+.. _AvailableCubes:
+
+Available cubes
+---------------
+
+An instance is made of several basic cubes. In the set of available
+basic cubes we can find for example:
+
+Base entity types
+~~~~~~~~~~~~~~~~~
+* addressbook_: PhoneNumber and PostalAddress
+* card_: Card, generic documenting card
+* event_: Event (define events, display them in calendars)
+* file_: File (to allow users to upload and store binary or text files)
+* link_: Link (to collect links to web resources)
+* mailinglist_: MailingList (to reference a mailing-list and the URLs
+  for its archives and its admin interface)
+* person_: Person (easily mixed with addressbook)
+* task_: Task (something to be done between start and stop date)
+* zone_: Zone (to define places within larger places, for example a
+  city in a state in a country)
+
+
+Classification
+~~~~~~~~~~~~~~
+* folder_: Folder (to organize things by grouping them in folders)
+* keyword_: Keyword (to define classification schemes)
+* tag_: Tag (to tag anything)
+
+Other features
+~~~~~~~~~~~~~~
+* basket_: Basket (like a shopping cart)
+* blog_: a blogging system using Blog and BlogEntry entity types
+* comment_: system to attach comment threads to entities)
+* email_: archiving management for emails (`Email`, `Emailpart`,
+  `Emailthread`), trigger action in cubicweb through email
+
+
+
+
+
+.. _addressbook: http://www.cubicweb.org/project/cubicweb-addressbook
+.. _basket: http://www.cubicweb.org/project/cubicweb-basket
+.. _card: http://www.cubicweb.org/project/cubicweb-card
+.. _blog: http://www.cubicweb.org/project/cubicweb-blog
+.. _comment: http://www.cubicweb.org/project/cubicweb-comment
+.. _email: http://www.cubicweb.org/project/cubicweb-email
+.. _event: http://www.cubicweb.org/project/cubicweb-event
+.. _file: http://www.cubicweb.org/project/cubicweb-file
+.. _folder: http://www.cubicweb.org/project/cubicweb-folder
+.. _keyword: http://www.cubicweb.org/project/cubicweb-keyword
+.. _link: http://www.cubicweb.org/project/cubicweb-link
+.. _mailinglist: http://www.cubicweb.org/project/cubicweb-mailinglist
+.. _person: http://www.cubicweb.org/project/cubicweb-person
+.. _tag: http://www.cubicweb.org/project/cubicweb-tag
+.. _task: http://www.cubicweb.org/project/cubicweb-task
+.. _zone: http://www.cubicweb.org/project/cubicweb-zone
+
+To declare the use of a cube, once installed, add the name of the cube
+and its dependency relation in the `__depends_cubes__` dictionary
+defined in the file `__pkginfo__.py` of your own component.
+
+.. note::
+  The listed cubes above are available as debian-packages on `CubicWeb's forge`_.
+
+.. _`CubicWeb's forge`: http://www.cubicweb.org/project?vtitle=All%20cubicweb%20projects
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/cubes/cc-newcube.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,58 @@
+Creating a new cube from scratch
+--------------------------------
+
+Let's start by creating the cube environment in which we will develop ::
+
+  cd ~/cubes
+  # use cubicweb-ctl to generate a template for the cube
+  # will ask some questions, most with nice default
+  cubicweb-ctl newcube mycube
+  # makes the cube source code managed by mercurial
+  cd mycube
+  hg init
+  hg add .
+  hg ci
+
+If all went well, you should see the cube you just created in the list
+returned by ``cubicweb-ctl list`` in the  *Available cubes* section.
+If not, please refer to :ref:`ConfigurationEnv`.
+
+To reuse an existing cube, add it to the list named
+``__depends_cubes__`` which is defined in :file:`__pkginfo__.py`.
+This variable is used for the instance packaging (dependencies handled
+by system utility tools such as APT) and to find used cubes when the
+database for the instance is created (import_erschema('MyCube') will
+not properly work otherwise).
+
+On a Unix system, the available cubes are usually stored in the
+directory :file:`/usr/share/cubicweb/cubes`. If you are using the
+cubicweb mercurial repository (:ref:`SourceInstallation`), the cubes
+are searched in the directory
+:file:`/path/to/cubicweb_toplevel/cubes`. In this configuration
+cubicweb itself ought to be located at
+:file:`/path/to/cubicweb_toplevel/cubicweb`.
+
+.. note::
+
+    Please note that if you do not wish to use default directory for your cubes
+    library, you should set the :envvar:`CW_CUBES_PATH` environment variable to
+    add extra directories where cubes will be search, and you'll then have to use
+    the option `--directory` to specify where you would like to place the source
+    code of your cube:
+
+    ``cubicweb-ctl newcube --directory=/path/to/cubes/library mycube``
+
+
+.. XXX resurrect once live-server is back
+.. Usage of :command:`cubicweb-ctl liveserver`
+.. -------------------------------------------
+
+.. To quickly test a new cube, you can also use the `liveserver` command for cubicweb-ctl
+.. which allows to create an instance in memory (using an SQLite database by
+.. default) and make it accessible through a web server ::
+
+..   cubicweb-ctl live-server mycube
+
+.. or by using an existing database (SQLite or Postgres)::
+
+..   cubicweb-ctl live-server -s myfile_sources mycube
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/cubes/index.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,11 @@
+Cubes
+=====
+
+This chapter describes how to define your own cubes and reuse already available cubes.
+
+.. toctree::
+   :maxdepth: 1
+
+   layout.rst
+   cc-newcube.rst
+   available-cubes.rst
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/cubes/layout.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,153 @@
+
+.. _foundationsCube:
+
+.. _cubelayout:
+
+Standard structure for a cube
+-----------------------------
+
+A cube is structured as follows:
+
+::
+
+  mycube/
+  |
+  |-- data/
+  |   |-- cubes.mycube.css
+  |   |-- cubes.mycube.js
+  |   `-- external_resources
+  |
+  |-- debian/
+  |   |-- changelog
+  |   |-- compat
+  |   |-- control
+  |   |-- copyright
+  |   |-- cubicweb-mycube.prerm
+  |   `-- rules
+  |
+  |-- entities.py
+  |
+  |-- i18n/
+  |   |-- en.po
+  |   |-- es.po
+  |   `-- fr.po
+  |
+  |-- __init__.py
+  |
+  |-- MANIFEST.in
+  |
+  |-- migration/
+  |   |-- postcreate.py
+  |   `-- precreate.py
+  |
+  |-- __pkginfo__.py
+  |
+  |-- schema.py
+  |
+  |-- setup.py
+  |
+  |-- site_cubicweb.py
+  |
+  |-- hooks.py
+  |
+  |-- test/
+  |   |-- data/
+  |   |   `-- bootstrap_cubes
+  |   |-- pytestconf.py
+  |   |-- realdb_test_mycube.py
+  |   `-- test_mycube.py
+  |
+  `-- views.py
+
+
+We can use subpackages instead of python modules for ``views.py``, ``entities.py``,
+``schema.py`` or ``hooks.py``. For example, we could have:
+
+::
+
+  mycube/
+  |
+  |-- entities.py
+  |-- hooks.py
+  `-- views/
+      |-- __init__.py
+      |-- forms.py
+      |-- primary.py
+      `-- widgets.py
+
+
+where :
+
+* ``schema`` contains the schema definition (server side only)
+* ``entities`` contains the entity definitions (server side and web interface)
+* ``hooks`` contains hooks and/or views notifications (server side only)
+* ``views`` contains the web interface components (web interface only)
+* ``test`` contains tests related to the cube (not installed)
+* ``i18n`` contains message catalogs for supported languages (server side and
+  web interface)
+* ``data`` contains data files for static content (images, css,
+  javascript code)...(web interface only)
+* ``migration`` contains initialization files for new instances (``postcreate.py``)
+  and a file containing dependencies of the component depending on the version
+  (``depends.map``)
+* ``debian`` contains all the files managing debian packaging (you will find
+  the usual files ``control``, ``rules``, ``changelog``... not installed)
+* file ``__pkginfo__.py`` provides component meta-data, especially the distribution
+  and the current version (server side and web interface) or sub-cubes used by
+  the cube.
+
+
+At least you should have the file ``__pkginfo__.py``.
+
+
+The :file:`__init__.py` and :file:`site_cubicweb.py` files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. XXX WRITEME
+
+The :file:`__pkginfo__.py` file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It contains metadata describing your cube, mostly useful for packaging.
+
+Two important attributes of this module are __depends__ and __recommends__
+dictionaries that indicates what should be installed (and each version if
+necessary) for the cube to work.
+
+Dependency on other cubes are expected to be of the form 'cubicweb-<cubename>'.
+
+When an instance is created, dependencies are automatically installed, while
+recommends are not.
+
+Recommends may be seen as a kind of 'weak dependency'. Eg, the most important
+effect of recommending a cube is that, if cube A recommends cube B, the cube B
+will be loaded before the cube A (same thing happend when A depends on B).
+
+Having this behaviour is sometime desired: on schema creation, you may rely on
+something defined in the other's schema; on database creation, on something
+created by the other's postcreate, and so on.
+
+
+:file:`migration/precreate.py` and :file:`migration/postcreate.py`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. XXX detail steps of instance creation
+
+
+External resources such as image, javascript and css files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. XXX naming convention external_resources file
+
+
+Out-of the box testing
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. XXX MANIFEST.in, __pkginfo__.include_dirs, debian
+
+
+Packaging and distribution
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. XXX MANIFEST.in, __pkginfo__.include_dirs, debian
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/dataimport.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,138 @@
+.. -*- coding: utf-8 -*-
+
+.. _dataimport:
+
+Dataimport
+==========
+
+*CubicWeb* is designed to manipulate huge of amount of data, and provides utilities to do so.
+
+The main entry point is :mod:`cubicweb.dataimport.importer` which defines an
+:class:`ExtEntitiesImporter` class responsible for importing data from an external source in the
+form :class:`ExtEntity` objects. An :class:`ExtEntity` is a transitional representation of an
+entity to be imported in the CubicWeb instance; building this representation is usually
+domain-specific -- e.g. dependent of the kind of data source (RDF, CSV, etc.) -- and is thus the
+responsibility of the end-user.
+
+Along with the importer, a *store* must be selected, which is responsible for insertion of data into
+the database. There exists different kind of stores_, allowing to insert data within different
+levels of the *CubicWeb* API and with different speed/security tradeoffs. Those keeping all the
+*CubicWeb* hooks and security will be slower but the possible errors in insertion (bad data types,
+integrity error, ...) will be handled.
+
+
+Example
+-------
+
+Consider the following schema snippet.
+
+.. code-block:: python
+
+    class Person(EntityType):
+        name = String(required=True)
+
+    class knows(RelationDefinition):
+        subject = 'Person'
+        object = 'Person'
+
+along with some data in a ``people.csv`` file::
+
+    # uri,name,knows
+    http://www.example.org/alice,Alice,
+    http://www.example.org/bob,Bob,http://www.example.org/alice
+
+The following code (using a shell context) defines a function `extentities_from_csv` to read
+`Person` external entities coming from a CSV file and calls the :class:`ExtEntitiesImporter` to
+insert corresponding entities and relations into the CubicWeb instance.
+
+.. code-block:: python
+
+    from cubicweb.dataimport import ucsvreader, RQLObjectStore
+    from cubicweb.dataimport.importer import ExtEntity, ExtEntitiesImporter
+
+    def extentities_from_csv(fpath):
+        """Yield Person ExtEntities read from `fpath` CSV file."""
+        with open(fpath) as f:
+            for uri, name, knows in ucsvreader(f, skipfirst=True, skip_empty=False):
+                yield ExtEntity('Personne', uri,
+                                {'nom': set([name]), 'connait': set([knows])})
+
+    extenties = extentities_from_csv('people.csv')
+    store = RQLObjectStore(cnx)
+    importer = ExtEntitiesImporter(schema, store)
+    importer.import_entities(extenties)
+    commit()
+    rset = cnx.execute('String N WHERE X nom N, X connait Y, Y nom "Alice"')
+    assert rset[0][0] == u'Bob', rset
+
+Importer API
+------------
+
+.. automodule:: cubicweb.dataimport.importer
+
+
+Stores
+~~~~~~
+
+Stores are responsible to insert properly formatted entities and relations into the database. They
+have the following API::
+
+    >>> user_eid = store.prepare_insert_entity('CWUser', login=u'johndoe')
+    >>> group_eid = store.prepare_insert_entity('CWUser', name=u'unknown')
+    >>> store.relate(user_eid, 'in_group', group_eid)
+    >>> store.flush()
+    >>> store.commit()
+    >>> store.finish()
+
+Some stores **require a flush** to copy data in the database, so if you want to have store
+independent code you should explicitly call it. (There may be multiple flushes during the
+process, or only one at the end if there is no memory issue). This is different from the
+commit which validates the database transaction. At last, the `finish()` method should be called in
+case the store requires additional work once everything is done.
+
+* ``prepare_insert_entity(<entity type>, **kwargs) -> eid``: given an entity
+  type, attributes and inlined relations, return the eid of the entity to be
+  inserted, *with no guarantee that anything has been inserted in database*.
+
+* ``prepare_update_entity(<entity type>, eid, **kwargs) -> None``: given an
+  entity type and eid, promise for update given attributes and inlined
+  relations *with no guarantee that anything has been inserted in database*.
+
+* ``prepare_insert_relation(eid_from, rtype, eid_to) -> None``: indicate that a
+  relation ``rtype`` should be added between entities with eids ``eid_from``
+  and ``eid_to``. Similar to ``prepare_insert_entity()``, *there is no
+  guarantee that the relation has been inserted in database*.
+
+* ``flush() -> None``: flush any temporary data to database. May be called
+  several times during an import.
+
+* ``commit() -> None``: commit the database transaction.
+
+* ``finish() -> None``: additional stuff to do after import is terminated.
+
+ObjectStore
+-----------
+
+This store keeps objects in memory for *faster* validation. It may be useful in development
+mode. However, as it will not enforce the constraints of the schema nor insert anything in the
+database, so it may miss some problems.
+
+
+RQLObjectStore
+--------------
+
+This store works with an actual RQL repository, and it may be used in production mode.
+
+
+NoHookRQLObjectStore
+--------------------
+
+This store works similarly to the *RQLObjectStore* but bypasses some *CubicWeb* hooks to be faster.
+
+
+SQLGenObjectStore
+-----------------
+
+This store relies on *COPY FROM*/execute many sql commands to directly push data using SQL commands
+rather than using the whole *CubicWeb* API. For now, **it only works with PostgresSQL** as it requires
+the *COPY FROM* command.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/datamodel/baseschema.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,42 @@
+.. _pre_defined_entity_types:
+
+Pre-defined entities in the library
+-----------------------------------
+
+The library defines a set of entity schemas that are required by the system
+or commonly used in *CubicWeb* instances.
+
+
+Entity types used to store the schema
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* _`CWEType`, entity type
+* _`CWRType`, relation type
+* _`CWRelation`, relation definition
+* _`CWAttribute`, attribute relation definition
+* _`CWConstraint`,  `CWConstraintType`, `RQLExpression`
+
+Entity types used to manage users and permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* _`CWUser`, system users
+* _`CWGroup`, users groups
+
+Entity types used to manage workflows
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* :ref:`Workflow <Workflow>`, workflow entity, linked to some entity types which may use this workflow
+* _`State`, workflow state
+* _`Transition`, workflow transition
+* _`TrInfo`, record of a transition trafic for an entity
+
+Other entity types
+~~~~~~~~~~~~~~~~~~
+* _`CWCache`, cache entities used to improve performances
+* _`CWProperty`, used to configure the instance
+
+* _`EmailAddress`, email address, used by the system to send notifications
+  to the users and also used by others optionnals schemas
+
+* _`Bookmark`, an entity type used to allow a user to customize his links within
+  the instance
+
+* _`ExternalUri`, used for semantic web site to indicate that an entity is the
+  same as another from an external site
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/datamodel/define-workflows.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,160 @@
+.. -*- coding: utf-8 -*-
+
+.. _Workflow:
+
+Defining a Workflow
+===================
+
+General
+-------
+
+A workflow describes how certain entities have to evolve between different
+states. Hence we have a set of states, and a "transition graph", i.e. a set of
+possible transitions from one state to another state.
+
+We will define a simple workflow for a blog, with only the following two states:
+`submitted` and `published`. You may want to take a look at :ref:`TutosBase` if
+you want to quickly setup an instance running a blog.
+
+Setting up a workflow
+---------------------
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on the instance. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it has to
+be in the state `published`. To move it from `submitted` to `published`,
+we need a transition that we can call `approve_blogentry`.
+
+A BlogEntry state should not be modifiable by every user.
+So we have to define a group of users, `moderators`, and
+this group will have appropriate permissions to publish a BlogEntry.
+
+There are two ways to create a workflow: from the user interface, or
+by defining it in ``migration/postcreate.py``. This script is executed
+each time a new ``cubicweb-ctl db-init`` is done.  We strongly
+recommend to create the workflow in ``migration/postcreate.py`` and we
+will now show you how. Read `Two bits of warning`_ to understand why.
+
+The state of an entity is managed by the `in_state` attribute which
+can be added to your entity schema by inheriting from
+`cubicweb.schema.WorkflowableEntityType`.
+
+
+About our example of BlogEntry, we must have:
+
+.. sourcecode:: python
+
+  from cubicweb.schema import WorkflowableEntityType
+
+  class BlogEntry(WorkflowableEntityType):
+      ...
+
+
+Creating states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :mod:`postcreate` script is executed in a special environment,
+adding several |cubicweb| primitives that can be used.
+
+They are all defined in the :class:`ServerMigrationHelper` class.
+We will only discuss the methods we use to create a workflow in this example.
+
+A workflow is a collection of entities of type ``State`` and of type
+``Transition`` which are standard *CubicWeb* entity types.
+
+To define a workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``:
+
+.. sourcecode:: python
+
+  _ = unicode
+
+  moderators = add_entity('CWGroup', name=u"moderators")
+
+This adds the `moderators` user group.
+
+.. sourcecode:: python
+
+  wf = add_workflow(u'blog publication workflow', 'BlogEntry')
+
+At first, instanciate a new workflow object with a gentle description
+and the concerned entity types (this one can be a tuple for multiple
+value).
+
+.. sourcecode:: python
+
+  submitted = wf.add_state(_('submitted'), initial=True)
+  published = wf.add_state(_('published'))
+
+This will create two entities of type ``State``, one with name
+'submitted', and the other with name 'published'.
+
+``add_state`` expects as first argument the name of the state you want
+to create and an optional argument to say if it is supposed to be the
+initial state of the entity type.
+
+.. sourcecode:: python
+
+  wf.add_transition(_('approve_blogentry'), (submitted,), published, ('moderators', 'managers'),)
+
+This will create an entity of type ``Transition`` with name
+`approve_blogentry` which will be linked to the ``State`` entities
+created before.
+
+``add_transition`` expects
+
+  * as the first argument: the name of the transition
+  * then the list of states on which the transition can be triggered,
+  * the target state of the transition,
+  * and the permissions
+    (e.g. a list of user groups who can apply the transition; the user
+    has to belong to at least one of the listed group to perform the action).
+
+.. sourcecode:: python
+
+  checkpoint()
+
+.. note::
+  Do not forget to add the `_()` in front of all states and
+  transitions names while creating a workflow so that they will be
+  identified by the i18n catalog scripts.
+
+In addition to the user groups (one of which the user needs to belong
+to), we could have added a RQL condition.  In this case, the user can
+only perform the action if the two conditions are satisfied.
+
+If we use an RQL condition on a transition, we can use the following variables:
+
+* `X`, the entity on which we may pass the transition
+* `U`, the user executing that may pass the transition
+
+
+.. image:: ../../images/03-transitions-view_en.png
+
+You can notice that in the action box of a BlogEntry, the state is now
+listed as well as the possible transitions for the current state
+defined by the workflow.
+
+The transitions will only be displayed for users having the right permissions.
+In our example, the transition `approve_blogentry` will only be displayed
+for the users belonging to the group `moderators` or `managers`.
+
+
+Two bits of warning
+~~~~~~~~~~~~~~~~~~~
+
+We could perfectly use the administration interface to do these
+operations. It is a convenient thing to do at times (when doing
+development, to quick-check things). But it is not recommended beyond
+that because it is a bit complicated to do it right and it will be
+only local to your instance (or, said a bit differently, such a
+workflow only exists in an instance database). Furthermore, you cannot
+write unit tests against deployed instances, and experience shows it
+is mandatory to have tests for any mildly complicated workflow
+setup.
+
+Indeed, if you create the states and transitions through the user
+interface, next time you initialize the database you will have to
+re-create all the workflow entities. The user interface should only be
+a reference for you to view the states and transitions, but is not the
+appropriate interface to define your application workflow.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/devrepo/datamodel/definition.rst	Thu Jan 08 22:11:06 2015 +0100
@@ -0,0 +1,912 @@
+.. -*- coding: utf-8 -*-
+
+.. _datamodel_definition:
+
+Yams *schema*
+-------------
+
+The **schema** is the core piece of a *CubicWeb* instance as it
+defines and handles the data model. It is based on entity types that
+are either already defined in `Yams`_ and the *CubicWeb* standard
+library; or more specific types defined in cubes. The schema for a
+cube is defined in a `schema` python module or package.
+
+.. _`Yams`: http://www.logilab.org/project/yams
+
+.. _datamodel_overview:
+
+Overview
+~~~~~~~~
+
+The core idea of the yams schema is not far from the classical
+`Entity-relationship`_ model. But while an E/R model (or `logical
+model`) traditionally has to be manually translated to a lower-level
+data description language (such as the SQL `create table`
+sublanguage), also often described as the `physical model`, no such
+step is required with |yams| and |cubicweb|.
+
+.. _`Entity-relationship`: http://en.wikipedia.org/wiki/Entity-relationship_model
+
+This is because in addition to high-level, logical |yams| models, one
+uses the |rql| data manipulation language to query, insert, update and
+delete data. |rql| abstracts as much of the underlying SQL database as
+a |yams| schema abstracts from the physical layout. The vagaries of
+SQL are avoided.
+
+As a bonus point, such abstraction make it quite comfortable to build
+or use different backends to which |rql| queries apply.
+
+So, as in the E/R formalism, the building blocks are ``entities``
+(:ref:`EntityType`), ``relationships`` (:ref:`RelationType`,
+:ref:`RelationDefinition`) and ``attributes`` (handled like relation
+with |yams|).
+
+Let us detail a little the divergences between E/R and |yams|:
+
+* all relationship are binary which means that to represent a
+  non-binary relationship, one has to use an entity,
+* relationships do not support attributes (yet, see:
+  http://www.cubicweb.org/ticket/341318), hence the need to reify it
+  as an entity if need arises,
+* all entities have an `eid` attribute (an integer) that is its
+  primary key (but it is possible to declare uniqueness on other
+  attributes)
+
+Also |yams| supports the notions of:
+
+* entity inheritance (quite experimental yet, and completely
+  undocumented),
+* relation type: that is, relationships can be established over a set
+  of couple of entity types (henre the distinction made between
+  `RelationType` and `RelationDefinition` below)
+
+Finally |yams| has a few concepts of its own:
+
+* relationships being oriented and binary, we call the left hand
+  entity type the `subject` and the right hand entity type the
+  `object`
+
+.. note::
+
+   The |yams| schema is available at run time through the .schema
+   attribute of the `vregistry`.  It's an instance of
+   :class:`cubicweb.schema.Schema`, which extends
+   :class:`yams.schema.Schema`.
+
+.. _EntityType:
+
+Entity type
+~~~~~~~~~~~
+
+An entity type is an instance of :class:`yams.schema.EntitySchema`. Each entity type has
+a set of attributes and relations, and some permissions which define who can add, read,
+update or delete entities of this type.
+
+The following built-in types are available: ``String``,
+``Int``, ``BigInt``, ``Float``, ``Decimal``, ``Boolean``,
+``Date``, ``Datetime``, ``Time``, ``Interval``, ``Byte`` and
+``Password``. They can only be used as attributes of an other entity
+type.
+
+There is also a `RichString` kindof type:
+
+ .. autoclass:: yams.buildobjs.RichString
+
+The ``__unique_together__`` class attribute is a list of tuples of names of
+attributes or inlined relations.  For each tuple, CubicWeb ensures the unicity
+of the combination.  For example:
+
+.. sourcecode:: python
+
+  class State(EntityType):
+      __unique_together__ = [('name', 'state_of')]
+
+      name = String(required=True)
+      state_of = SubjectRelation('Workflow', cardinality='1*',
+                                 composite='object', inlined=True)
+
+
+You can find more base entity types in
+:ref:`pre_defined_entity_types`.
+
+.. XXX yams inheritance
+
+.. _RelationType:
+
+Relation type
+~~~~~~~~~~~~~
+
+A relation type is an instance of
+:class:`yams.schema.RelationSchema`. A relation type is simply a
+semantic definition of a kind of relationship that may occur in an
+application.
+
+It may be referenced by zero, one or more relation definitions.
+
+It is important to choose a good name, at least to avoid conflicts
+with some semantically different relation defined in other cubes
+(since there's only a shared name space for these names).
+
+A relation type holds the following properties (which are hence shared
+between all relation definitions of that type):
+
+* `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 relations where cardinality
+  of subject->relation->object is 0..1 (`?`) or 1..1 (`1`) for *all* its relation
+  definitions.
+
+* `symmetric`: boolean indicating that the relation is symmetrical, which
+  means that `X relation Y` implies `Y relation X`.
+
+.. _RelationDefinition:
+
+Relation definition
+~~~~~~~~~~~~~~~~~~~
+
+A relation definition is an instance of
+:class:`yams.schema.RelationDefinition`. It is a complete triplet
+"<subject entity type> <relation type> <object entity type>".
+
+When creating a new instance of that class, the corresponding
+:class:`RelationType` instance is created on the fly if necessary.
+
+Properties
+``````````
+
+The available properties for relation definitions are enumerated
+here. There are several kind of properties, as some relation
+definitions are actually attribute definitions, and other are not.
+
+Some properties may be completely optional, other may have a default
+value.
+
+Common properties for attributes and relations:
+
+* `description`: a unicode 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`: a list of conditions/constraints that the relation has to
+  satisfy (c.f. `Constraints`_)
+
+* `cardinality`: a two character string specifying the cardinality of
+  the relation. The first character defines the cardinality of the
+  relation on the subject, and the second on the object. When a
+  relation can have multiple subjects or objects, the cardinality
+  applies to all, not on a one-to-one basis (so it must be
+  consistent...). Default value is '**'. The possible values are
+  inspired from regular expression syntax:
+
+    * `1`: 1..1
+    * `?`: 0..1
+    * `+`: 1..n
+    * `*`: 0..n
+
+Attributes properties:
+
+* `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 useful
+  only if you know that you will have to run numerous searches on the
+  value of this attribute.
+
+* `default`: default value of the attribute. In case of date types, the values
+  which could be used correspond to the RQL keywords `TODAY` and `NOW`.
+
+* `metadata`: Is also accepted as an argument of the attribute contructor. It is
+  not really an attribute property. see `Metadata`_ for details.
+
+Properties for `String` attributes:
+
+* `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)
+
+Relation properties:
+
+* `composite`: string indicating that the subject (composite ==
+  'subject') is composed of the objects of the relations. For the
+  opposite case (when the object is composed of the subjects of the
+  relation), we just set 'object' as value. The composition implies
+  that when the relation is deleted (so when the composite is deleted,
+  at least), the composed are also deleted.
+
+* `fulltext_container`: string indicating if the value if the full
+  text indexation of the entity on one end of the relation should be
+  used to find the entity on the other end. The possible values are
+  'subject' or 'object'. For instance the use_email relation has that
+  property set to 'subject', since when performing a full text search
+  people want to find the entity using an email address, and not the
+  entity representing the email address.
+
+Constraints
+```````````
+
+By default, the available constraint types are:
+
+General Constraints
+......................
+
+* `SizeConstraint`: allows to specify a minimum and/or maximum size on
+  string (generic case of `maxsize`)
+
+* `BoundaryConstraint`: allows to specify a minimum and/or maximum value
+  on numeric types and date
+
+.. sourcecode:: python
+
+   from yams.constraints import BoundaryConstraint, TODAY, NOW, Attribute
+
+   class DatedEntity(EntityType):
+      start = Date(constraints=[BoundaryConstraint('>=', TODAY())])
+      end = Date(constraints=[BoundaryConstraint('>=', Attribute('start'))])
+
+   class Before(EntityType);
+      last_time = DateTime(constraints=[BoundaryConstraint('<=', NOW())])
+
+* `IntervalBoundConstraint`: allows to specify an interval with
+  included values
+
+.. sourcecode:: python
+
+     class Node(EntityType):
+         latitude = Float(constraints=[IntervalBoundConstraint(-90, +90)])
+
+* `UniqueConstraint`: identical to "unique=True"
+
+* `StaticVocabularyConstraint`: identical to "vocabulary=(...)"
+
+Constraints can be dependent on a fixed value (90, Date(2015,3,23)) or a variable.
+In this second case, yams can handle :
+
+* `Attribute`: compare to the value of another attribute.
+* `TODAY`: compare to the current Date.
+* `NOW`: compare to the current Datetime.
+
+RQL Based Constraints
+......................
+
+RQL based constraints may take three arguments. The first one is the ``WHERE``
+clause of a RQL query used by the constraint. The second argument ``mainvars``
+is the ``Any`` clause of the query. By default this include `S` reserved for the
+subject of the relation and `O` for the object. Additional variables could be
+specified using ``mainvars``. The argument expects a single string with all
+variable's name separated by spaces. The last one, ``msg``, is the error message
+displayed when the constraint fails. As RQLVocabularyConstraint never fails the
+third argument is not available.
+
+* `RQLConstraint`: allows to specify a RQL query that has to be satisfied
+  by the subject and/or the object of relation. In this query the variables
+  `S` and `O` are reserved for the relation subject and object entities.
+
+* `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.
+
+* `RQLUniqueConstraint`: allows to the specify a RQL query that ensure that an
+  attribute is unique in a specific context. The Query must **never** return more
+  than a single result to be satisfied. In this query the variables `S` is
+  reserved for the relation subject entity. The other variables should be
+  specified with the second constructor argument (mainvars). This constraint type
+  should be used when __unique_together__ doesn't fit.
+
+.. XXX note about how to add new constraint
+
+.. _securitymodel:
+
+The security model
+~~~~~~~~~~~~~~~~~~
+
+The security model of `CubicWeb` is based on `Access Control List`.
+The main principles are:
+
+* users and groups of users
+* a user belongs to at least one group of user
+* permissions (`read`, `update`, `create`, `delete`)
+* permissions are assigned to groups (and not to users)
+
+For *CubicWeb* in particular:
+
+* we associate rights at the entities/relations schema level
+
+* the default groups are: `managers`, `users` and `guests`
+
+* users belong to the `users` group
+
+* there is a virtual group called `owners` to which we can associate only
+  `delete` and `update` permissions
+
+  * we can not add users to the `owners` group, they are implicitly added to it
+    according to the context of the objects they own
+
+  * the permissions of this group are only checked on `update`/`delete` actions
+    if all the other groups the user belongs to do not provide those permissions
+
+Setting permissions is done with the class attribute `__permissions__`
+of entity types and relation definitions. The value of this attribute
+is a dictionary where the keys are the access types (action), and the
+values are the authorized groups or rql expressions.
+
+For an entity type, the possible actions are `read`, `add`, `update` and
+`delete`.
+
+For a relation, the possible actions are `read`, `add`, and `delete`.
+
+For an attribute, the possible actions are `read`, `add` and `update`,
+and they are a refinement of an entity type permission.
+
+.. note::
+
+   By default, the permissions of an entity type attributes are
+   equivalent to the permissions of the entity type itself.
+
+   It is possible to provide custom attribute permissions which are
+   stronger than, or are more lenient than the entity type
+   permissions.
+
+   In a situation where all attributes were given custom permissions,
+   the entity type permissions would not be checked, except for the
+   `delete` action.
+
+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 if the user is in one of the listed groups or if one of the RQL condition
+is satisfied.
+
+Default permissions
+```````````````````
+
+The default permissions for ``EntityType`` are:
+
+.. sourcecode:: python
+
+   __permissions__ = {
+        'read': ('managers', 'users', 'guests',),
+        'update': ('managers', 'owners',),
+        'delete': ('managers', 'owners'),
+        'add': ('managers', 'users',)
+        }
+
+The default permissions for relations are:
+
+.. sourcecode:: python
+
+   __permissions__ = {'read': ('managers', 'users', 'guests',),
+                    'delete': ('managers', 'users'),
+                    'add': ('managers', 'users',)}
+
+The default permissions for attributes are:
+
+.. sourcecode:: python
+
+   __permissions__ = {'read': ('managers', 'users', 'guests',),
+                      'add': ('managers', ERQLExpression('U has_add_permission X'),
+                      'update': ('managers', ERQLExpression('U has_update_permission X')),}
+
+.. note::
+
+   The default permissions for attributes are not syntactically
+   equivalent to the default permissions of the entity types, but the
+   rql expressions work by delegating to the entity type permissions.
+
+
+The standard user groups
+````````````````````````
+
+* `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 defined in the precreate
+script of the cube (``migration/precreate.py``). Defining groups in postcreate
+script or later makes them unavailable for security purposes (in this case, an
+`sync_schema_props_perms` command has to be issued in a CubicWeb shell).
+
+
+Use of RQL expression for write permissions
+```````````````````````````````````````````
+
+It is possible to define RQL expression to provide update perm