[doc] major rework of the simple blog tutorial stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 17 Jan 2011 12:43:07 +0100
branchstable
changeset 6835 87e2641d75f7
parent 6834 b4befa12bbcc
child 6836 fb3633142d8f
[doc] major rework of the simple blog tutorial
doc/book/en/images/blog-demo-first-page.png
doc/book/en/images/cbw-add-relation-entryof_en.png
doc/book/en/images/cbw-create-blog_en.png
doc/book/en/images/cbw-detail-one-blogentry_en.png
doc/book/en/images/cbw-list-one-blog_en.png
doc/book/en/images/cbw-list-two-blog_en.png
doc/book/en/images/cbw-schema_en.png
doc/book/en/images/cbw-update-primary-view_en.png
doc/book/en/images/lax-book_06-header-no-login_en.png
doc/book/en/images/lax-book_06-main-template-layout_en.png
doc/book/en/images/lax-book_06-simple-main-template_en.png
doc/book/en/images/login-form.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/tutorials/base/blog-in-five-minutes.rst
doc/book/en/tutorials/base/components.rst
doc/book/en/tutorials/base/conclusion.rst
doc/book/en/tutorials/base/create-cube.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/base/maintemplate.rst
Binary file doc/book/en/images/blog-demo-first-page.png has changed
Binary file doc/book/en/images/cbw-add-relation-entryof_en.png has changed
Binary file doc/book/en/images/cbw-create-blog_en.png has changed
Binary file doc/book/en/images/cbw-detail-one-blogentry_en.png has changed
Binary file doc/book/en/images/cbw-list-one-blog_en.png has changed
Binary file doc/book/en/images/cbw-list-two-blog_en.png has changed
Binary file doc/book/en/images/cbw-schema_en.png has changed
Binary file doc/book/en/images/cbw-update-primary-view_en.png has changed
Binary file doc/book/en/images/lax-book_06-header-no-login_en.png has changed
Binary file doc/book/en/images/lax-book_06-main-template-layout_en.png has changed
Binary file doc/book/en/images/lax-book_06-simple-main-template_en.png has changed
Binary file doc/book/en/images/login-form.png has changed
Binary file doc/book/en/images/tutos-base_blog-form_en.png has changed
Binary file doc/book/en/images/tutos-base_blog-primary-after-post-creation_en.png has changed
Binary file doc/book/en/images/tutos-base_blog-primary_en.png has changed
Binary file doc/book/en/images/tutos-base_blogs-list_en.png has changed
Binary file doc/book/en/images/tutos-base_form-generic-relations_en.png has changed
Binary file doc/book/en/images/tutos-base_index_en.png has changed
Binary file doc/book/en/images/tutos-base_login-form_en.png has changed
Binary file doc/book/en/images/tutos-base_myblog-blogentry-taggable-commentable-primary_en.png has changed
Binary file doc/book/en/images/tutos-base_myblog-community-custom-primary_en.png has changed
Binary file doc/book/en/images/tutos-base_myblog-community-default-primary_en.png has changed
Binary file doc/book/en/images/tutos-base_myblog-community-taggable-primary_en.png has changed
Binary file doc/book/en/images/tutos-base_myblog-custom-footer_en.png has changed
Binary file doc/book/en/images/tutos-base_myblog-schema_en.png has changed
Binary file doc/book/en/images/tutos-base_myblog-siteinfo_en.png has changed
Binary file doc/book/en/images/tutos-base_schema_en.png has changed
Binary file doc/book/en/images/tutos-base_siteconfig_en.png has changed
Binary file doc/book/en/images/tutos-base_user-menu_en.png has changed
--- a/doc/book/en/tutorials/base/blog-in-five-minutes.rst	Mon Jan 17 12:42:27 2011 +0100
+++ b/doc/book/en/tutorials/base/blog-in-five-minutes.rst	Mon Jan 17 12:43:07 2011 +0100
@@ -1,6 +1,6 @@
 .. -*- coding: utf-8 -*-
 
-.. _BlogFiveMinutes:
+.. _TutosBaseBlogFiveMinutes:
 
 Get a blog running in five minutes!
 -----------------------------------
@@ -17,23 +17,42 @@
 
     cubicweb-ctl create blog myblog
 
-And start it::
+You'll be asked a few questions, and you can keep the default answer for most of
+them. The one question you'll have to think about is the database you'll want to
+use for that instance. For a quick test, if you don't have `postgresql` installed
+and configured (see :ref:`PostgresqlConfiguration`), it's higly recommended to
+choose `sqlite` when asked for which database driber to use, since it has a much
+simple setup (no database server needed).
+
+One the process is completed (including database initialisation), you can start
+your instance by using: ::
 
     cubicweb-ctl start -D myblog
 
-The -D option is the debugging mode of |cubicweb|, removing it will lauch the
-instance in the background.
+The `-D` option activate the debugging mode, removing it will launch the instance
+as a daemon in the background.
+
+
+About file-system permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Permission
-~~~~~~~~~~
+Unless you installed from sources, above commands assumes that you have root
+access to the :file:`/etc/` path. In order to initialize your instance as a
+regulary user, within your home directory, you can use the :envvar:`CW_MODE`
+environment variable: ::
 
-This command assumes that you have root access to the /etc/ path. In order to initialize your instance as a `user` (from scratch), please check your current PYTHONPATH then create the ~/etc/cubicweb.d directory.
+  export CW_MODE=user
+
+then create a :file:`~/etc/cubicweb.d` directory that will hold your instances.
+
+More information about how to configure your own environment in :ref:`ResourceMode`.
+
 
 Instance parameters
 ~~~~~~~~~~~~~~~~~~~
 
-If you would like to change some instance parameters, for example, the main
-database host or the user name, edit the `sources` file located in the
+If you would like to change database parameters such as the database host or the
+user name used to connect to the database, edit the `sources` file located in the
 :file:`/etc/cubicweb.d/myblog` directory.
 
 Then relaunch the database creation::
@@ -43,8 +62,7 @@
 Other paramaters, like web server or emails parameters, can be modified in the
 :file:`/etc/cubicweb.d/myblog/all-in-one.conf` file.
 
-This is it. Your blog is running. Visit http://localhost:8080 and enjoy it! This
-blog is fully functionnal. The next section section will present the way to
-develop new cubes and customizing the look of your instance.
+You'll have to restart the instance after modification in one of those files.
 
+This is it. Your blog is functionnal and running. Visit http://localhost:8080 and enjoy it!
 
