38 content = String(required=True, fulltextindexed=True) |
38 content = String(required=True, fulltextindexed=True) |
39 entry_of = SubjectRelation('Blog', cardinality='?*') |
39 entry_of = SubjectRelation('Blog', cardinality='?*') |
40 |
40 |
41 |
41 |
42 A Blog has a title and a description. The title is a string that is |
42 A Blog has a title and a description. The title is a string that is |
43 required by the class EntityType and must be less than 50 characters. |
43 required and must be less than 50 characters. The |
44 The description is a string that is not constrained. |
44 description is a string that is not constrained. |
45 |
45 |
46 A BlogEntry has a title, a publish_date and a content. The title is a |
46 A BlogEntry has a title, a publish_date and a content. The title is a |
47 string that is required and must be less than 100 characters. The |
47 string that is required and must be less than 100 characters. The |
48 publish_date is a Date with a default value of TODAY, meaning that |
48 publish_date is a Date with a default value of TODAY, meaning that |
49 when a BlogEntry is created, its publish_date will be the current day |
49 when a BlogEntry is created, its publish_date will be the current day |
50 unless it is modified. The content is a string that will be indexed in |
50 unless it is modified. The content is a string that will be indexed in |
51 the full-text index and has no constraint. |
51 the database full-text index and has no constraint. |
52 |
52 |
53 A BlogEntry also has a relationship ``entry_of`` that links it to a |
53 A BlogEntry also has a relationship ``entry_of`` that links it to a |
54 Blog. The cardinality ``?*`` means that a BlogEntry can be part of |
54 Blog. The cardinality ``?*`` means that a BlogEntry can be part of |
55 zero or one Blog (``?`` means `zero or one`) and that a Blog can |
55 zero or one Blog (``?`` means `zero or one`) and that a Blog can |
56 have any number of BlogEntry (``*`` means `any number including |
56 have any number of BlogEntry (``*`` means `any number including |
170 .. _DefineViews: |
170 .. _DefineViews: |
171 |
171 |
172 Define your entity views |
172 Define your entity views |
173 ------------------------ |
173 ------------------------ |
174 |
174 |
175 Each entity defined in a model inherits default views allowing |
175 Each entity defined in a model is associated with default views |
176 different rendering of the data. You can redefine each of them |
176 allowing different rendering of the data. You can redefine each of |
177 according to your needs and preferences. So let's see how the |
177 them according to your needs and preferences. So let's see how the |
178 views are defined. |
178 views are defined. |
179 |
179 |
180 |
180 |
181 The view selection principle |
181 The view selection principle |
182 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
182 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
183 |
183 |
184 A view is defined by a Python class which includes: |
184 A view is defined by a Python class which includes: |
185 |
185 |
186 - an identifier (all objects in *CubicWeb* are entered in a registry |
186 - an identifier (all objects in *CubicWeb* are recorded in a |
187 and this identifier will be used as a key) |
187 registry and this identifier will be used as a key) |
188 |
188 |
189 - a filter to select the result sets it can be applied to |
189 - a filter to select the result sets it can be applied to |
190 |
190 |
191 A view has a set of methods complying |
191 A view has a set of methods complying with the `View` class interface |
192 with the `View` class interface (`cubicweb.common.view`). |
192 (`cubicweb.common.view`). |
193 |
193 |
194 *CubicWeb* provides a lot of standard views for the type `EntityView`; |
194 *CubicWeb* provides a lot of standard views for the type `EntityView`; |
195 for a complete list, read the code in directory ``cubicweb/web/views/``. |
195 for a complete list, read the code in directory ``cubicweb/web/views/``. |
196 |
196 |
197 A view is applied on a `result set` which contains a set of |
197 A view is applied on a `result set` which contains a set of entities |
198 entities we are trying to display. *CubicWeb* uses a selector |
198 we are trying to display. *CubicWeb* uses a selector mechanism which |
199 mechanism which computes for each available view a score: |
199 computes for each available view a score: the view with the highest |
200 the view with the highest score is then used to display the given `result set`. |
200 score is then used to display the given `result set`. The standard |
201 The standard library of selectors is in |
201 library of selectors is in ``cubicweb.selector``. |
202 ``cubicweb.common.selector`` and a library of methods used to |
|
203 compute scores is available in ``cubicweb.vregistry.vreq``. |
|
204 |
202 |
205 It is possible to define multiple views for the same identifier |
203 It is possible to define multiple views for the same identifier |
206 and to associate selectors and filters to allow the application |
204 and to associate selectors and filters to allow the application |
207 to find the best way to render the data. |
205 to find the most appropriate way to render the data. |
208 |
206 |
209 For example, the view named ``primary`` is the one used to display |
207 For example, the view named ``primary`` is the one used to display a |
210 a single entity. We will now show you how to customize this view. |
208 single entity. We will now show you how to create a primary view for |
211 |
209 BlogEntry. |
212 |
210 |
213 View customization |
211 |
214 ~~~~~~~~~~~~~~~~~~ |
212 Primary view customization |
215 |
213 ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
216 If you wish to modify the way a `BlogEntry` is rendered, you will have to |
214 |
217 overwrite the `primary` view defined in the module ``views`` of the cube |
215 If you wish to modify the way a `BlogEntry` is rendered, you will have |
218 ``cubes/blog/views.py``. |
216 to subclass the `primary` view, for instance in the module ``views`` |
219 |
217 of the cube ``cubes/blog/views.py``. |
220 We can for example add in front of the publication date a prefix specifying |
218 |
221 that the date we see is the publication date. |
219 The standard primary view is the most sophisticated view of all. It |
|
220 has more than a call() method. It is a template. Actually the entry |
|
221 point calls the following sequence of (redefinable) methods: |
|
222 |
|
223 * render_entity_title |
|
224 |
|
225 * render_entity_metadata |
|
226 |
|
227 * render_entity_attributes |
|
228 |
|
229 * render_entity_relations |
|
230 |
|
231 * render_side_boxes |
|
232 |
|
233 Excepted side boxes, we can see all of them already in action in the |
|
234 blog entry view. This is all described in more details in |
|
235 :ref:`primary`. |
|
236 |
|
237 We can for example add in front of the publication date a prefix |
|
238 specifying that the date we see is the publication date. |
222 |
239 |
223 To do so, please apply the following changes: |
240 To do so, please apply the following changes: |
224 |
241 |
225 .. sourcecode:: python |
242 .. sourcecode:: python |
226 |
243 |
227 from cubicweb.web.views import baseviews |
244 from cubicweb.selectors import implements |
228 |
245 from cubicweb.web.views import primary |
229 |
246 |
230 class BlogEntryPrimaryView(baseviews.PrimaryView): |
247 class BlogEntryPrimaryView(primary.PrimaryView): |
231 |
248 __select__ = implements('BlogEntry') |
232 accepts = ('BlogEntry',) |
249 |
233 |
250 def render_entity_attributes(self, entity): |
234 def render_entity_title(self, entity): |
251 self.w(u'<p>published on %s</p>' % |
235 self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title())) |
252 entity.publish_date.strftime('%Y-%m-%d')) |
236 |
253 super(BlogEntryPrimaryView, self).render_entity_attributes(entity) |
237 def content_format(self, entity): |
|
238 return entity.view('reledit', rtype='content_format') |
|
239 |
|
240 def cell_call(self, row, col): |
|
241 entity = self.entity(row, col) |
|
242 |
|
243 # display entity attributes with prefixes |
|
244 self.w(u'<h1>%s</h1>' % entity.title) |
|
245 self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d')) |
|
246 self.w(u'<p>%s</p>' % entity.content) |
|
247 |
|
248 # display relations |
|
249 siderelations = [] |
|
250 if self.main_related_section: |
|
251 self.render_entity_relations(entity, siderelations) |
|
252 |
254 |
253 .. note:: |
255 .. note:: |
254 When a view is modified, it is not required to restart the instance |
256 When a view is modified, it is not required to restart the instance |
255 server. Save the Python file and reload the page in your web browser |
257 server. Save the Python file and reload the page in your web browser |
256 to view the changes. |
258 to view the changes. |