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