doc/book/en/04-develop-views.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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
74
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     1
.. -*- coding: utf-8 -*-
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     2
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     3
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     4
Developing the user interface with Views
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     5
========================================
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     6
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     7
Before moving to this section, make sure you read the `Essentials`
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     8
section in the Introduction.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
     9
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    10
Tip: when modifying views, you do not need to restart the local 
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    11
server. Just save the file in your editor and reload the page in your
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    12
browser to see the changes.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    13
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    14
The selection/view principle
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    15
----------------------------
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    16
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    17
With `LAX`, views are defined by Python classes. A view includes :
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    18
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    19
- an identifier (all objects in `LAX` are entered in a registry
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    20
  and this identifier will be used as a key)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    21
  
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    22
- a filter to select the resulsets it can be applied to
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    23
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    24
`LAX` provides a lot of standard views, for a complete list, you
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    25
will have to read the code in directory ``ginco/web/views/`` (XXX
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    26
improve doc).
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    27
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    28
For example, the view named ``primary`` is the one used to display
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    29
a single entity.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    30
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    31
If you want to change the way a ``BlogEntry`` is displayed, just
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    32
override the view ``primary`` in ``BlogDemo/views.py`` ::
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    33
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    34
  01. from ginco.web.views import baseviews
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    35
  02.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    36
  03. class BlogEntryPrimaryView(baseviews.PrimaryView):
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    37
  04.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    38
  05.     accepts = ('BlogEntry',)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    39
  06.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    40
  07.     def cell_call(self, row, col):
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    41
  08.         entity = self.entity(row, col)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    42
  09.         self.w(u'<h1>%s</h1>' % entity.title)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    43
  10.         self.w(u'<p>published on %s in category %s</p>' % \
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    44
  11.                (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    45
  12.         self.w(u'<p>%s</p>' % entity.text)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    46
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    47
The above source code defines a new primary view (`line 03`) for
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    48
``BlogEntry`` (`line 05`). 
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    49
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    50
Since views are applied to resultsets and resulsets can be tables of
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    51
data, it is needed to recover the entity from its (row,col)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    52
coordinates (`line 08`). We will get to this in more detail later.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    53
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    54
The view has a ``self.w()`` method that is used to output data. Here `lines
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    55
09-12` output HTML tags and values of the entity's attributes.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    56
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    57
When displaying same blog entry as before, you will notice that the
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    58
page is now looking much nicer.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    59
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    60
.. image:: images/lax-book.09-new-view-blogentry.en.png
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    61
   :alt: blog entries now look much nicer
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    62
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    63
Let us now improve the primary view of a blog ::
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    64
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    65
  01. class BlogPrimaryView(baseviews.PrimaryView):
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    66
  02. 
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    67
  03.     accepts = ('Blog',)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    68
  04.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    69
  05.     def cell_call(self, row, col):
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    70
  06.         entity = self.entity(row, col)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    71
  07.         self.w(u'<h1>%s</h1>' % entity.title)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    72
  08.         self.w(u'<p>%s</p>' % entity.description)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    73
  09.         rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    74
  10.         self.wview('primary', rset)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    75
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    76
In the above source code, `lines 01-08` are similar to the previous
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    77
view we defined.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    78
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    79
At `line 09`, a simple request in made to build a resultset with all
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    80
the entities linked to the current ``Blog`` entity by the relationship
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    81
``entry_of``. The part of the framework handling the request knows
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    82
about the schema and infer that such entities have to be of the
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    83
``BlogEntry`` kind and retrieves them.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    84
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    85
The request returns a selection of data called a resultset. At 
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    86
`line 10` the view 'primary' is applied to this resultset to output
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    87
HTML. 
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    88
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    89
**This is to be compared to interfaces and protocols in object-oriented
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    90
languages. Applying a given view to all the entities of a resultset only
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    91
requires the availability, for each entity of this resultset, of a
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    92
view with that name that can accepts the entity.**
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    93
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    94
Assuming we added entries to the blog titled `MyLife`, displaying it
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    95
now allows to read its description and all its entries.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    96
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    97
.. image:: images/lax-book.10-blog-with-two-entries.en.png
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    98
   :alt: a blog and all its entries
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
    99
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   100
**Before we move forward, remember that the selection/view principle is
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   101
at the core of `LAX`. Everywhere in the engine, data is requested
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   102
using the RQL language, then HTML/XML/text/PNG is output by applying a
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   103
view to the resultset returned by the query. That is where most of the
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   104
flexibility comes from.**
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   105
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   106
[WRITE ME]
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   107
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   108
* implementing interfaces, calendar for blog entries
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   109
* show that a calendar view can export data to ical
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   110
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   111
We will implement the ginco.interfaces.ICalendarable interfaces on
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   112
entities.BloEntry and apply the OneMonthCalendar and iCalendar views
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   113
to resultsets like "Any E WHERE E is BlogEntry"
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   114
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   115
* create view "blogentry table" with title, publish_date, category
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   116
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   117
We will show that by default the view that displays 
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   118
"Any E,D,C WHERE E publish_date D, E category C" is the table view.
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   119
Of course, the same can be obtained by calling
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   120
self.wview('table',rset)
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   121
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   122
* in view blog, select blogentries and apply view "blogentry table"
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   123
* demo ajax by filtering blogentry table on category
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   124
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   125
we did the same with 'primary', but with tables we can turn on filters
9a9fe515934d [doc] reuse the lax book
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
diff changeset
   126
and show that ajax comes for free.