[doc/book] more flesh to views/primary view stable
authorAurelien Campeas <aurelien.campeas@logilab.fr>
Mon, 12 Apr 2010 19:36:51 +0200
branchstable
changeset 5222 ed6905d98a5e
parent 5221 b851558456bb
child 5225 9ff0dee81eb2
[doc/book] more flesh to views/primary view
doc/book/en/conf.py
doc/book/en/development/devweb/internationalization.rst
doc/book/en/development/devweb/rtags.rst
doc/book/en/development/devweb/views.rst
doc/book/en/development/entityclasses/data-as-objects.rst
doc/book/en/development/webstdlib/baseviews.rst
doc/book/en/development/webstdlib/primary.rst
web/views/baseviews.py
web/views/primary.py
--- a/doc/book/en/conf.py	Mon Apr 12 16:57:11 2010 +0200
+++ b/doc/book/en/conf.py	Mon Apr 12 19:36:51 2010 +0200
@@ -32,7 +32,7 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'logilab.common.sphinx_ext']
+extensions = ['sphinx.ext.autodoc', 'logilab.common.sphinx_ext', 'sphinxcontrib.aafig']
 autoclass_content = 'both'
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['.templates']
@@ -186,3 +186,5 @@
 
 # If false, no module index is generated.
 #latex_use_modindex = True
+aafig_format = dict(latex='pdf', html='svg', text=None)
+
--- a/doc/book/en/development/devweb/internationalization.rst	Mon Apr 12 16:57:11 2010 +0200
+++ b/doc/book/en/development/devweb/internationalization.rst	Mon Apr 12 19:36:51 2010 +0200
@@ -37,7 +37,7 @@
 
  * by using the equivalent request's method ::
 
-     class NoResultView(EmptyRsetView):
+     class NoResultView(View):
          """default view when no result has been found"""
          __regid__ = 'noresult'
 
--- a/doc/book/en/development/devweb/rtags.rst	Mon Apr 12 16:57:11 2010 +0200
+++ b/doc/book/en/development/devweb/rtags.rst	Mon Apr 12 19:36:51 2010 +0200
@@ -1,5 +1,5 @@
-Configuring the generated interface
------------------------------------
+Configuring the user interface
+------------------------------
 
 
 Relation tags
--- a/doc/book/en/development/devweb/views.rst	Mon Apr 12 16:57:11 2010 +0200
+++ b/doc/book/en/development/devweb/views.rst	Mon Apr 12 19:36:51 2010 +0200
@@ -9,7 +9,7 @@
 in *CubicWeb*.
 
 We'll start with a description of the interface providing you with a basic
-understanding of the classes and methods available, then detail the view
+understanding of the available classes and methods, then detail the view
 selection principle which makes *CubicWeb* web interface very flexible.
 
 A `View` is an object applied to another object such as an entity.
@@ -26,20 +26,22 @@
 A `View` is instantiated to render a result set or part of a result set. `View`
 subclasses may be parametrized using the following class attributes:
 
-    * `templatable` indicates if the view may be embeded in a main
-      template or if it has to be rendered standalone (i.e. XML views
-      must not be embeded in the main template for HTML pages)
-    * if the view is not templatable, it should set the `content_type` class
-      attribute to the correct MIME type (text/xhtml by default)
-    * the `category` attribute may be used in the interface to regroup related
-      objects together
+* `templatable` indicates if the view may be embedded in a main
+  template or if it has to be rendered standalone (i.e. XML views must
+  not be embedded in the main template for HTML pages)
+
+* if the view is not templatable, it should set the `content_type`
+  class attribute to the correct MIME type (text/xhtml by default)
+
+* the `category` attribute may be used in the interface to regroup
+  related objects together
+
+A view writes to its output stream thanks to its attribute `w` (an
+`UStreamIO`, except for binary views).
 
 At instantiation time, the standard `_cw` and `cw_rset` attributes are
 added and the `w` attribute will be set at rendering time.
 
-A view writes to its output stream thanks to its attribute `w` (an
-`UStreamIO`, except for binary views).
-
 The basic interface for views is as follows (remember that the result set has a
 tabular structure with rows and columns, hence cells):
 
@@ -51,24 +53,21 @@
   result set)
 
 * `cell_call(row, col, **kwargs)`, call the view for a given cell of a
-  result set
+  result set (`row` and `col` being integers used to access the cell)
 
 * `url()`, returns the URL enabling us to get the view with the current
   result set
 
