[doc] Inserted content from LAX book about templates.
authorSandrine Ribeau <sandrine.ribeau@logilab.fr>
Tue, 09 Dec 2008 16:19:02 -0800
changeset 199 c603087373cd
parent 198 5e5ba709d022
child 200 a4f8a5fb3c3f
[doc] Inserted content from LAX book about templates.
doc/book/en/BXXX-templates.en.txt
doc/book/en/D010-faq.en.txt
--- a/doc/book/en/BXXX-templates.en.txt	Tue Dec 09 16:18:38 2008 -0800
+++ b/doc/book/en/BXXX-templates.en.txt	Tue Dec 09 16:19:02 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 16:18:38 2008 -0800
+++ b/doc/book/en/D010-faq.en.txt	Tue Dec 09 16:19:02 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``.
+
+
+