doc/book/en/06-maintemplate.en.txt
author Nicolas Chauvat <nicolas.chauvat@logilab.fr>
Fri, 14 Nov 2008 11:05:32 +0100
changeset 74 9a9fe515934d
child 81 f5886815126b
permissions -rw-r--r--
[doc] reuse the lax book

.. -*- coding: utf-8 -*-

Views & Templates
=================


Look at ``lax/skel/ginco/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.

Change logo
~~~~~~~~~~~

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.

.. image:: images/lax-book.06-main-template-logo.en.png

[ADD]
customized external_resources in myapp/data cd crih for reference

[WRITE ME]
ADD how to use external_resources variables used in ginco/web/webconfig.py

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.