merge
authorSandrine Ribeau <sandrine.ribeau@logilab.fr>
Tue, 09 Dec 2008 16:20:00 -0800
changeset 200 a4f8a5fb3c3f
parent 199 c603087373cd (diff)
parent 196 6232bdc705ac (current diff)
child 201 12e13120c56e
merge
--- a/doc/book/en/B040-define-workflows.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/B040-define-workflows.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -1,7 +1,9 @@
 .. -*- coding: utf-8 -*-
 
+.. _Workflow:
+
 Workflow definition
-======================
+===================
 
 General
 -------
--- a/doc/book/en/B080-internationalization.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/B080-internationalization.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -18,42 +18,42 @@
 
 * in your application : handle the translation catalog
  
-String internalization
-----------------------
+String internationalization
+---------------------------
 
 In the Python code and cubicweb-tal templates translatable strings can be
 marked in one of the following ways :
 
  * by using the *built-in* function `_` ::
 
-   class PrimaryView(EntityView):
-       """the full view of an non final entity"""
-       id = 'primary'
-       title = _('primary')
+     class PrimaryView(EntityView):
+         """the full view of an non final entity"""
+         id = 'primary'
+         title = _('primary')
 
   OR
 
  * by using the equivalent request's method ::
    
-   class NoResultView(EmptyRsetView):
-       """default view when no result has been found"""
-       id = 'noresult'
+     class NoResultView(EmptyRsetView):
+         """default view when no result has been found"""
+         id = 'noresult'
     
-       def call(self, **kwargs):
-           self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
-               % self.req._('No result matching query'))
+         def call(self, **kwargs):
+             self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
+                 % self.req._('No result matching query'))
 
 The goal of the *built-in* function `_` is only **to mark the
-translatable strings**, it will only return the translation string
-it-self, but not it's translation.
+translatable strings**, it will only return the string to translate
+it-self, but not its translation.
 
-In the other hand the request's method `_` is ment to retrive the
+In the other hand the request's method `self.req._` is meant to retrieve the
 proper translation of translation strings in the requested language.
 
 Translations in cubicweb-tal template can also be done with TAL tags
 `i18n:content` and `i18n:replace`.
 
-Note ::
+.. note::
 
    We dont need to mark the translation strings of entities/relations
    used by a particular application's schema as they are generated
@@ -63,22 +63,22 @@
 Handle the translation catalog 
 ------------------------------
 
-Once the internalization is done in your application's code, you need
+Once the internationalization is done in your application's code, you need
 to populate and update the translation catalog. Cubicweb provides the
 following commands for this purpose:
 
 
 * `i18nlibupdate` updates Cubicweb framework's translation
-  catalogs. Unless you work on the framework development, you dont
+  catalogs. Unless you work on the framework development, you don't
   need to use this command.
 
 * `i18nupdate` updates the translation catalogs of *one particular
-  component* (or of all components). FIXME After this command is
+  component* (or of all components). After this command is
   executed you must update the translation files *.po* in the "i18n"
   directory of your template. This command will of course not remove
-  existing translations still in use
+  existing translations still in use.
 
-* `i18ncompile` recompile the transaltion catalogs of *one particular
+* `i18ncompile` recompile the translation catalogs of *one particular
   instance* (or of all instances) after the translation catalogs of
   its components have been updated. This command is automatically
   called every time you create or update your instance. The compiled
--- a/doc/book/en/B090-ui-components.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/B090-ui-components.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -1,5 +1,5 @@
-Autres composants de l'interface web
-====================================
+Others web interface components
+===============================
 
 Actions
 -------
--- a/doc/book/en/B100-hooks.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/B100-hooks.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -1,16 +1,15 @@
 .. -*- coding: utf-8 -*-
 
-Les crochets (*hooks*)
-======================
+Hooks
+=====
 
 XXX FILLME
 
-Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
-relations dans le dépot
+*Hooks* are executed before or after updating an entity or a relation in the
+repository.
 
-Leur prototypes sont les suivants
-
-
+Their prototypes are as follows: 
+    
     * after_add_entity     (session, entity)
     * after_update_entity  (session, entity)
     * after_delete_entity  (session, eid)