--- a/doc/book/en/tutorials/base/components.rst	Mon Jan 17 12:42:27 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _cubes:
-
-Cubes
------
-
-Standard library
-~~~~~~~~~~~~~~~~
-
-A library of standard cubes are available from `CubicWeb Forge`_
-Cubes provide entities and views.
-
-The available application entities in standard cubes are:
-
-* addressbook: PhoneNumber and PostalAddress
-
-* basket: Basket (like a shopping cart)
-
-* blog: Blog (a *very* basic blog)
-
-* classfolder: Folder (to organize things but grouping them in folders)
-
-* classtags: Tag (to tag anything)
-
-* comment: Comment (to attach comment threads to entities)
-
-* 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)
-
-.. _`CubicWeb Forge`: http://www.cubicweb.org/project/
-
-Adding comments to BlogDemo
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To import a cube in your instance just change the line in the
-``__pkginfo__.py`` file and verify that the cube you are planning
-to use is listed by the command ``cubicweb-ctl list``.
-For example::
-
-    __use__ = ('comment',)
-
-will make the ``Comment`` entity available in your ``BlogDemo``
-cube.
-
-Change the schema to add a relationship between ``BlogEntry`` and
-``Comment`` and you are done. Since the comment cube defines the
-``comments`` relationship, adding the line::
-
-    comments = ObjectRelation('Comment', cardinality='1*', composite='object')
-
-to the definition of a ``BlogEntry`` will be enough.
-
-Synchronize the data model
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Once you modified your data model, you need to synchronize the
-database with your model. For this purpose, *CubicWeb* provides
-a very useful command ``cubicweb-ctl shell blogdemo`` which
-launches an interactive shell where you can enter migration
-commands (see :ref:`cubicweb-ctl` for more details)).
-As you added the cube named `comment`, you need to run:
-
-::
-
-  add_cube('comment')
-
-You can now start your instance and comment your blog entries.
--- a/doc/book/en/tutorials/base/conclusion.rst	Mon Jan 17 12:42:27 2011 +0100
+++ b/doc/book/en/tutorials/base/conclusion.rst	Mon Jan 17 12:43:07 2011 +0100
@@ -3,11 +3,16 @@
 What's next?
 ------------
 
-In this chapter, we have seen have you can, right after the installation of *CubicWeb*, build a web application in five minutes by defining a data model. Everything is there already: views, templates, permissions, etc.
+In this tutorial, we have seen have you can, right after the installation of
+|cubicweb|, build a web application in a few minutes by defining a data model as
+assembling cubes. You get a working application that you can then customize there
+and there while keeping something that works. This is important in agile
+development practices, you can right from the start of the project show things
+to customer and so take the right decision early in the process.
 
-The next step is to change the design and learn about the many features available to customize and extend your application: RSS channels (:ref:`XmlAndRss`), events (:ref:`hooks`), support of sources such as
-Google App Engine (:ref:`GoogleAppEngineSource`), etc.
-
-You will find more `tutorials and howtos`_ in the blog published on the CubicWeb.org website.
+The next steps will be to discover hooks, security, data sources, digging deeper
+into view writing and interface customisation... Yet a lot of fun stuff to
+discover! You will find more `tutorials and howtos`_ in the blog published on the
+CubicWeb.org website.
 
 .. _`tutorials and howtos`: http://www.cubicweb.org/view?rql=Any+X+ORDERBY+D+DESC+WHERE+X+is+BlogEntry%2C+T+tags+X%2C+T+name+IN+%28%22tutorial%22%2C+%22howto%22%29%2C+X+creation_date+D