-* `view(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of identifier
-  `__vid` on the given result set. It is possible to give a view identifier
-  of fallback that will be used if the view requested is not applicable to the
-  result set. This is actually defined on the AppObject class.
+* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of
+  identifier `__vid` on the given result set. It is possible to give a
+  fallback view identifier that will be used if the requested view is
+  not applicable to the result set.
 
-* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, similar to `view` except
-  the flow is automatically passed in the parameters
-
-* `html_headers()`, returns a list of HTML headers to set by the main template
+* `html_headers()`, returns a list of HTML headers to be set by the
+  main template
 
 * `page_title()`, returns the title to use in the HTML header `title`
 
-
 Other basic view classes
 ````````````````````````
 Here are some of the subclasses of `View` defined in `cubicweb.common.view`
@@ -77,8 +76,6 @@
 * `EntityView`, view applying to lines or cell containing an entity (e.g. an eid)
 * `StartupView`, start view that does not require a result set to apply to
 * `AnyRsetView`, view applicable to any result set
-* `EmptyRsetView`, view applicable to an empty result set
-
 
 Examples of views class
 -----------------------
@@ -109,6 +106,7 @@
         __select__ = one_line_rset() & match_search_state('linksearch') & implements('Any')
 
 
+
 Example of view customization and creation
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
--- a/doc/book/en/development/entityclasses/data-as-objects.rst	Mon Apr 12 16:57:11 2010 +0200
+++ b/doc/book/en/development/entityclasses/data-as-objects.rst	Mon Apr 12 19:36:51 2010 +0200
@@ -16,15 +16,15 @@
 
 :Formatting and output generation:
 
-  * `view(vid, **kwargs)`, applies the given view to the entity
+  * `view(__vid, __registry='views', **kwargs)`, applies the given view to the entity
     (and returns an unicode string)
 
-  * `absolute_url(**kwargs)`, returns an absolute URL to access the primary view
+  * `absolute_url(*args, **kwargs)`, returns an absolute URL to access the primary view
     of an entity
 
   * `rest_path()`, returns a relative REST URL to get the entity
 
-  * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
+  * `printable_value(attr, value=_marker, attrtype=None, format='text/html', displaytime=True)`,
     returns a string enabling the display of an attribute value in a given format
     (the value is automatically recovered if necessary)
 
--- a/doc/book/en/development/webstdlib/baseviews.rst	Mon Apr 12 16:57:11 2010 +0200
+++ b/doc/book/en/development/webstdlib/baseviews.rst	Mon Apr 12 19:36:51 2010 +0200
@@ -12,6 +12,7 @@
 
 HTML views
 ~~~~~~~~~~
+
 Special views
 `````````````
 