--- a/doc/book/en/B110-notifications.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/B110-notifications.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -1,6 +1,6 @@
 .. -*- coding: utf-8 -*-
 
-Gestion de notifications
+Notifications management
 ========================
 
 XXX FILLME
--- a/doc/book/en/B120-migration.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/B120-migration.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -4,215 +4,207 @@
 Migration
 =========
 
-Une des idées de base d'Erudi est la création incrémentale d'application, et
-pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
-une application et tout particulièrement le modèle de données manipulé sans
-perdre les données des instances existantes.
+One of the main concept in `CubicWeb` is to create incremental applications
+and for this purpose multiple actions are provided to facilitate the improvement
+of an application and in particular changes applied to the data model
+without loosing existing data.
 
-La version courante d'un modèle d'application est données dans le fichier
-`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
-
+The current version of an application model is provided in the file
+`__pkginfo__.py` as a tuple of 3 integers.
 
-Gestion des scripts de migrations
----------------------------------
-Les scripts des migrations doivent être placés dans le répertoire `migration` de
-l'application, et nommé de la manière suivante :
+Migration scripts management
+----------------------------
+
+Migration scripts needs to be located in the directory `migration` of your
+application and nammed accordingly:
 
 ::
 
-  <n° de version X.Y.Z>[_<description>]_<mode>.py
+  <version n° X.Y.Z>[_<description>]_<mode>.py
 
-dans lequel : 
+in which : 
 
-* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
-  migrer,
+* X.Y.Z is the model version number to which the script enable to migrate
 
-* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
-  de l'application (serveur RQL, serveur web) le script s'applique en cas
-  d'installation distribuée. Il peut valoir : 
+* *mode* (between the last "_" and the extension ".py") indicates which part
+  of the application (RQL server, web server) the script applies to in case
+  of distributed installation. Its value could be :
 
-  * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
-    et met à jour des fichiers sur le disque (migration de fichier de
-    configuration par exemple).
+  * `common`, applies to the RQL server as well as the web server and updates
+    files on the hard drive (configuration files migration by example).
+
+  * `web`, applies only to the web server and updates files on the hard drive
 
-  * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
-    sur le disque 
+  * `repository`, applies only to the RQL server and updates files on the
+    hard drive
 
-  * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
-    fichiers sur le disque 
-
-  * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
-    données en base (migrations de schéma et de données par ex.)
-
+  * `Any`, applies only to the RQL server and updates data in the database
+    (schema and data migration by example)
 
-Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
-d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
-d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
-des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
-une ligne de la manière suivante : ::
+Again in the directory `migration`, the file `depends.map` allows to indicate
+that to migrate to a particular model version, you always have to first migrate
+to a particular `CubicWeb` version. This file can contains comments (lines
+starting by `#`) and a dependancy is listed as follows: ::
+  
+  <model version n° X.Y.Z> : <cubicweb version n° X.Y.Z>
 
-  <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
-
-Par exemple ::
+By example: ::
 
   0.12.0: 2.26.0
   0.13.0: 2.27.0
   # 0.14 works with 2.27 <= erudi <= 2.28 at least
   0.15.0: 2.28.0
 
+Base context
+------------
 
-Contexte de base
-----------------
-Les identifiants suivants sont préféfinis dans les scripts de migration : 
+The following identifiers are pre-defined in the migration scripts:
 
-* `config`, configuration de l'instance
+* `config`, instance configuration
 
-* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
-  interactif ou non
+* `interactive_mode`, boolean indicating that the script is executed in
+  an intercative mode or not 
 
-* `appltemplversion`, version du modèle d'application de l'instance
+* `appltemplversion`, application model version of the instance
 
-* `applerudiversion`, version erudi de l'instance
+* `applerudiversion`, cubicweb instance version
 
-* `templversion`, version du modéle d'application installée
+* `templversion`, installed application model version
 
-* `erudiversion`, version erudi installée
+* `erudiversion`, installed cubicweb version
 
-* `confirm(question)`, fonction posant une question et retournant vrai si
-  l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
-  interactif) 
+* `confirm(question)`, function interrogating the user and returning true
+  if the user answers yes, false otherwise (always returns true when in a
+  non-interactive mode)
 
-* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
-  internationaliser dans les scripts de migration
+* `_`, function fonction equivalent to `unicode` allowing to flag the strings
+  to internationalize in the migration scripts
 
-Dans les scripts "repository", les identifiants suivant sont également définis :
+In the `repository` scripts, the following identifiers are also defined:
 
-* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
+* `checkpoint`, request confirming and executing a "commit" at checking point
 
-* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
-  cours de migration)
+* `repo_schema`, instance persisting schema (e.g. instance schema of the
+  current migration)
 
-* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
-  version à jour du modèle et de erudi)
+* `newschema`, installed schema on the file system (e.g. schema of 
+  the updated model and erudi)
 
-* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
-  nécessaire ou avantageux de passer par du sql
+* `sqlcursor`, SQL cursor for very rare cases where it is really
+   necessary or beneficial to go through the sql
 
-* `repo`, l'objet repository
+* `repo`, repository object
 
                         
-Migration de schéma
--------------------
-Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
-"repository" : 
+Schema migration
+----------------
+The following functions for schema migration are available in the `repository`
+scripts:
 
-* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
-  nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
-  spécifié il est extrait du schéma à jour.
+* `add_attribute(etype, attrname, attrtype=None, commit=True)`, adds a new
+  attribute to an existing entity type. If the attribute type is not specified, 
+  then it is extracted from the updated schema.
         
-* `drop_attribute(etype, attrname, commit=True)`, supprime un
-  attribut à un type d'entité existante.
+* `drop_attribute(etype, attrname, commit=True)`, removes an attribute from an
+  existing entity type.
 
-* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
+* `rename_attribute(etype, oldname, newname, commit=True)`, rename an attribute
             
-* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
-  d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
-  et ayant un type d'entité connu à l'autre extrémité vont également être
-  ajoutées.
+* `add_entity_type(etype, auto=True, commit=True)`, adds a new entity type.
+  If `auto` is True, all the relations using this entity type and having a known
+  entity type on the other hand will automatically be added.
 
-* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
-  les relations l'utilisant.
+* `drop_entity_type(etype, commit=True)`, removes an entity type and all the 
+  relations using it.
 
-* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
+* `rename_entity_type(oldname, newname, commit=True)`, renames an entity type
             
-* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
-  de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
-  type seront également ajoutées.
+* `add_relation_type(rtype, addrdef=True, commit=True)`, adds a new relation
+  type. If `addrdef` is True, all the relations definitions of this type will
+  be added.
+
+* `drop_relation_type(rtype, commit=True)`, removes a relation type and all the
+  definitions of this type.
 
-* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
-  toutes les définitions de ce type.
+* `rename_relation(oldname, newname, commit=True)`, renames a relation.
+
+* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, adds a new
+  relation definition.
+
+* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, removes
+  a relation definition.
 
-* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
-
-* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
-  définition de relation.
-
-* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
-  une définition de relation.
-
-* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
-  d'un type d'entité ou de relation
+* `synchronize_permissions(ertype, commit=True)`, synchronizes permissions on
+  an entity type or relation type.
         
-* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
-  permissions d'un type de relation.
+* `synchronize_rschema(rtype, commit=True)`, synchronizes properties and permissions
+  on a relation type.
                 
-* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
-  permissions d'un type d'entité.
+* `synchronize_eschema(etype, commit=True)`, synchronizes properties and persmissions
+  on an entity type.
     
-* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
-  schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
-  de relations ni de définitions de relation).
+* `synchronize_schema(commit=True)`, synchronizes the persisting schema with the
+  updated schema (but without adding or removing new entity types, relations types 
+  or even relations definitions).
         
-* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
-  les propriétés d'une definition de relation en utilisant les arguments nommés
-  pour les propriétés à changer.
+* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, changes
+  properties of a relation definition by using the nammed parameters of the properties
+  to change.
+
+* `set_widget(etype, rtype, widget, commit=True)`, changes the widget used for the
+  relation <rtype> of entity type <etype>.
+
+* `set_size_constraint(etype, rtype, size, commit=True)`, changes the size constraints
+  for the relation <rtype> of entity type <etype>.
+
+Data migration
+--------------
+The following functions for data migration are available in the `repository` scripts:
+
+* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, executes an arbitrary RQL
+  query, either to interrogate or update. A result set object is returned.  
+
+* `add_entity(etype, *args, **kwargs)`, adds a nes entity type of the given
+  type. The attributes and relations values are specified using the nammed and
+  positionned parameters.
+
+Workflow creation
+-----------------
 
-* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
-  pour la relation <rtype> du type d'entité <etype>
+The following functions for workflow creation are available in the `repository`
+scripts:
+
+* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, adds a new state
+  in the workflow.
+    
+* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`, 
+  adds a new transition in the workflow.
+
+You can find more details about workflows in the chapter :ref:`Workflow` .
 
-* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
-  de taille pour la relation <rtype> du type d'entité <etype>
+Configuration migration
+-----------------------
+
+The following functions for configuration migration are available in all the
+scripts:
+
+* `option_renamed(oldname, newname)`, indicates that an option has been renammed
+
+* `option_group_change(option, oldgroup, newgroup)`, indicates that an option does not
+  belong anymore to the same group.
+
+* `option_added(oldname, newname)`, indicates that an option has been added.
+
+* `option_removed(oldname, newname)`, indicates that an option has been deleted.
 
 
-Migration de données
---------------------
-Les fonctions de migration de données suivantes sont disponibles dans les scripts
-"repository" : 
-
-* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
-  requête rql arbitraire, d'interrogation ou de modification. Un objet result
-  set est retourné.
-
-* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
-  données. La valeur des attributs et relations est spécifiée en utilisant les
-  arguments nommés et positionnels.
-
-  
-Création de workflow
---------------------
-Les fonctions de création de workflow suivantes sont disponibles dans les scripts
-"repository" : 
-
-* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
-  nouvel état de workflow
-    
-* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`, 
-  ajoute une nouvelle transtion de workflow
+Others migration functions
+--------------------------
+Those functions are only used for low level operations that could not be 
+accomplished otherwise or to repair damaged databases during interactive 
+session. They are available in the `repository` scripts:
 
-Migration de configuration
---------------------------
-Les fonctions de migration de configuration suivantes sont disponibles dans tout
-les scripts : 
-
-* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
-
-* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
-  changé de groupe
-
-* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
-
-* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
-
-
-Autres fonctions de migration
------------------------------
-Ces fonctions ne sont utilisés que pour des opérations de bas niveau
-irréalisables autrement ou pour réparer des bases cassées lors de session
-interactive. Elles sont disponibles dans les scripts "repository".
-
-* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
-  arbitraire, à n'utiliser 
-
+* `sqlexec(sql, args=None, ask_confirm=True)`, executes an arbitrary SQL query
 * `add_entity_type_table(etype, commit=True)`
 * `add_relation_type_table(rtype, commit=True)`
 * `uninline_relation(rtype, commit=True)`
--- a/doc/book/en/B130-tests.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/B130-tests.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -3,36 +3,36 @@
 Tests
 =====
 
-Écriture de tests unitaires
----------------------------
-Le framework de test fournit principalement deux classes de tests dans le module
-`ginco.devtools.apptest`:
+Unit tests
+----------
 
-* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
-* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
+`CubicWeb` framework provides essentially two Python test classes in the
+module `cubicweb.devtools.apptest`:
 
-Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
-rendant l'écriture de test puissante et rapide.
+* `EnvBasedTC`, to simulate a complete environment (web + repository)
+* `RepositoryBasedTC`, to simulate a repository environment only
 
-XXXFILLME describe API
+Thos two classes almost have the same interface and offers numerous methods to
+write tests rapidely and efficiently.
 
-Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
-unitaires ou fonctionnels pour vos entités, vues, crochets...
+XXX FILLME describe API
 
+In most of the cases, you will inherit `EnvBasedTC` to write Unittest or
+functional tests for your entities, views, hooks, etc...
 
