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