ticket #342987, add navigation links in monthly archives and makes BlogEntry an IPrevNext entity type
authorSandrine Ribeau <sandrine.ribeau@logilab.fr>
Wed, 04 Nov 2009 12:40:43 -0800
changeset 140 c12f85ec602f
parent 139 5bd23a419f06
child 141 6102b385b8a3
ticket #342987, add navigation links in monthly archives and makes BlogEntry an IPrevNext entity type
data/cubes.blog.css
entities.py
views/secondary.py
--- a/data/cubes.blog.css	Wed Nov 04 12:39:49 2009 +0100
+++ b/data/cubes.blog.css	Wed Nov 04 12:40:43 2009 -0800
@@ -43,3 +43,12 @@
 ul.simple li {
   background: transparent url(bullet_orange.png) no-repeat scroll 0 6px;
 }
+
+span.previousmonth {
+ float:left;
+}
+
+span.nextmonth {
+ float:right;
+}
+
--- a/entities.py	Wed Nov 04 12:39:49 2009 +0100
+++ b/entities.py	Wed Nov 04 12:40:43 2009 -0800
@@ -10,7 +10,7 @@
 from cubicweb.utils import todate
 from cubicweb.entities import AnyEntity, fetch_config
 from cubicweb.interfaces import (ICalendarViews, ICalendarable,
-                                 ISiocItem, ISiocContainer)
+                                 ISiocItem, ISiocContainer, IPrevNext)
 
 
 class Blog(AnyEntity):
@@ -42,7 +42,7 @@
     id = 'BlogEntry'
     fetch_attrs, fetch_order = fetch_config(['creation_date', 'title'], order='DESC')
     __implements__ = AnyEntity.__implements__ + (
-        ICalendarViews, ICalendarable, ISiocItem)
+        ICalendarViews, ICalendarable, ISiocItem, IPrevNext)
 
     def dc_title(self):
         return self.title
@@ -96,3 +96,22 @@
     def isioc_topics(self):
         # XXX link to tags, folders?
         return []
+
+    # IPrevNext interface #####################################################
+
+    def next_entity(self):
+        rql = ('Any B ORDERBY B ASC LIMIT 1 '
+               'WHERE B is BlogEntry, B entry_of BL, BL eid %(blog)s, '
+               'B eid > %(eid)s')
+        rset = self.req.execute(rql, {'blog': self.entry_of[0].eid, 'eid': self.eid})
+        if rset:
+            return rset.get_entity(0,0)
+
+    def previous_entity(self):
+        rql = ('Any B ORDERBY B DESC LIMIT 1 '
+               'WHERE B is BlogEntry, B entry_of BL, BL eid %(blog)s, '
+               'B eid < %(eid)s')
+        rset = self.req.execute(rql, {'blog': self.entry_of[0].eid, 'eid': self.eid})
+        if rset:
+            return rset.get_entity(0,0)
+
--- a/views/secondary.py	Wed Nov 04 12:39:49 2009 +0100
+++ b/views/secondary.py	Wed Nov 04 12:40:43 2009 -0800
@@ -34,7 +34,8 @@
         nmb_entries = self.req.execute(self.countrql, args)[0][0]
         label = u'%s %s [%s]' % (self.req._(calendar.MONTHNAMES[month-1]), year,
                                  nmb_entries)
-        url = xml_escape(self.build_url('view', rql=rql))
+        vtitle = '%s %s' % (self.req._('BlogEntry_plural'), label)
+        url = xml_escape(self.build_url('view', rql=rql, month=month, year=year, vtitle=vtitle))
         link = u'<a href="%s" title="">%s</a>' % (url, label)
         items.append( u'<li class="">%s</li>\n' % link )
 
@@ -124,10 +125,52 @@
 
 class BlogEntryAdaptedListView(baseviews.AdaptedListView):
     __select__ = baseviews.AdaptedListView.__select__ & implements('BlogEntry')
+    countrql = 'Any COUNT(B) WHERE B is BlogEntry, B creation_date >=  %(firstday)s, B creation_date <= %(lastday)s'
 
     def call(self, **kwargs):
         self.req.add_css('cubes.blog.css')
         super(BlogEntryAdaptedListView, self).call(**kwargs)
+        if 'year' in self.req.form and 'month' in self.req.form:
+            self.render_next_previous(int(self.req.form['year']), int(self.req.form['month']))
+
+    def render_next_previous(self, year, month):
+        if month == 12:
+            nextmonth = 1
+            year = year + 1
+        else:
+            nextmonth = month + 1
+        if month == 1:
+            previousmonth = 12
+            year = year - 1
+        else:
+            previousmonth = month -1
+
+        self.w(u'<div class="prevnext">')
+        self.w(u'<span class="previousmonth">%s</span>' \
+               % self.render_link(year, previousmonth,
+                                  xml_escape(u'<< ' + self.req._(u'previous month'))))
+        self.w(u'<span class="nextmonth">%s</span>' \
+               % self.render_link(year, nextmonth,
+                                  xml_escape(self.req._(u'next month') + u' >>')))
+        self.w(u'</div>')
+
+    def render_link(self, year, month, atitle):
+        firstday = datetime(year, month, 1)
+        lastday = datetime(year, month, monthrange(year, month)[1])
+        rql = ('Any B, BD ORDERBY BD DESC '
+               'WHERE B is BlogEntry, B creation_date BD, '
+               'B creation_date >=  "%s", B creation_date <= "%s"' %
+                (firstday.strftime('%Y-%m-%d'), lastday.strftime('%Y-%m-%d')))
+        args = {'firstday':firstday, 'lastday':lastday}
+        nmb_entries = self.req.execute(self.countrql, args)[0][0]
+        label = u'%s %s [%s]' % (self.req._(calendar.MONTHNAMES[month-1]), year,
+                                 nmb_entries)
+        vtitle = '%s %s' % (self.req._('BlogEntry_plural'), label)
+        url = xml_escape(self.build_url('view', rql=rql, vtitle=vtitle,
+                                        month=month, year=year))
+        if self.req.execute(rql):
+            return u'<a href="%s" title="">%s</a>' % (url, atitle)
+        return u''
 
 class BlogEntryAdaptedListItemView(baseviews.AdaptedListItemView):
     __select__ = baseviews.AdaptedListView.__select__ & implements('BlogEntry')