web/views/baseviews.py
changeset 6455 3282742dd4c6
parent 5518 ceea458025b9
child 6583 4e7325d6b616
equal deleted inserted replaced
6454:97203d0af4cb 6455:3282742dd4c6
    31 
    31 
    32 from rql import nodes
    32 from rql import nodes
    33 
    33 
    34 from logilab.mtconverter import TransformError, xml_escape, xml_escape
    34 from logilab.mtconverter import TransformError, xml_escape, xml_escape
    35 
    35 
    36 from cubicweb import NoSelectableObject
    36 from cubicweb import NoSelectableObject, tags
    37 from cubicweb.selectors import yes, empty_rset, one_etype_rset
    37 from cubicweb.selectors import yes, empty_rset, one_etype_rset, match_kwargs
    38 from cubicweb.schema import display_name
    38 from cubicweb.schema import display_name
    39 from cubicweb.view import EntityView, AnyRsetView, View
    39 from cubicweb.view import EntityView, AnyRsetView, View
    40 from cubicweb.uilib import cut, printable_value
    40 from cubicweb.uilib import cut, printable_value
       
    41 from cubicweb.web.views import calendar
    41 
    42 
    42 
    43 
    43 class NullView(AnyRsetView):
    44 class NullView(AnyRsetView):
    44     """default view when no result has been found"""
    45     """default view when no result has been found"""
    45     __regid__ = 'null'
    46     __regid__ = 'null'
   434 XmlItemView = class_moved(xmlrss.XMLItemView)
   435 XmlItemView = class_moved(xmlrss.XMLItemView)
   435 XmlRsetView = class_moved(xmlrss.XMLRsetView)
   436 XmlRsetView = class_moved(xmlrss.XMLRsetView)
   436 RssView = class_moved(xmlrss.RSSView)
   437 RssView = class_moved(xmlrss.RSSView)
   437 RssItemView = class_moved(xmlrss.RSSItemView)
   438 RssItemView = class_moved(xmlrss.RSSItemView)
   438 
   439 
       
   440 
       
   441 class GroupByView(EntityView):
       
   442     """grouped view of a result set. The `group_key` method return the group
       
   443     key of an entities (a string or tuple of string).
       
   444 
       
   445     For each group, display a link to entities of this group by generating url
       
   446     like <basepath>/<key> or <basepath>/<key item 1>/<key item 2>.
       
   447     """
       
   448     __abstrack__ = True
       
   449     __select__ = EntityView.__select__ & match_kwargs('basepath')
       
   450     entity_attribute = None
       
   451     reversed = False
       
   452 
       
   453     def index_url(self, basepath, key, **kwargs):
       
   454         if isinstance(key, (list, tuple)):
       
   455             key = '/'.join(key)
       
   456         return self._cw.build_url('%s/%s' % (basepath, key),
       
   457                                   **kwargs)
       
   458 
       
   459     def index_link(self, basepath, key, items):
       
   460         url = self.index_url(basepath, key)
       
   461         if isinstance(key, (list, tuple)):
       
   462             key = ' '.join(key)
       
   463         return tags.a(key, href=url)
       
   464 
       
   465     def group_key(self, entity, **kwargs):
       
   466         value = getattr(entity, self.entity_attribute)
       
   467         if callable(value):
       
   468             value = value()
       
   469         return value
       
   470 
       
   471     def call(self, basepath, maxentries=None, **kwargs):
       
   472         index = {}
       
   473         for entity in self.cw_rset.entities():
       
   474             index.setdefault(self.group_key(entity, **kwargs), []).append(entity)
       
   475         displayed = sorted(index)
       
   476         if self.reversed:
       
   477             displayed = reversed(displayed)
       
   478         if maxentries is None:
       
   479             needmore = False
       
   480         else:
       
   481             needmore = len(index) > maxentries
       
   482             displayed = tuple(displayed)[:maxentries]
       
   483         w = self.w
       
   484         w(u'<ul class="boxListing">')
       
   485         for key in displayed:
       
   486             w(u'<li>%s</li>\n' %
       
   487               self.index_link(basepath, key, index[key]))
       
   488         if needmore:
       
   489             url = self._cw.build_url('view', vid=self.__regid__,
       
   490                                      rql=self.cw_rset.printable_rql())
       
   491             w( u'<li>%s</li>\n' % tags.a(u'[%s]' % self._cw._('see more'),
       
   492                                          href=url))
       
   493         w(u'</ul>\n')
       
   494 
       
   495 
       
   496 class ArchiveView(GroupByView):
       
   497     """archive view of a result set. Links to months are built using a basepath
       
   498     parameters, eg using url like <basepath>/<year>/<month>
       
   499     """
       
   500     __regid__ = 'cw.archive.by_date'
       
   501     entity_attribute = 'creation_date'
       
   502     reversed = True
       
   503 
       
   504     def group_key(self, entity, **kwargs):
       
   505         value = super(ArchiveView, self).group_key(entity, **kwargs)
       
   506         return '%04d' % value.year, '%02d' % value.month
       
   507 
       
   508     def index_link(self, basepath, key, items):
       
   509         """represent a single month entry"""
       
   510         year, month = key
       
   511         label = u'%s %s [%s]' % (self._cw._(calendar.MONTHNAMES[int(month)-1]),
       
   512                                  year, len(items))
       
   513         etypes = set(entity.__regid__ for entity in items)
       
   514         vtitle = '%s %s' % (', '.join(display_name(self._cw, etype, 'plural')
       
   515                                       for etype in etypes),
       
   516                             label)
       
   517         title = self._cw._('archive for %(month)s/%(year)s') % {
       
   518             'month': month, 'year': year}
       
   519         url = self.index_url(basepath, key, vtitle=vtitle)
       
   520         return tags.a(label, href=url, title=title)
       
   521 
       
   522 
       
   523 class AuthorView(GroupByView):
       
   524     """author view of a result set. Links to month are built using a basepath
       
   525     parameters, eg using url like <basepath>/<author>
       
   526     """
       
   527     __regid__ = 'cw.archive.by_author'
       
   528     entity_attribute = 'creator'
       
   529 
       
   530     def group_key(self, entity, **kwargs):
       
   531         value = super(AuthorView, self).group_key(entity, **kwargs)
       
   532         if value:
       
   533             return value.login
       
   534         return value
       
   535 
       
   536     def index_link(self, basepath, key, items):
       
   537         label = u'%s [%s]' % (key, len(items))
       
   538         etypes = set(entity.__regid__ for entity in items)
       
   539         vtitle = self._cw._('%(etype)s by %(author)s') % {
       
   540             'etype': ', '.join(display_name(self._cw, etype, 'plural')
       
   541                                for etype in etypes),
       
   542             'author': label}
       
   543         url = self.index_url(basepath, key, vtitle=vtitle)
       
   544         title = self._cw._('archive for %(author)s') % {'author': key}
       
   545         return tags.a(label, href=url, title=title)