@@ -43,6 +44,7 @@
 
 List
 `````
+
 *list*
     This view displays a list of entities by creating a HTML list (`<ul>`)
     and call the view `listitem` for each entity of the result set.
@@ -50,12 +52,12 @@
 *listitem*
     This view redirects by default to the `outofcontext` view.
 
-*adaptedlist*
+*sameetypelist*
     This view displays a list of entities of the same type, in HTML section (`<div>`)
-    and call the view `adaptedlistitem` for each entity of the result set.
+    and call the view `sameetypelistitem` for each entity of the result set.
 
-*adaptedlistitem*
-    This view redirects by default to the `outofcontext` view.
+*sameetypelistitem*
+    This view redirects by default to the `listitem` view.
 
 *csv*
     This view applies to entity groups, which are individually
--- a/doc/book/en/development/webstdlib/primary.rst	Mon Apr 12 16:57:11 2010 +0200
+++ b/doc/book/en/development/webstdlib/primary.rst	Mon Apr 12 19:36:51 2010 +0200
@@ -1,83 +1,45 @@
 .. _primary:
 
-The default 'primary' view (:mod:`cubicweb.web.views.primary`)
+The Primary View (:mod:`cubicweb.web.views.primary`)
 ---------------------------------------------------------------
 
-The primary view of an entity is the view called by default when a single
-entity is in the result set and needs to be displayed.
-
-This view is supposed to render a maximum of informations about the entity.
+The primary view of an entity is the view called by default when a
+single entity is in the result set and needs to be displayed.
 
-Beware when overriding this top level `cell_call` in a primary because
-you will loose a bunch of functionnality that automatically comes with
-it : `in-context` boxes, related boxes, some navigation, some
-displaying of the metadata, etc. It might be interresting to
-understand the implementation fo the `cell_call` to override specifics
-bits of it.
+This view is supposed to render a maximum of informations about the
+entity.
 
 Rendering methods and attributes for ``PrimaryView``
 ----------------------------------------------------
 
-By default, *CubicWeb* provides a primary view for every available
+By default, *CubicWeb* provides a primary view that fits every available
 entity type. This is the first view you might be interested in
-modifying.
-
-Let's have a quick look at the EntityView ``PrimaryView`` as well as
-its rendering method
-
-.. sourcecode:: python
+modifying. It is also one of the richest and most complex.
 
-    class PrimaryView(EntityView):
-        """the full view of an non final entity"""
-        __regid__ = 'primary'
-        title = _('primary')
-        show_attr_label = True
-        show_rel_label = True
-        skip_none = True
-        rsection = uicfg.primaryview_section
-        display_ctrl = uicfg.primaryview_display_ctrl
-        main_related_section = True
+The basic layout of a primary view is as follows. This layout is
+actually set up by the `render_entity` method.
 
-        ...
-
-    def cell_call(self, row, col):
-        self.row = row
-        self.maxrelated = self._cw.property_value('navigation.related-limit')
-        entity = self.complete_entity(row, col)
-        self.render_entity(entity)
+.. aafig::
 
-    def render_entity(self, entity):
-        self.render_entity_title(entity)
-        self.render_entity_metadata(entity)
-        # entity's attributes and relations, excluding meta data
-        # if the entity isn't meta itself
-        boxes = self._prepare_side_boxes(entity)
-        if boxes or hasattr(self, 'render_side_related'):
-            self.w(u'<table width="100%"><tr><td style="width: 75%">')
-        self.render_entity_summary(entity)
-        self.w(u'<div class="mainInfo">')
-        self.content_navigation_components('navcontenttop')
-        self.render_entity_attributes(entity)
-        if self.main_related_section:
-            self.render_entity_relations(entity)
-        self.w(u'</div>')
-        # side boxes
-        if boxes or hasattr(self, 'render_side_related'):
-            self.w(u'</td><td>')
-            self.w(u'<div class="primaryRight">')
-            if hasattr(self, 'render_side_related'):
-                warn('render_side_related is deprecated')
-                self.render_side_related(entity, [])
-            self.render_side_boxes(boxes)
-            self.w(u'</div>')
-            self.w(u'</td></tr></table>')
-        self.content_navigation_components('navcontentbottom')
+ +------------------------------------+
+ |"content navigation (top)"          |
+ +------------------------------------+
+ |"title, toolbox"                    |
+ +------------------------------------+
+ |"metadata"                          |
+ +----------------------+-------------+
+ |"attributes"          |"side boxes" |
+ |                      |             |
+ |                      |             |
+ +----------------------+             |
+ |"relations"           |             |
+ |                      |             |
+ |                      |             |
+ +----------------------+-------------+
+ |"content navigation (bottom)"       |
+ +------------------------------------+
 
-    ...
-
-``cell_call`` is executed for each entity of a result set.
-
-The methods you want to modify while customizing a ``PrimaryView`` are:
+The methods you may want to modify while customizing a ``PrimaryView`` are:
 
 *render_entity_title(self, entity)*
     Renders the entity title based on the assumption that the method
@@ -92,23 +54,24 @@
     attribute of type `Password` and `Bytes`. The skip_none class
     attribute controls the display of None valued attributes.
 
-*content_navigation_components(self, context)*
-    This method is applicable only for entity type implementing the interface
-    `IPrevNext`. This interface is for entities which can be linked to a previous
-    and/or next entity. This methods will render the navigation links between
-    entities of this type, either at the top or at the bottom of the page
-    given the context (navcontent{top|bottom}).
-
 *render_entity_relations(self, entity)*
     Renders all the relations of the entity in the main section of the page.
 
 *render_side_boxes(self, entity, boxes)*
-    Renders all the relations of the entity in a side box. This is equivalent
-    to *render_entity_relations* in addition to render the relations
-    in a box.
+    Renders relations of the entity in a side box.
+
+The placement of relations in the relations section or in side boxes
+can be controlled through the uicfg mechanism.
 
-Also, please note that by setting the following attributes in your class,
-you can already customize some of the rendering:
+*content_navigation_components(self, context)*
+    This method is applicable only for entity type implementing the interface
+    `IPrevNext`. This interface is for entities which can be linked to a previous
+    and/or next entity. This method will render the navigation links between
+    entities of this type, either at the top or at the bottom of the page
+    given the context (navcontent{top|bottom}).
+
+Also, please note that by setting the following attributes in your
+subclass, you can already customize some of the rendering:
 
 *show_attr_label*
     Renders the attribute label next to the attribute value if set to True.
@@ -126,8 +89,109 @@
 
 A good practice is for you to identify the content of your entity type for which
 the default rendering does not answer your need so that you can focus on the specific
-method (from the list above) that needs to be modified. We do not recommand you to
-overwrite ``render_entity`` as you might potentially loose the benefits of the side
-boxes handling.
+method (from the list above) that needs to be modified. We do not advise you to
+overwrite ``render_entity`` unless you want a completely different layout.
+
+Also, a lot of customisation can be achieved using the
+`primaryview_section` and `primaryview_display_ctrl` relation tags of
+the uicfg module.
+
+Primary view configuration
+``````````````````````````
+
+If you want to customize the primary view of an entity, overriding the primary
+view class may not be necessary. For simple adjustments (attributes or relations
+display locations and styles), a much simpler way is to use uicfg.
+
+Attributes/relations display location
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the primary view, there are 3 sections where attributes and relations can be
+displayed (represented in pink in the image below):
+
+* attributes
+* relations
+* sideboxes
+
+.. image:: ../../images/primaryview_template.png
+
+
+**Attributes** can only be displayed in the attributes section (default
+  behavior). They can also be hidden.
+
+For instance, to hide the ``title`` attribute of the ``Blog`` entity:
+
+.. sourcecode:: python
+
+   from cubicweb.web import uicfg
+   uicfg.primaryview_section.tag_attribute(('Blog', 'title'), 'hidden')
+
+
+**Relations** can be either displayed in one of the three sections or hidden.
+
+For relations, there are two methods:
+
+* ``tag_object_of`` for modifying the primary view of the object
+* ``tag_subject_of`` for modifying the primary view of the subject
+
+These two methods take two arguments:
+
+* a triplet ``(subject, relation_name, object)``, where subject or object can be replaced with ``'*'``
+* the section name or ``hidden``
+
+.. sourcecode:: python
 
-.. XXX talk about uicfg.rdisplay
+   # hide every relation ``entry_of`` in the ``Blog`` primary view
+   uicfg.primaryview_section.tag_object_of(('*', 'entry_of', 'Blog'), 'hidden')
+
+   # display ``entry_of`` relations in the ``relations`` section in the ``BlogEntry`` primary view
+   uicfg.primaryview_section.tag_subject_of(('BlogEntry', 'entry_of', '*'),
+                                             'relations')
+
+
+Display content
+^^^^^^^^^^^^^^^
+
+You can use ``primaryview_display_ctrl`` to customize the display of attributes
+or relations. Values of ``primaryview_display_ctrl`` are dictionaries.
+
+
+Common keys for attributes and relations are:
+* ``vid``: specifies the regid of the view for displaying the attribute or the relation.
+
+  If ``vid`` is not specified, the default value depends on the section:
+  * ``attributes`` section: 'reledit' view
+  * ``relations`` section: 'autolimited' view
+  * ``sideboxes`` section: 'sidebox' view
+
+* ``order``: int used to control order within a section. When not specified,
+  automatically set according to order in which tags are added.
+
+
+Keys for relations only:
+
+* ``label``: label for the relations section or side box
+
+* ``showlabel``: boolean telling whether the label is displayed
+
+* ``limit``: boolean telling if the results should be limited. If so, a link to all results is displayed
+
+* ``filter``: callback taking the related result set as argument and returning it filtered
+
+.. sourcecode:: python
+
+   # in ``CWUser`` primary view, display ``created_by`` relations in relations section
+   uicfg.primaryview_section.tag_object_of(('*', 'created_by', 'CWUser'), 'relations')
+
+   # displays this relation as a list, sets the label, limits the number of results and filters on comments
+   uicfg.primaryview_display_ctrl.tag_object_of(
+       ('*', 'created_by', 'CWUser'),
+       {'vid': 'list', 'label': _('latest comment(s):'), 'limit': True,
+        'filter': lambda rset: rset.filtered_rset(lambda x: x.e_schema == 'Comment')})
+
+.. Warning:: with the ``primaryview_display_ctrl`` rtag, the subject or the
+   object of the relation is ignored for respectively ``tag_object_of`` or
+   ``tag_subject_of``. To avoid warnings during execution, they should be set to
+   ``'*'``.
+
+
--- a/web/views/baseviews.py	Mon Apr 12 16:57:11 2010 +0200
+++ b/web/views/baseviews.py	Mon Apr 12 19:36:51 2010 +0200
@@ -297,7 +297,7 @@
 
 
 class SameETypeListView(EntityView):
-    """list of entities of the same type, when asked explicitly for adapted list
+    """list of entities of the same type, when asked explicitly for same etype list
     view (for instance, display gallery if only images)
     """
     __regid__ = 'sameetypelist'
--- a/web/views/primary.py	Mon Apr 12 16:57:11 2010 +0200
+++ b/web/views/primary.py	Mon Apr 12 19:36:51 2010 +0200
@@ -102,7 +102,6 @@
         self.content_navigation_components('ctxtoolbar')
 
     def render_entity_metadata(self, entity):
-        # XXX deprecated
         entity.view('metadata', w=self.w)
 
     def render_entity_summary(self, entity):