--- a/doc/book/en/tutorials/base/create-cube.rst	Mon Jan 17 12:42:27 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,437 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Steps:
-
-Steps for creating your cube
-----------------------------
-
-The following steps will help you to create and customize a new cube.
-
-1. :ref:`CreateYourCube`
-
-   Create the directory to hold the code of your cube. The most important files
-   that will be useful to customize your newly created cube are:
-
-     * schema.py: contains the data model
-     * views.py: contains your custom views
-     * entities.py: contains logic on top of the data model
-
-   The detailed structure of the cube directory is described in
-   :ref:`cubelayout`.
-
-2. :ref:`DefineDataModel`
-
-   Define the data model of your application.
-
-3. :ref:`ExploreYourInstance`
-
-   Create, run, and explore an instance of your cube.
-
-4. :ref:`DefineViews`
-
-   Customize the views of your data: how and which part of your data are showed.
-
-   .. note::
-
-     views usually do not define the look'n'feel and the design of your
-     application. For that, you will use CSS and the files located 'blog/data/'.
-
-
-5. :ref:`DefineEntities`
-
-   Define your own entities to add useful functions when you manipulate your
-   data, especially when you write view.
-
-
-.. _CreateYourCube:
-
-Create your cube
-----------------
-
-The packages ``cubicweb`` and ``cubicweb-dev`` install a command line
-tool for |cubicweb| called ``cubicweb-ctl``. This tool provides a wide
-range of commands described in details in :ref:`cubicweb-ctl`.
-
-Once your |cubicweb| development environment is set up, you can create
-a new cube::
-
-  cubicweb-ctl newcube blog
-
-This will create in the cubes directory (:file:`/path/to/forest/cubes` for Mercurial
-installation, :file:`/usr/share/cubicweb/cubes` for debian packages installation)
-a directory named ``blog`` reflecting the structure described in :ref:`Concepts`.
-
-
-For packages installation, you can still create new cubes in your home directory
-using the following configuration. Let's say you want to develop your new cubes
-in `~src/cubes`, then set the following environment variables: ::
-
-  CW_CUBES_PATH=~/src/cubes
-  CW_MODE=user
-
-and then create your new cube using: ::
-
-  cubicweb-ctl newcube --directory=~/src/cubes blog
-
-
-.. _DefineDataModel:
-
-Define your data model
-----------------------
-
-The data model or schema is the core of your |cubicweb| application.
-It defines the type of content your application will handle.
-
-The data model of your cube ``blog`` is defined in the file ``schema.py``:
-
-.. sourcecode:: python
-
-  from yams.buildobjs import EntityType, SubjectRelation, String, Date
-
-  class Blog(EntityType):
-    title = String(maxsize=50, required=True)
-    description = String()
-
-  class BlogEntry(EntityType):
-    title = String(required=True, fulltextindexed=True, maxsize=256)
-    publish_date = Date(default='TODAY')
-    content = String(required=True, fulltextindexed=True)
-    entry_of = SubjectRelation('Blog', cardinality='?*')
-
-The first step is the import of the :class:`EntityType` (generic class for entity
-and attributes that will be used in both Blog and BlogEntry entities.
-
-A Blog has a title and a description. The title is a string that is
-required and must be less than 50 characters.  The
-description is a string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a content. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The content is a string that will be indexed in
-the database full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that links it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-
-.. _ExploreYourInstance:
-
-Create and explore your instance
---------------------------------
-.. _CreateYourInstance:
-
-Create your instance
-~~~~~~~~~~~~~~~~~~~~
-
-To use this cube as an instance and create a new instance named ``blogdemo``, do::
-
-  cubicweb-ctl create blog blogdemo
-
-This command will create the corresponding database and initialize it.
-
-
-.. _WelcomeToYourWebInstance:
-
-Welcome to your web instance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Start your instance in debug mode with the following command: ::
-
-  cubicweb-ctl start -D blogdemo
-
-
-You can now access your web instance to create blogs and post messages
-by visiting the URL http://localhost:8080/.
-
-A login form will appear. By default, the instance will not allow anonymous
-users to enter the instance. To login, you need then use the admin account
-you created at the time you initialized the database with ``cubicweb-ctl
-create``.
-
-.. image:: ../../images/login-form.png
-
-
-Once authenticated, you can start playing with your instance
-and create entities.
-
-.. image:: ../../images/blog-demo-first-page.png
-
-Please notice that so far, the |cubicweb| framework managed all aspects of
-the web application based on the schema provided at the beginning.
-
-.. _AddEntities:
-
-Add entities
-~~~~~~~~~~~~
-
-We will now add entities in our web application.
-
-Add a Blog
-**********
-
-Let us create a few of these entities. Click on the `[+]` at the left of the
-link Blog on the home page. Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the form by
-clicking on ``Validate``.
-
-.. image:: ../../images/cbw-create-blog_en.png
-   :alt: from to create blog
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link that will list for you all the existing Blog.
-You should be seeing a list with a single item ``Tech-blog`` you
-just created.
-
-.. image:: ../../images/cbw-list-one-blog_en.png
-   :alt: displaying a list of a single blog
-
-Clicking on this item will get you to its detailed description except
-that in this case, there is not much to display besides the name and
-the phrase ``everything about technology``.
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-.. image:: ../../images/cbw-list-two-blog_en.png
-   :alt: displaying a list of two blogs
-
-Add a BlogEntry
-***************
-
-Get back to the home page and click on [+] at the left of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``Validate``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``.
-
-You could also have, at the time you started to fill the form for a
-new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
-combobox titled ``add relation`` would have showed up.
-
-
-.. image:: ../../images/cbw-add-relation-entryof_en.png
-   :alt: editing a blog entry to add a relation to a blog
-
-Validate the changes by clicking ``Validate``. The entity BlogEntry
-that is displayed now includes a link to the entity Blog named
-``MyLife``.
-
-.. image:: ../../images/cbw-detail-one-blogentry_en.png
-   :alt: displaying the detailed view of a blogentry
-
-Note that all of this was handled by the framework and that the only input
-that was provided so far is the schema. To get a graphical view of the schema,
-point your browser to the URL http://localhost:8080/schema
-
-.. image:: ../../images/cbw-schema_en.png
-   :alt: graphical view of the schema (aka data-model)
-
-
-.. _DefineViews:
-
-Define your entity views
-------------------------
-
-Each entity defined in a model is associated with default views
-allowing different renderings of the data. You can redefine each of
-them according to your needs and preferences. So let's see how the
-views are defined.
-
-
-The view selection principle
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A view is defined by a Python class which includes:
-
-  - an identifier (all objects in |cubicweb| are recorded in a
-    registry and this identifier will be used as a key)
-
-  - a filter to select the result sets it can be applied to
-
-A view has a set of methods complying with the `View` class interface
-(`cubicweb.common.view`).
-
-|cubicweb| provides a lot of standard views for the type `EntityView`;
-for a complete list, read the code in directory ``cubicweb/web/views/``.
-
-A view is applied on a `result set` which contains a set of entities
-we are trying to display. |cubicweb| uses a selector mechanism which
-computes for each available view a score: the view with the highest
-score is then used to display the given `result set`.  The standard
-library of selectors is in ``cubicweb.selector``.
-
-It is possible to define multiple views for the same identifier
-and to associate selectors and filters to allow the application
-to find the most appropriate way to render the data.
-
-For example, the view named ``primary`` is the one used to display a
-single entity. We will now show you how to create a primary view for
-BlogEntry.
-
-
-Primary view customization
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you wish to modify the way a `BlogEntry` is rendered, you will have
-to subclass the `primary` view, for instance in the module ``views``
-of the cube ``cubes/blog/views.py``.
-
-The standard primary view is the most sophisticated view of all. It
-has more than a call() method. It is a template. Actually the entry
-point calls the following sequence of (redefinable) methods:
-
- * render_entity_title
-
- * render_entity_attributes
-
- * render_entity_relations
-
-We can see all of them already in action in the blog entry view. This is all
-described in more details in :ref:`primary_view`.
-
-We can for example add in front of the publication date a prefix
-specifying that the date we see is the publication date.
-
-To do so, please apply the following changes:
-
-.. sourcecode:: python
-
-  from cubicweb.selectors import is_instance
-  from cubicweb.web.views import primary
-
-  class BlogEntryPrimaryView(primary.PrimaryView):
-      __select__ = is_instance('BlogEntry')
-
-      def render_entity_attributes(self, entity):
-          self.w(u'<p>published on %s</p>' %
-                 entity.publish_date.strftime('%Y-%m-%d'))
-          super(BlogEntryPrimaryView, self).render_entity_attributes(entity)
-
-.. note::
-  When a view is modified, it is not required to restart the instance
-  server. Save the Python file and reload the page in your web browser
-  to view the changes.
-
-You can now see that the publication date has a prefix.
-
-.. image:: ../../images/cbw-update-primary-view_en.png
-   :alt: modified primary view
-
-
-The above source code defines a new primary view for ``BlogEntry``.
-
-Since views are applied to result sets and result sets can be tables of
-data, we have to recover the entity from its (row,col)-coordinates.
-The view has a ``self.w()`` method that is used to output data, in our
-example HTML output.
-
-.. note::
-   You can find more details about views and selectors in :ref:`Views`.
-
-
-.. _DefineEntities:
-
-Write entities to add logic in your data
-----------------------------------------
-
-By default, CubicWeb provides a default entity for each data type defined in the schema.
-A default entity mainly contains the attributes defined in the data model.
-
-You can redefine each entity to provide additional functions to help you write your views.
-
-.. sourcecode:: python
-
-    from cubicweb.entities import AnyEntity
-
-    class BlogEntry(AnyEntity):
-        """customized class for BlogEntry entities"""
-    	__regid__ = 'BlogEntry'
-
-        def display_cw_logo(self):
-            if 'CW' in self.title:
-                return True
-            else:
-                return False
-
-Customizing an entity requires that your entity:
- - inherits from ``cubicweb.entities`` or any subclass
- - defines a ``__regid__`` linked to the corresponding data type of your schema
- - implements the base class by explicitly using ``__implements__``.
-
-We implemented here a function ``display_cw_logo`` which tests if the blog entry title contains 'CW'.
-This function can then be used when you customize your views. For instance, you can modify your previous ``views.py`` as follows:
-
-.. sourcecode:: python
-
- class BlogEntryPrimaryView(primary.PrimaryView):
-     __select__ = is_instance('BlogEntry')
-
-     ...
-
-     def render_entity_title(self, entity):
-	 if entity.display_cw_logo():
-	     self.w(u'<image src="http://www.cubicweb.org/doc/en/_static/cubicweb.png"/>')
-	 super(BlogEntryPrimaryView, self).render_entity_title(entity)
-
-Then each blog entry whose title contains 'CW' is shown with the CubicWeb logo in front of it.
-
-.. _UpdatingSchemaAndSynchronisingInstance:
-
-Updating the schema and synchronising the instance
---------------------------------------------------
-
-While developping your cube, you may want to update your data model. Let's say you
-want to add a ``category`` attribute in the ``Blog`` data type. This is called a migration.
-
-The required steps are:
-
-1. modify the file ``schema.py``. The ``Blog`` class looks now like this:
-
-.. sourcecode:: python
-
- class Blog(EntityType):
-   title = String(maxsize=50, required=True)
-   description = String()
-   category = String(required=True, vocabulary=(_('Professional'), _('Personal')), default='Personal')
-
-2. stop your ``blogdemo`` instance:
-
-.. sourcecode:: bash
-
-  cubicweb-ctl stop blogdemo
-
-3. start the cubicweb shell for your instance by running the following command:
-
-.. sourcecode:: bash
-
-  cubicweb-ctl shell blogdemo
-
-4. at the cubicweb shell prompt, execute:
-
-.. sourcecode:: python
-
- add_attribute('Blog', 'category')
-
-5. restart your instance:
-   
-.. sourcecode:: bash
-
-  cubicweb-ctl start blogdemo
-
-6. modify a blog entity and check that the new attribute
-``category`` has been added.
-
-Of course, you may also want to add relations, entity types, etc. See :ref:`migration`
-for a list of all available migration commands.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/customizing-the-application.rst	Mon Jan 17 12:43:07 2011 +0100
@@ -0,0 +1,532 @@
+.. -*- coding: utf-8 -*-
+
+.. _TutosBaseCustomizingTheApplication:
+
+Customizing your application
+----------------------------
+
+So far so good. The point is that usually, you won't get enough by assembling
+cubes out-of-the-box. You'll want to customize them, have a personal look and
+feel, add your own data model and so on. Or maybe start from scratch?
+
+So let's get a bit deeper and start coding our own cube. In our case, we want
+to customize the blog we created to add more features to it.
+
+
+Create your own cube
+~~~~~~~~~~~~~~~~~~~~
+
+First, notice that if you've installed |cubicweb| using debian packages, you'll
+need the additional ``cubicweb-dev`` package to get the commands necessary to
+|cubicweb| development. All `cubicweb-ctl` commands are described in details in
+:ref:`cubicweb-ctl`.
+
+Once your |cubicweb| development environment is set up, you can create a new
+cube::
+
+  cubicweb-ctl newcube myblog
+
+This will create in the cubes directory (:file:`/path/to/forest/cubes` for source
+installation, :file:`/usr/share/cubicweb/cubes` for debian packages installation)
+a directory named :file:`blog` reflecting the structure described in
+:ref:`cubelayout`.
+
+For packages installation, you can still create new cubes in your home directory
+using the following configuration. Let's say you want to develop your new cubes
+in `~src/cubes`, then set the following environment variables: ::
+
+  CW_CUBES_PATH=~/src/cubes
+
+and then create your new cube using: ::
+
+  cubicweb-ctl newcube --directory=~/src/cubes myblog
+
+.. Note:
+
+   We previously used `myblog` as the name of our *instance*. We're now creating
+   a *cube* with the same name. Both are different things. We'll now try to
+   specify when we talk about one or another, but keep in mind this difference.
+
+
+Cube's metadata
+~~~~~~~~~~~~~~~
+
+A simple set of metadata about your cube are stored in the :file:`__pkginfo__.py`
+file. In our case, we want to extend the blog cube, so we have to tell that our
+cube depends on this cube, by modifying the ``__depends__`` dictionary in that
+file:
+
+.. sourcecode:: python
+
+   __depends__ =  {'cubicweb': '>= 3.10.7',
+                   'cubicweb-blog': None}
+
+where the ``None`` means we do not depends on a particular version of the cube.
+
+
+Extending the data model
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The data model or schema is the core of your |cubicweb| application.  It defines
+the type of content your application will handle. It is defined in the file
+:file:`schema.py` of cubes.
+
+
+Defining our model
+******************
+
+For the sake of example, let's say we want a new entity type named `Community`
+with a name, a description. A `Community` will hold several blogs.
+
+.. sourcecode:: python
+
+  from yams.buildobjs import EntityType, RelationDefinition, String, RichString
+
+  class Community(EntityType):
+      name = String(maxsize=50, required=True)
+      description = RichString()
+
+  class community_blog(RelationDefinition):
+      subject = 'Community'
+      object = 'Blog'
+      cardinality = '*?'
+      composite = 'subject'
+
+The first step is the import from the :mod:`yams` package necessary classes to build
+the schema.
+
+This file defines the following:
+
+* a `Community` has a title and a description as attributes
+
+  - the name is a string that is required and can't be longer than 50 characters
+
+  - the description is a string that is not constrained and may contains rich
+    content such as html or Restructured text.
+
+* a `Commnunity` may be linked to a `Blog` using the `community_blog` relation
+
+  - ``*`` means a community may be linked to 0 to N blog, ``?`` means a blog may
+    be linked to 0 to 1 community. For completeness, remember that you can also
+    use ``+`` for 1 to N, and ``1`` for single, mandatory relation (e.g. one to one);
+
+  - this is a composite relation where `Community` (e.g. the subject of the
+    relation) is the composite. That means that if you delete a community, its
+    blog will be deleted as well.
+
+Of course, there are a lot of other data types and things such as constraints,
+permissions, etc, that may be defined in the schema, but those won't be covered
+in this tutorial.
+
+Notice that our schema refers to the `Blog` entity types which is not defined
+here.  But we know this type is available since we depends on the `blog` cube
+which is defining it.
+
+
+Applying changes to the model into our instance
+***********************************************
+
+Now the problem is that we created an instance using the `blog` cube, not our
+`myblog` cube, so if we don't do anything there is no way that we'll see anything
+changing in the instance.
+
+One easy way, as we've no really valuable data in the instance would be to trash and recreated it::
+
+  cubicweb-ctl stop myblog
+  cubicweb-ctl delete myblog
+  cubicweb-ctl create myblog
+
+Another way is to add our cube to the instance using the cubicweb-ctl shell
+facility. It's a python shell connected to the instance with some special
+commands available to manipulate it (the same as you'll have in migration
+scripts, which are not covered in this tutorial). In that case, we're interested
+in the `add_cube` command: ::
+
+  $ cubicweb-ctl stop myblog
+  $ cubicweb-ctl shell myblog
+  entering the migration python shell
+  just type migration commands or arbitrary python code and type ENTER to execute it
+  type "exit" or Ctrl-D to quit the shell and resume operation
+  >>> add_cube('myblog')
+  >>>
+
+The `add_cube` command is enough since it automatically updates our application
+to the cube'schema. There are plenty of other migration commands of a more finer grain. They are described in :ref:`migration`
+
+As explained, leave the shell by typing Ctrl-D. If you restart the instance and
+take another look at the schema, you'll see that changes to the data model have
+actually been applied (meaning database schema updates and all necessary stuff
+has been done).
+
+.. image:: ../../images/tutos-base_myblog-schema_en.png
+   :alt: the instance'schema after adding our cube
+
+If you follow the 'info' link in the user pop-up menu, you'll also see that the
+instance is using blog and myblog cubes.
+
+.. image:: ../../images/tutos-base_myblog-siteinfo_en.png
+   :alt: the instance'schema after adding our cube
+
+You can now add some community, link them to blog, etc... You'll see that the
+framework provides default views for this entity type (we've not yet defined any
+view for it!), and also that the blog primary view'll show the community it's
+linked to if any. All this thanks to the model driven interface provided by the
+framework.
+
+You'll then be able to redefine each of them according to your needs
+and preferences. We'll now see how to do such thing.
+
+Defining your views
+~~~~~~~~~~~~~~~~~~~
+
+|cubicweb| provides a lot of standard views in directory
+:file:`cubicweb/web/views/`. We already talked about 'primary' and 'list' views,
+which are views which apply to one ore more entities.
+
+A view is defined by a python class which includes:
+
+  - an identifier: all objects used to build the user interface in |cubicweb| are
+    recorded in a registry and this identifier will be used as a key in that
+    registry. There may be multiple views for the same identifier.
+
+  - a *selector*, which is a kind of filter telling how well a view suit to a
+    particular context. When looking for a particular view (e.g. given an
+    identifier), |cubicweb| computes for each available view with that identifier
+    a score which is returned by the selector. Then the view with the highest
+    score is used. The standard library of selectors is in
+    :mod:`cubicweb.selector`.
+
+A view has a set of methods inherited from the :class:`cubicweb.view.View` class,
+though you usually don't derive directly from this class but from one of its more
+specific child class.
+
+Last but not least, |cubicweb| provides a set of default views accepting any kind
+of entities.
+
+Want a proof? Create a community as you've already done for other entity types
+through the index page, you'll then see something like that:
+
+.. image:: ../../images/tutos-base_myblog-community-default-primary_en.png
+   :alt: the default primary view for our community entity type
+
+
+If you notice the weird messages that appear in the page: those are messages
+generated for the new data model, which have no translation yet. To fix that,
+we'll have to use dedicated `cubicweb-ctl` commands:
+
+.. sourcecode: bash
+
+  cubicweb-ctl i18ncube myblog # build/update cube's message catalogs
+  # then add translation into .po file into the cube's i18n directory
+  cubicweb-ctl i18ninstance myblog # recompile instance's message catalogs
+  cubicweb-ctl restart -D myblog # instance has to be restarted to consider new catalogs
+
+You'll then be able to redefine each of them according to your needs and
+preferences. So let's see how to do such thing.
+
+Changing the layout of the application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The layout is the general organization of pages of the site. Views that generates
+the layout ore sometimes refered as 'templates'. They are implemented in the
+framework in the module :mod:`cubicweb.web.views.basetemplates`. By overriding
+classes in this module, you can customize whatever part you wish of the default
+layout.
+
+But notice that |cubicweb| provides a lot of other ways to customize the
+interface, thanks to actions and components (which you can individually
+(de)activate, control their location, customize their look...) as well as
+"simple" CSS customization. You should first try to acheive your goal using such
+fine grained parametrization rather then overriding a whole template, which usually
+embeds customisation access points that you may loose in the process.
+
+But for the sake of example, let's say we want to change the generic page
+footer...  We can simply add to the module ``views`` of our cube,
+e.g. :file:`cubes/myblog/views.py`, the code below:
+
+.. sourcecode:: python
+
+  from cubicweb.web.views import basetemplates
+
+  class MyHTMLPageFooter(basetemplates.HTMLPageFooter):
+
+      def footer_content(self):
+	  self.w(u'This website has been created with <a href="http://cubicweb.org">CubicWeb</a>.')
+
+  def registration_callback(vreg):
+      vreg.register_all(globals().values(), __name__, (MyHTMLPageFooter,))
+      vreg.register_and_replace(MyHTMLPageFooter, basetemplates.HTMLPageFooter)
+
+
+* Our class inherit from the default page footer to ease getting things right,
+  but this is not mandatory.
+
+* When we want to write something to the output stream, we simply call `self.w`,
+  that *must be given an unicode string*.
+
+* The latest function is the more exotic stuff. The point is that without it, you
+  would get an error at display time because the framework woulnd't be able to
+  choose which footer to use between :class:`HTMLPageFooter` and
+  :class:`MyHTMLPageFooter`, since both have the same selector, hence the same
+  score...  In this case, we want our footer to replace the default one, so we've
+  to define a :func:`registration_callback` function to control object
+  registration: the first instruction tells to register everything in the module
+  but the :class:`MyHTMLPageFooter` class, then the second to register it instead
+  of :class:`HTMLPageFooter`. Without this function, everything in the module is
+  registered blindly.
+
+.. Note::
+
+  When a view is modified while running in debug mode, it is not required to
+  restart the instance server. Save the Python file and reload the page in your
+  web browser to view the changes.
+
+We'll now have on every page of the site this simple footer.
+
+
+Primary view customization
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The 'primary' view (e.g. whose identifier is 'primary') is the one used to
+display all information about a single entity. The standard primary view is one
+of the most sophisticated view of all. It has several customisation points, but
+its power comes with `uicfg`, allowing you to control it without having to
+subclass it.
+
+But, this is a bit off-topic for this first tutorial. Let say we simply want a
+custom primary view for my `Community` entity type, using directly the view
+interface without trying to benefit from the default implementation (you should
+do that though if you're rewriting reusable cubes; this is all described in more
+details in :ref:`primary_view`).
+
+
+So... Some code! That we'll put again in the module ``views`` of our cube.
+
+.. sourcecode:: python
+
+  from cubicweb.selectors import is_instance
+  from cubicweb.web.views import primary
+
+  class CommunityPrimaryView(primary.PrimaryView):
+      __select__ = is_instance('Community')
+
+      def cell_call(self, row, col):
+          entity = self.cw_rset.get_entity(row, col)
+          self.w(u'<h1>Welcome to the "%s" community</h1>' % entity.printable_value('name'))
+          if entity.description:
+              self.w(u'<p>%s</p>' % entity.printable_value('description'))
+
+What's going on here?
+
+* Our class inherit from the default primary view, here mainly to get the correct
+  view identifier, since we don't use any of its features.
+
+* We set on it a selector telling that it only applies when trying to display
+  some entity of the `Community` type. This is enough to get an higher score than
+  the default view for entities of this type.
+
+* View applying to entities usually have to define `cell_call` as entry point,
+  where given `row` and `col` arguments tell to which entity in the result set
+  the view is applied. We can then get this entity on the result set
+  (`self.cw_rset`) by using the `get_entity` method.
+
+* To ease thing, we access our entity's attribute for display using its
+  printable_value method, which will handle formating and escaping when
+  necessary. As you can see, you can also access attributes by their name on the
+  entity to get the raw value.
+
+
+You can now reload the page of the community we just created and see the changes.
+
+.. image:: ../../images/tutos-base_myblog-community-custom-primary_en.png
+   :alt: the custom primary view for our community entity type
+
+We've seen here a lot of thing you'll have to deal with to write views in
+|cubicweb|. The good news is that here is almost everything that is then used to
+build higher level layers.
+
+.. Note::
+
+  As things get complicated and the volume of code in your cube increases, you can
+  of course still split your views module into a python package with subpackages.
+
+You can find more details about views and selectors in :ref:`Views`.
+
+
+Write entities to add logic in your data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+|cubicweb| provides an ORM to easily programitically manipulate entities (as
+we've fetched ealier by calling `get_entity` on a reslut set). By default, entity
+types are instances of the :class:`AnyEntity` class, which hold a set of
+predefined methods as well as property automatically generated for
+attributes/relations of the type it represents.
+
+You can redefine each entity to provide additional methods or whatever you want
+to help you write your application. Customizing an entity requires that your
+entity:
+
+- inherits from :class:`cubicweb.entities.AnyEntyt` or any subclass
+
+- defines a :attr:`__regid__` linked to the corresponding data type of your schema
+
+You may then want to add your own methods, override default implementation of some
+method, etc...
+
+.. sourcecode:: python
+
+    from cubicweb.entities import AnyEntity, fetch_config
+
+
+    class Community(AnyEntity):
+        """customized class for Community entities"""
+        __regid__ = 'Community'
+
+        fetch_attrs, fetch_order = fetch_config(['name'])
+
+        def dc_title(self):
+            return self.name
+
+        def display_cw_logo(self):
+            return 'CubicWeb' in self.description
+
+Here :
+
+* we used convenience :func:`fetch_config` function to tell which attributes
+  should be prefetched by the ORM when looking for some related entities of this
+  type, and how they should be ordered
+
+* we overrided standard `dc_title` method, used in various place in the interface
+  to display the entity (though in this case the default implementation would
+  have had the same result)
+
+* we implemented here a method :meth:`display_cw_logo` which tests if the blog
+  entry title contains 'CW'.  It can then be used when you're writing code
+  involving 'Community' entities in your views, hooks, etc. For instance, you can
+  modify your previous views as follows:
+
+.. sourcecode:: python
+
+
+  class CommunityPrimaryView(primary.PrimaryView):
+      __select__ = is_instance('Community')
+
+      def cell_call(self, row, col):
+          entity = self.cw_rset.get_entity(row, col)
+          self.w(u'<h1>Welcome to the "%s" community</h1>' % entity.printable_value('name'))
+          if entity.display_cw_logo():
+              self.w(u'<img src="http://www.cubicweb.org/doc/en/_static/cubicweb.png"/>')
+          if entity.description:
+              self.w(u'<p>%s</p>' % entity.printable_value('description'))
+
+Then each community whose description contains 'CW' is shown with the |cubicweb|
+logo in front of it.
+
+.. Note::
+
+  As for view, you don't have to restart your instance when modifying some entity
+  classes while your server is running in debug mode, the code will be
+  automatically reloaded.
+
+
+Extending the application by using more cubes!
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One of the goal of the |cubicweb| framework was to have truly reusable
+components. To do so, they must both behave nicely when plugged into the
+application and be easily customisable, from the data model to the user
+interface. And I think the result is pretty successful, thanks to system such as
+the selection mecanism and the choice to write views as python code which allow
+use to build our page using true object oriented programming technics, that no
+template langage provides.
+
+
+A library of standard cubes are available from `CubicWeb Forge`_, to address a
+lot of common concerns such has manipulating people, files, things to do, etc. In
+our community blog case, we could be interested for instance in functionnalities
+provided by the `comment` and `tag` cubes. The former provides threaded
+discussion functionalities, the later a simple tag mecanism to classify content.
+Let's say we want to try those. We'll first modify our cube's :file:`__pkginfo__.py`
+file:
+
+.. sourcecode:: python
+
+   __depends__ =  {'cubicweb': '>= 3.10.7',
+                   'cubicweb-blog': None,
+                   'cubicweb-comment': None,
+                   'cubicweb-tag': None}
+
+Now, we'll simply tell on which entity types we want to activate the 'comment'
+and 'tag' facilities by adding respectivly the 'comments' and 'tags' relations on
+them in our schema (:file:`schema.py`).
+
+.. sourcecode:: python
+
+  class comments(RelationDefinition):
+      subject = 'Comment'
+      object = 'BlogEntry'
+      cardinality = '1*'
+      composite = 'object'
+
+  class tags(RelationDefinition):
+      subject = 'Tag'
+      object = ('Community', 'BlogEntry')
+
+
+So in the case above we activated comments on `BlogEntry` entities and tags on
+both `Community` and `BlogEntry`. Various views from both `comment` and `tag`
+cubes will then be automatically displayed when one of those relations is
+supported.
+
+Let's synchronize the data model as we've done earlier: ::
+
+
+  $ cubicweb-ctl stop myblog
+  $ cubicweb-ctl shell myblog
+  entering the migration python shell
+  just type migration commands or arbitrary python code and type ENTER to execute it
+  type "exit" or Ctrl-D to quit the shell and resume operation
+  >>> add_cubes('comment', 'tag')
+  >>>
+
+Then restart the instance. Let's look at a blog entry:
+
+.. image:: ../../images/tutos-base_myblog-blogentry-taggable-commentable-primary_en.png
+   :alt: the primary view for a blog entry with comments and tags activated
+
+As you can see, we now have a box displaying tags and a section proposing to add
+a comment and displaying existing one below the post. All this without changing
+anything in our views, thanks to the design of generic views provided by the
+framework. Though if we take a look at a community, we won't see the tags box!
+That's because by default this box try to locate itself in the left column within
+the white frame, and this column is handled by the primary view we
+hi-jacked. Let's change our view to make it more extensible, by keeping both our
+custom rendering but also extension points provided by the default
+implementation.
+
+
+.. sourcecode:: python
+
+  class CommunityPrimaryView(primary.PrimaryView):
+      __select__ = is_instance('Community')
+
+      def render_entity_title(self, entity):
+	  self.w(u'<h1>Welcome to the "%s" community</h1>' % entity.printable_value('name'))
+
+      def render_entity_attributes(self, entity):
+	  if entity.display_cw_logo():
+	      self.w(u'<img src="http://www.cubicweb.org/doc/en/_static/cubicweb.png"/>')
+	  if entity.description:
+	      self.w(u'<p>%s</p>' % entity.printable_value('description'))
+
+It appears now properly:
+
+.. image:: ../../images/tutos-base_myblog-community-taggable-primary_en.png
+   :alt: the custom primary view for a community entry with tags activated
+
+You can control part of the interface independantly from each others, piece by
+piece. Really.
+
+
+
+.. _`CubicWeb Forge`: http://www.cubicweb.org/project
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/base/discovering-the-ui.rst	Mon Jan 17 12:43:07 2011 +0100
@@ -0,0 +1,158 @@
+
+.. _TutosBaseDiscoveringTheUI:
+
+Discovering the web interface
+-----------------------------
+
+You can now access your web instance to create blogs and post messages
+by visiting the URL http://localhost:8080/.
+
+By default, anonymous access is disabled, so a login form will appear. If you
+asked to allow anonymous access when initailizing the instance, click on the
+'login' link in the top right hand corner. To login, you need then use the admin
+account you specified at the time you initialized the database with
+``cubicweb-ctl create``.
+
+.. image:: ../../images/tutos-base_login-form_en.png
+   :alt: the login form
+
+
+Once authenticated, you can start playing with your instance. The default index
+page looks like the following:
+
+.. image:: ../../images/tutos-base_index_en.png
+   :alt: the index page
+
+
+Minimal configuration
+~~~~~~~~~~~~~~~~~~~~~
+
+Before creating entities, let's change that 'unset title' thing that appeared
+there and there. This is handled using |cubicweb| properties system. To set it,
+click on the 'site configuration link' in the pop-up menu behind your login name
+in the upper left-hand corner
+
+.. image:: ../../images/tutos-base_user-menu_en.png
+   :alt: the user pop-up menu
+
+The site title is in the 'Ui' section. Simply set it to the desired value and
+click the 'validate' button.
+
+.. image:: ../../images/tutos-base_siteconfig_en.png
+   :alt: the site configuration form
+
+You should see a 'changes applied' message appear. You can now go back to the
+index page by clicking on the |cubicweb| logo in the upper left-hand corner.
+
+You will much likely still see 'unset title' at this point. This is because by
+default the index page is cached. Force a refresh of the page (by typing Ctrl-R
+in firefox for instance) and you should now see the title you entered.
+
+
+Adding entities
+~~~~~~~~~~~~~~~
+
+The ``blog`` cube defines several entity types, among them ``Blog`` which is a
+container for ``BlogEntry`` (e.g. post) on a particular topic. We can get a
+graphical view of the schema by clicking on the 'site schema' link in the user
+pop-up menu we've already seen:
+
+.. image:: ../../images/tutos-base_schema_en.png
+   :alt: graphical view of the schema (aka data-model)
+
+Nice isn't it? Notice that this, as most other stuff we'll see in this tutorial,
+is generated by the framework according to the model of the application. In our
+case, the model defined by the ``blog`` cube.
+
+Now let us create a few of these entities.
+
+
+Add a blog
+**********
+
+Clicking on the `[+]` at the left of the 'Blog' link on the index page will lead
+you to an HTML form to create a blog.
+
+.. image:: ../../images/tutos-base_blog-form_en.png
+   :alt: the blog creation form
+
+For instance, call this new blog 'Tech-blog' and type in 'everything about
+technology' as the description , then validate the form by clicking on
+'Validate'. You'll be redirected to the `primary` view of the newly created blog.
+
+.. image:: ../../images/tutos-base_blog-primary_en.png
+   :alt: the blog primary view
+
+
+Add a blog post
+***************
+
+There are several way to add a blog entry. The simplest is to click on the 'add
+blog entry' link in the actions box on viewing the blog we've juste created.
+You'll then see a form to create a post, with a 'blog entry of' selector preset
+to the blog we're coming from. Enter a title, some content, click the 'validate'
+button and you're done. You'll be redirected to the blog primary view, though you
+now see that it contains the blog post you've just created.
+
+.. image:: ../../images/tutos-base_blog-primary-after-post-creation_en.png
+   :alt: the blog primary view after creation of a post
+
+Notice there are some new boxes that appears in the left column.
+
+You can achieve the same thing by following the same path as we did for the blog
+creation, e.g. by clicking on the `[+]` at the left of the 'Blog entry' link on
+the index page. The diffence being that since there is now context information,
+the 'blog entry of' selector won't be preset to the blog.
+
+
+If you click on the 'modify' link of the action box, you are back to the form to
+edit the entity you just created, except that the form now has another section
+with a combo-box entitled 'add relation'. It provices a generic way to edit
+relations which don't appears in the above form. Choose the relation you want to
+add and a second combobox appears where you can pick existing entities.  If there
+are too much of them, you'll be proposed to navigate (so go away from the form to
+go back to it later, once you've selected the entity you want to link with).
+
+.. image:: ../../images/tutos-base_form-generic-relations_en.png
+   :alt: the generic relations combobox
+
+This combobox can't appear until the entity is actually created. That's why you
+haven't seen it at creation time. You could also have hit 'Apply' instead of
+'validate' and it would have showed up.
+
+
+About ui auto-adaptation
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+One thing among other that makes |cubicweb| different than other framework is
+its automatic user interface that adapts itself according to the data being
+displayed. Let's see an example.
+
+If you go back to the home page an click on the 'Blog' link, you'll be redirected
+to the primary view of the blog, the same we've seen earlier. Now, add another
+blog, go back to the index page, and click again on this link. You'll see
+a very different view (namely the 'list' view).
+
+.. image:: ../../images/tutos-base_blogs-list_en.png
+   :alt: the list view when there are more than one blog to display
+
+This is because in the first case, the framework choosed to use the 'primary'
+view since there were only one entity in the data to be displayed. Now that there
+are two entities, the 'list' view is more appropriate and hence has been used.
+
+There are various other places where it's able to adapt to display data in the best
+way, the main being provided by views *selection* mecanism that will be detailled
+later.
+
+
+Digging deeper
+~~~~~~~~~~~~~~
+
+By following principles explained below, you should now be able to create new
+user to your application, to configure with a finer grain, etc... You'll notice
+that the index page list a lot of types you don't know about. Most are built-in
+type provided by the framework to make work the whole system. You may ignore them
+in a first time and discover them as time goes.
+
+One thing that is worth playing with is the search box. It may be used in various
+way, from simple full text search to advanced queries using the :ref:`RQL` .
\ No newline at end of file
--- a/doc/book/en/tutorials/base/index.rst	Mon Jan 17 12:42:27 2011 +0100
+++ b/doc/book/en/tutorials/base/index.rst	Mon Jan 17 12:43:07 2011 +0100
@@ -1,30 +1,48 @@
 .. -*- coding: utf-8 -*-
 
-.. _Tutorial:
-
-.. _tuto_blog:
+.. _TutosBase:
 
-Building a simple blog
-======================
+Building a simple blog with |cubicweb|
+======================================
 
-*CubicWeb* is a semantic web application framework that favors reuse and
+|cubicweb| is a semantic web application framework that favors reuse and
 object-oriented design.
 
-A `cube` is a component that includes a model defining the data types and a set of
-views to display the data. A cube can be built by assembling other cubes.
+
+This tutorial is designed to help in your very first steps to start with
+|cubicweb|. We will glance through basic concepts such as:
 
-An `instance` is a specific installation of a cube and includes configuration
-files.
+* having an application running by using existing components
+* discovering the default user interface
+* basically extending and customizing the look and feel of that application
+
+More advanced concepts will covered in :ref:`advanced_tutorial`.
 
 
-This tutorial will show how to create a `cube` and how to use it as an
-application to run an `instance`.
+.. _TutosBaseVocab:
+
+Some vocabulary
+---------------
+
+|cubicweb| comes with a few words of vocabulary that you should know to
+understand what we're talking about. To follow this tutorial, you should at least
+know that:
+
+* a `cube` is a component that usually includes a model defining some data types
+  and a set of views to display them. A cube can be built by assembling other
+  cubes;
+
+* an `instance` is a specific installation of one more more cubes and includes
+  configuration files, a web server and a database.
+
+Reading :ref:`Concepts` for more vocabulary will be a must do at some point.
+
+Now, let's start the hot stuff!
 
 .. toctree::
    :maxdepth: 2
 
    blog-in-five-minutes
-   create-cube
-   components
-   maintemplate
+   discovering-the-ui
+   customizing-the-application
    conclusion
--- a/doc/book/en/tutorials/base/maintemplate.rst	Mon Jan 17 12:42:27 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Templates
----------
-
-Look at ``cubicweb/web/views/basetemplates.py`` and you will
-find the base templates used to generate HTML for your application.
-
-A page is composed as indicated on the schema below:
-
-.. image:: ../../images/lax-book_06-main-template-layout_en.png
-
-In this section we will demonstrate a change in one of the main
-interesting template from the three you will look for,
-that is to say, the HTMLPageHeader, the HTMLPageFooter
-and the TheMainTemplate.
-
-
-Customize a template
-~~~~~~~~~~~~~~~~~~~~
-
-Based on the diagram below, each template can be overriden
-by your customized template. To do so, we recommand you create
-a Python module ``blog.views.templates`` to keep it organized.
-In this module you will have to import the parent class you are
-interested as follows: ::
-
-  from cubicweb.web.views.basetemplates import HTMLPageHeader, \
-                                    HTMLPageFooter, TheMainTemplate
-
-and then create your sub-class::
-
-  class MyBlogHTMLPageHeader(HTMLPageHeader):
-      ...
-
-Customize header
-`````````````````
-
-Let's now move the search box in the header and remove the login form from the
-header. We'll show how to move it to the left column of the user interface.
-
-Let's say we do not want anymore the login menu to be in the header
-
-First, to remove the login menu, we just need to comment out the display of the
-login graphic component such as follows:
-
-.. sourcecode:: python
-
-  class MyBlogHTMLPageHeader(HTMLPageHeader):
-
-      def main_header(self, view):
-          """build the top menu with authentification info and the rql box"""
-          self.w(u'<table id="header"><tr>\n')
-          self.w(u'<td id="firstcolumn">')
-          self._cw.vreg.select_component('logo', self._cw, self.cw_rset).dispatch(w=self.w)
-          self.w(u'</td>\n')
-          # appliname and breadcrumbs
-          self.w(u'<td id="headtext">')
-          comp = self._cw.vreg.select_component('appliname', self._cw, self.cw_rset)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w)
-          comp = self._cw.vreg.select_component('breadcrumbs', self._cw, self.cw_rset, view=view)
-          if comp and comp.propval('visible'):
-              comp.dispatch(w=self.w, view=view)
-          self.w(u'</td>')
-          # logged user and help
-          #self.w(u'<td>\n')
-          #comp = self._cw.vreg.select_component('loggeduserlink', self._cw, self.cw_rset)
-          #comp.dispatch(w=self.w)
-          #self.w(u'</td><td>')
-
-          self.w(u'<td>')
-          helpcomp = self._cw.vreg.select_component('help', self._cw, self.cw_rset)
-          if helpcomp: # may not be available if Card is not defined in the schema
-              helpcomp.dispatch(w=self.w)
-          self.w(u'</td>')
-          # lastcolumn
-          self.w(u'<td id="lastcolumn">')
-          self.w(u'</td>\n')
-          self.w(u'</tr></table>\n')
-          self.template('logform', rset=self.cw_rset, id='popupLoginBox', klass='hidden',
-                        title=False, message=False)
-
-
-
-.. image:: ../../images/lax-book_06-header-no-login_en.png
-
-Customize footer
-````````````````
-
-If you want to change the footer for example, look
-for HTMLPageFooter and override it in your views file as in:
-
-.. sourcecode:: python
-
-  from cubicweb.web.views.basetemplates import HTMLPageFooter
-
-  class MyHTMLPageFooter(HTMLPageFooter):
-
-      def call(self, **kwargs):
-          self.w(u'<div class="footer">')
-          self.w(u'This website has been created with <a href="http://cubicweb.org">CubicWeb</a>.')
-          self.w(u'</div>')
-
-Updating a view does not require any restart of the server. By reloading
-the page you can see your new page footer.
-
-
-TheMainTemplate
-```````````````
-
-.. _TheMainTemplate:
-
-The MainTemplate is a bit complex as it tries to accomodate many
-different cases. We are now about to go through it and cutomize entirely
-our application.
-
-TheMainTemplate is responsible for the general layout of the entire application.
-It defines the template of ``__regid__ = main`` that is used by the application. Is
-also defined in ``cubicweb/web/views/basetemplates.py`` another template that can
-be used based on TheMainTemplate called SimpleMainTemplate which does not have
-a top section.
-
-.. image:: ../../images/lax-book_06-simple-main-template_en.png
-
-.. XXX
-.. [WRITE ME]
-
-* customize MainTemplate and show that everything in the user
-  interface can be changed
-