-Test des courriels de notifications
-```````````````````````````````````
-Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
-envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
-liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
-et `RepositoryBasedTC`).
+Email notifications tests
+-------------------------
+When running tests potentially generated e-mails are not really
+sent but is found in the list `MAILBOX` of module `cubicweb.devtools.apptest`. 
+This list is reset at each test *setUp* (by the setUp of classes `EnvBasedTC`
+and `RepositoryBasedTC`).
 
-Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
-contient des objets ayant deux attributs :
-* `recipients`, la liste des destinataires
-* `msg`, l'objet email.Message
+	
+You can test your notifications by analyzing the contents of this list, which
+contains objects with two attributes:
+* `recipients`, the list of recipients
+* `msg`, object email.Message
 
-
-Tests automatiques
-------------------
+Automatic testing
+-----------------
 XXXFILLME
--- a/doc/book/en/BXXX-templates.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/BXXX-templates.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -7,3 +7,193 @@
 
 * talk about main templates, etc.
 
+
+
+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 go through a couple of the primary templates
+you must be interested in, that is to say, the HTMLPageHeader,
+the HTMLPageFooter and the TheMainTemplate.
+
+
+HTMLPageHeader
+--------------
+
+Let's use a different logo than the default one provided with LAX
+and customize our header.
+
+Customize header
+~~~~~~~~~~~~~~~~
+
+Let's now move the search box in the header and remove the login form
+from the header. We'll show how to move it to the left column of the application.
+
+Let's sat we do not want anymore the login menu to be in the header, but we 
+prefer it to be in the left column just below the logo. As the left column is
+rendered by ``TheMainTemplate``, we will show how to do it in TheMainTemplate_. 
+
+First, to remove the login menu, we just need to comment out the display of the
+login component such as follows : ::
+
+  class MyHTMLPageHeader(HTMLPageHeader):
+    
+      def main_header(self, view):
+          """build the top menu with authentification info and the rql box"""
+          self.w(u'<table id="header"><tr>\n')
+          self.w(u'<td id="firstcolumn">')
+          self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+          self.w(u'</td>\n')
+          # appliname and breadcrumbs
+          self.w(u'<td id="headtext">')
+          comp = self.vreg.select_component('appliname', self.req, self.rset)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w)
+          comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
+          if comp and comp.propval('visible'):
+              comp.dispatch(w=self.w, view=view)
+          self.w(u'</td>')
+          # logged user and help
+          #self.w(u'<td>\n')
+          #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
+          #comp.dispatch(w=self.w)
+          #self.w(u'</td><td>')
+
+          self.w(u'<td>')
+          helpcomp = self.vreg.select_component('help', self.req, self.rset)
+          if helpcomp: # may not be available if Card is not defined in the schema
+              helpcomp.dispatch(w=self.w)
+          self.w(u'</td>')
+          # lastcolumn
+          self.w(u'<td id="lastcolumn">')
+          self.w(u'</td>\n')
+          self.w(u'</tr></table>\n')
+          self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden',
+                        title=False, message=False)
+
+
+
+.. image:: images/lax-book.06-header-no-login.en.png
+
+Let's now move the search box in the top-right header area. To do so, we will
+first create a method to get the search box display and insert it in the header
+table.
+
+::
+
+ from ginco.web.views.basetemplates import HTMLPageHeader
+ class MyHTMLPageHeader(HTMLPageHeader):
+    def main_header(self, view):
+        """build the top menu with authentification info and the rql box"""
+        self.w(u'<table id="header"><tr>\n')
+        self.w(u'<td id="firstcolumn">')
+        self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+        self.w(u'</td>\n')
+        # appliname and breadcrumbs
+        self.w(u'<td id="headtext">')
+        comp = self.vreg.select_component('appliname', self.req, self.rset)
+        if comp and comp.propval('visible'):
+            comp.dispatch(w=self.w)
+        comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
+        if comp and comp.propval('visible'):
+            comp.dispatch(w=self.w, view=view)
+        self.w(u'</td>')
+        
+        # logged user and help
+        #self.w(u'<td>\n')
+        #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
+        #comp.dispatch(w=self.w)
+        #self.w(u'</td><td>')
+        
+        # search box
+        self.w(u'<td>')
+        self.get_searchbox(view, 'left')
+        self.w(u'</td>')
+
+        self.w(u'<td>')
+        helpcomp = self.vreg.select_component('help', self.req, self.rset)
+        if helpcomp: # may not be available if Card is not defined in the schema
+            helpcomp.dispatch(w=self.w)
+        self.w(u'</td>')
+        # lastcolumn
+        self.w(u'<td id="lastcolumn">')
+        self.w(u'</td>\n')
+        self.w(u'</tr></table>\n')
+        self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden',
+                      title=False, message=False)
+
+    def get_searchbox(self, view, context):
+        boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset,
+                                                 view=view, context=context))
+        if boxes:
+            for box in boxes:
+                if box.id == 'search_box':
+                    box.dispatch(w=self.w, view=view)
+
+ 
+
+
+HTMLPageFooter
+--------------
+
+If you want to change the footer for example, look
+for HTMLPageFooter and override it in your views file as in : 
+::
+
+  form ginco.web.views.basetemplates import HTMLPageFooter
+  class MyHTMLPageFooter(HTMLPageFooter):
+      def call(self, **kwargs):
+          self.w(u'<div class="footer">')
+          self.w(u'This website has been created with <a href="http://lax.logilab.org">LAX</a>.')
+          self.w(u'</div>')
+
+Updating a view does not require any restart of the server. By reloading
+the page you can see your new page footer.
+
+
+TheMainTemplate
+---------------
+.. _TheMainTemplate:
+
+The MainTemplate is a bit complex as it tries to accomodate many
+different cases. We are now about to go through it and cutomize entirely
+our application.
+
+TheMainTemplate is responsible for the general layout of the entire application. 
+It defines the template of ``id = main`` that is used by the application. Is 
+also defined in ``ginco/web/views/basetemplates.py`` another template that can
+be used based on TheMainTemplate called SimpleMainTemplate which does not have 
+a top section.
+
+.. image:: images/lax-book.06-simple-main-template.en.png
+
+CSS changes
+-----------
+
+We cannot modify the order in which the application is reading the CSS. In
+the case we want to create new CSS style, the best is to define it a in a new
+CSS located under ``myapp/data/``.
+
+If you want to modify an existing CSS styling property, you will have to use
+``!important`` declaration to override the existing property. The application
+apply a higher priority on the default CSS and you can not change that. 
+Customized CSS will not be read first.
+
+1
+[TODO]
+Add login menu in left column
+
+
+[WRITE ME]
+
+* customize MainTemplate and show that everything in the user
+  interface can be changed
+
+[TODO]
+Rajouter une section pour definir la terminologie utilisee.
+Dans ginco-doc rajouter une section pour erudi-ctl shell ou
+on liste les commandes dispos.
--- a/doc/book/en/D010-faq.en.txt	Tue Dec 09 09:00:31 2008 +0100
+++ b/doc/book/en/D010-faq.en.txt	Tue Dec 09 16:20:00 2008 -0800
@@ -68,6 +68,19 @@
   s'applique. Il faut donc bien reflechir avant de decider de l'un ou
   de l'autre, mais vous avez la possibilite de choisir.
 
+* What is the difference between `AppRsetObject` and `AppObject` ?
+
+  La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
+  les instances de la premières sont séléctionnées pour une requête et un "result
+  set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
+  identifiant.
+
+HOW TO
+======
+
+[TO COMPLETE]
+
+
 * How to update a database after a schema modification?
   
   Cela dépend de ce qui a été modifié dans le schéma. 
@@ -76,7 +89,6 @@
 
   * Modification d'une relation finale 
 
-[TO COMPLETE]
 
 * How to create an anonymous user?
   
@@ -95,10 +107,24 @@
   de données, le plus simple étant de s'identifier sur votre application en
   administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
 
-* What is the difference between `AppRsetObject` and `AppObject` ?
+
+* How to change the application logo?
+  
+  There are two ways of changing the logo.
+
+  1. The easiest way to use a different logo is to replace the existing
+     ``logo.png`` in ``myapp/data`` by your prefered icon and refresh.
+     By default all application will look for a ``logo.png`` to be 
+     rendered in the logo section.
 
-  La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
-  les instances de la premières sont séléctionnées pour une requête et un "result
-  set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
-  identifiant.
+     .. image:: images/lax-book.06-main-template-logo.en.png
 
+  2. In your cube directory, you can specify which file to use for the logo.
+     This is configurable in ``mycube/data/external_resources``: ::
+        
+       LOGO = DATADIR/path/to/mylogo.gif
+
+     where DATADIR is ``mycubes/data``.
+
+
+