50 `CubicWeb` utilise un selecteur qui permet de calculer un score et d'identifier |
50 `CubicWeb` utilise un selecteur qui permet de calculer un score et d'identifier |
51 la vue la plus appropriee a appliquer dans le contexte. La librairie du selecteur |
51 la vue la plus appropriee a appliquer dans le contexte. La librairie du selecteur |
52 se trouve dans ``cubicweb.common.selector`` et une librairie des methodes utilisees |
52 se trouve dans ``cubicweb.common.selector`` et une librairie des methodes utilisees |
53 pour calculer les scores est dans ``cubicweb.vregistry.vreq``. |
53 pour calculer les scores est dans ``cubicweb.vregistry.vreq``. |
54 |
54 |
55 |
55 [FROM-LAX-BOOK] |
|
56 |
|
57 Tip: when modifying views, you do not need to restart the local |
|
58 server. Just save the file in your editor and reload the page in your |
|
59 browser to see the changes. |
|
60 |
|
61 With `LAX`, views are defined by Python classes. A view includes : |
|
62 |
|
63 - an identifier (all objects in `LAX` are entered in a registry |
|
64 and this identifier will be used as a key) |
|
65 |
|
66 - a filter to select the resulsets it can be applied to |
|
67 |
|
68 `LAX` provides a lot of standard views, for a complete list, you |
|
69 will have to read the code in directory ``ginco/web/views/`` (XXX |
|
70 improve doc). |
|
71 |
|
72 For example, the view named ``primary`` is the one used to display |
|
73 a single entity. |
|
74 |
|
75 If you want to change the way a ``BlogEntry`` is displayed, just |
|
76 override the view ``primary`` in ``BlogDemo/views.py`` :: |
|
77 |
|
78 01. from ginco.web.views import baseviews |
|
79 02. |
|
80 03. class BlogEntryPrimaryView(baseviews.PrimaryView): |
|
81 04. |
|
82 05. accepts = ('BlogEntry',) |
|
83 06. |
|
84 07. def cell_call(self, row, col): |
|
85 08. entity = self.entity(row, col) |
|
86 09. self.w(u'<h1>%s</h1>' % entity.title) |
|
87 10. self.w(u'<p>published on %s in category %s</p>' % \ |
|
88 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category)) |
|
89 12. self.w(u'<p>%s</p>' % entity.text) |
|
90 |
|
91 The above source code defines a new primary view (`line 03`) for |
|
92 ``BlogEntry`` (`line 05`). |
|
93 |
|
94 Since views are applied to resultsets and resulsets can be tables of |
|
95 data, it is needed to recover the entity from its (row,col) |
|
96 coordinates (`line 08`). We will get to this in more detail later. |
|
97 |
|
98 The view has a ``self.w()`` method that is used to output data. Here `lines |
|
99 09-12` output HTML tags and values of the entity's attributes. |
|
100 |
|
101 When displaying same blog entry as before, you will notice that the |
|
102 page is now looking much nicer. |
|
103 |
|
104 .. image:: ../images/lax-book.09-new-view-blogentry.en.png |
|
105 :alt: blog entries now look much nicer |
|
106 |
|
107 Let us now improve the primary view of a blog :: |
|
108 |
|
109 01. class BlogPrimaryView(baseviews.PrimaryView): |
|
110 02. |
|
111 03. accepts = ('Blog',) |
|
112 04. |
|
113 05. def cell_call(self, row, col): |
|
114 06. entity = self.entity(row, col) |
|
115 07. self.w(u'<h1>%s</h1>' % entity.title) |
|
116 08. self.w(u'<p>%s</p>' % entity.description) |
|
117 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid) |
|
118 10. self.wview('primary', rset) |
|
119 |
|
120 In the above source code, `lines 01-08` are similar to the previous |
|
121 view we defined. |
|
122 |
|
123 At `line 09`, a simple request in made to build a resultset with all |
|
124 the entities linked to the current ``Blog`` entity by the relationship |
|
125 ``entry_of``. The part of the framework handling the request knows |
|
126 about the schema and infer that such entities have to be of the |
|
127 ``BlogEntry`` kind and retrieves them. |
|
128 |
|
129 The request returns a selection of data called a resultset. At |
|
130 `line 10` the view 'primary' is applied to this resultset to output |
|
131 HTML. |
|
132 |
|
133 **This is to be compared to interfaces and protocols in object-oriented |
|
134 languages. Applying a given view to all the entities of a resultset only |
|
135 requires the availability, for each entity of this resultset, of a |
|
136 view with that name that can accepts the entity.** |
|
137 |
|
138 Assuming we added entries to the blog titled `MyLife`, displaying it |
|
139 now allows to read its description and all its entries. |
|
140 |
|
141 .. image:: ../images/lax-book.10-blog-with-two-entries.en.png |
|
142 :alt: a blog and all its entries |
|
143 |
|
144 **Before we move forward, remember that the selection/view principle is |
|
145 at the core of `LAX`. Everywhere in the engine, data is requested |
|
146 using the RQL language, then HTML/XML/text/PNG is output by applying a |
|
147 view to the resultset returned by the query. That is where most of the |
|
148 flexibility comes from.** |
|
149 |
|
150 [WRITE ME] |
|
151 |
|
152 * implementing interfaces, calendar for blog entries |
|
153 * show that a calendar view can export data to ical |
|
154 |
|
155 We will implement the ginco.interfaces.ICalendarable interfaces on |
|
156 entities.BloEntry and apply the OneMonthCalendar and iCalendar views |
|
157 to resultsets like "Any E WHERE E is BlogEntry" |
|
158 |
|
159 * create view "blogentry table" with title, publish_date, category |
|
160 |
|
161 We will show that by default the view that displays |
|
162 "Any E,D,C WHERE E publish_date D, E category C" is the table view. |
|
163 Of course, the same can be obtained by calling |
|
164 self.wview('table',rset) |
|
165 |
|
166 * in view blog, select blogentries and apply view "blogentry table" |
|
167 * demo ajax by filtering blogentry table on category |
|
168 |
|
169 we did the same with 'primary', but with tables we can turn on filters |
|
170 and show that ajax comes for free. |
56 [FILLME] |
171 [FILLME] |
57 |
172 |
58 Les templates ou patron |
173 Les templates ou patron |
59 ----------------------- |
174 ----------------------- |
60 |
175 |