# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1241074420 -7200 # Thu Apr 30 08:53:40 2009 +0200 # Node ID bc483eb454cecd5bc4f095d1abdb5486a685f485 # Parent f79c5314a68fb3576839867145d58d9d7ff9b6cd sioc view moved to cw; primary view refactoring and others 3.2 updates diff --git a/views.py b/views.py --- a/views.py +++ b/views.py @@ -6,128 +6,49 @@ """ __docformat__ = "restructuredtext en" -from mx.DateTime import DateTime +from calendar import monthrange +from datetime import datetime + from logilab.mtconverter import html_escape -from cubicweb import Unauthorized -from cubicweb.common.uilib import text_cut, safe_cut -from cubicweb.common.uilib import rql_for_eid -from cubicweb.common.view import EntityView, StartupView -from cubicweb.common.utils import UStringIO -from cubicweb.common.selectors import (paginated_rset, sorted_rset, - accept, implement_interface) -from cubicweb.web.views import baseviews -from cubicweb.web.views.boxes import BoxTemplate, BoxHtml -from cubicweb.web.views.calendar import MONTHNAMES -from cubicweb.web.views.navigation import PageNavigation +from cubicweb.view import EntityView, StartupView +from cubicweb.utils import UStringIO +from cubicweb.selectors import paginated_rset, sorted_rset, implements +from cubicweb.web import uicfg from cubicweb.web.htmlwidgets import BoxLink, BoxWidget -from cubicweb.interfaces import ISiocItem, ISiocContainer - -# FIXME: this view is generic and should be defined in cubicweb/web/views/?? -# See ticket #224980 -class SIOCView(EntityView): - id = 'sioc' - __selectors__ = EntityView.__selectors__ + (implement_interface,) - accepts_interfaces = (ISiocItem, ISiocContainer) - title = _('sioc') - templatable = False - content_type = 'text/xml' - - def call(self): - self.w(u'<?xml version="1.0" encoding="%s"?>\n' % self.req.encoding) - self.w(u'''<rdf:RDF - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" - xmlns:owl="http://www.w3.org/2002/07/owl#" - xmlns:foaf="http://xmlns.com/foaf/0.1/" - xmlns:sioc="http://rdfs.org/sioc/ns#" - xmlns:sioctype="http://rdfs.org/sioc/types#" - xmlns:dcterms="http://purl.org/dc/terms/">\n''') - for i in xrange(self.rset.rowcount): - self.cell_call(i, 0) - self.w(u'</rdf:RDF>\n') - - def cell_call(self, row, col): - self.wview('sioc_element', self.rset, row=row, col=col) +from cubicweb.web.views import baseviews, primary, boxes, calendar, navigation -class SIOCContainerView(EntityView): - id = 'sioc_element' - __selectors__ = EntityView.__selectors__ + (implement_interface,) - accepts_interfaces = (ISiocContainer,) - templatable = False - content_type = 'text/xml' - - def cell_call(self, row, col): - entity = self.complete_entity(row, col) - self.w(u'<sioc:%s rdf:about="%s">\n' % (html_escape(entity.isioc_type()), - html_escape(entity.absolute_url()))) - self.w(u'<dcterms:title>%s</dcterms:title>' % html_escape(entity.title)) - self.w(u'<dcterms:created>%s</dcterms:created>' % entity.creation_date) - self.w(u'<dcterms:modified>%s</dcterms:modified>' % entity.modification_date) - self.w(u'<!-- FIXME : here be items -->')#entity.isioc_items() - self.w(u'</sioc:%s>\n' % entity.isioc_type()) - -class SIOCItemView(EntityView): - id = 'sioc_element' - __selectors__ = EntityView.__selectors__ + (implement_interface,) - accepts_interfaces = (ISiocItem,) - templatable = False - content_type = 'text/xml' - - def cell_call(self, row, col): - entity = self.complete_entity(row, col) - self.w(u'<sioc:%s rdf:about="%s">\n' % ('Post', #entity.isioc_type(), - html_escape(entity.absolute_url()))) - self.w(u'<dcterms:title>%s</dcterms:title>' % html_escape(entity.title)) - self.w(u'<dcterms:created>%s</dcterms:created>' % entity.creation_date) - self.w(u'<dcterms:modified>%s</dcterms:modified>' % entity.modification_date) - if entity.content: - self.w(u'<sioc:content>%s</sioc:content>''' % html_escape(entity.isioc_content())) - if entity.related('entry_of'): - self.w(u'<sioc:has_container rdf:resource="%s"/>\n' % html_escape(entity.isioc_container().absolute_url())) - if entity.creator: - self.w(u'<sioc:has_creator>\n') - self.w(u'<sioc:User rdf:about="%s">\n' % html_escape(entity.creator.absolute_url())) - self.w(entity.creator.view('foaf')) - self.w(u'</sioc:User>\n') - self.w(u'</sioc:has_creator>\n') - self.w(u'<!-- FIXME : here be topics -->')#entity.isioc_topics() - self.w(u'<!-- FIXME : here be replies -->')#entity.isioc_replies() - self.w(u' </sioc:%s>\n' % 'Post') +uicfg.rdisplay.tag_attribute({}, 'Blog', 'title') +uicfg.rdisplay.tag_attribute({}, 'Blog', 'rss_url') +uicfg.rdisplay.tag_attribute({}, 'BlogEntry', 'title') +uicfg.rdisplay.tag_relation({'where': 'relations', 'vid': 'full_list'}, + ('*', 'entry_of', 'Blog'), 'object') +uicfg.rdisplay.tag_relation({'where': 'relations'}, + ('BlogEntry', 'entry_of', '*'), 'subject') - -class BlogPrimaryView(baseviews.PrimaryView): - accepts = ('Blog',) - skip_attrs = baseviews.PrimaryView.skip_attrs + ('title',) +class BlogPrimaryView(primary.PrimaryView): + __select__ = implements('Blog') - def render_entity_title(self, entity): - self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title())) + def render_entity_attributes(self, entity): + super(BlogPrimaryView, self).render_entity_attributes(entity) + self.w('<a class="right" href="%s">%s <img src="%s" alt="%s"/></a>' % ( + html_escape(entity.rss_feed_url()), self.req._(u'subscribe'), + self.req.external_resource('RSS_LOGO_16'), self.req._('rss icon'))) - def render_entity_relations(self, entity, siderelations): + def render_entity_relations(self, entity): + super(BlogPrimaryView, self).render_entity_relations(entity) rset = entity.related('entry_of', 'object') strio = UStringIO() self.pagination(self.req, rset, strio.write, page_size=10) self.wview('full_list', rset, 'null') self.w(strio.getvalue()) - def render_entity_attributes(self, entity, siderelations): - self.w('<a class="right" href="%s">%s <img src="%s" alt="%s"/></a>' % ( - html_escape(entity.rss_feed_url()), self.req._(u'subscribe'), - self.req.external_resource('RSS_LOGO_16'), self.req._('rss icon'))) - -class BlogEntryPrimaryView(baseviews.PrimaryView): - accepts = ('BlogEntry',) - skip_attrs = baseviews.PrimaryView.skip_attrs + ('title',) +class BlogEntryPrimaryView(primary.PrimaryView): + __select__ = implements('BlogEntry') show_attr_label = False - def render_entity_title(self, entity): - self.w(u'<h1>%s</h1>' % html_escape(entity.dc_title())) - - def content_format(self, entity): - return entity.view('reledit', rtype='content_format') - - def render_entity_relations(self, entity, siderelations): + def render_entity_relations(self, entity): rset = entity.related('entry_of', 'subject') if rset: _ = self.req._ @@ -142,13 +63,13 @@ def represent(self, items, year, month): """represent a single month entry""" - firstday = DateTime(year, month, 1) - lastday = DateTime(year, month, firstday.days_in_month) + firstday = datetime(year, month, 1) + lastday = datetime(year, month, monthrange(year, month)[1]) rql = ('Any B WHERE B is BlogEntry, 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]' % (_(MONTHNAMES[month-1]), year, nmb_entries) + label = u'%s %s [%s]' % (_(calendar.MONTHNAMES[month-1]), year, nmb_entries) vtitle = '%s %s' % (_('BlogEntry_plural'), label) url = html_escape(self.build_url(rql=rql, vtitle=vtitle, vid='full_list')) link = u'<a href="%s" title="">%s</a>' % (url, label) @@ -158,14 +79,14 @@ """display a list of entities by calling their <item_vid> view """ rset = self.req.execute('Any CD ORDERBY CD DESC WHERE B is BlogEntry, B creation_date CD') - + blogmonths = [] items = [] for (blogdate,) in rset: year, month = blogdate.year, blogdate.month if (year, month) not in blogmonths: blogmonths.append( (year, month) ) - if maxentries is None: + if maxentries is None: displayed_months = blogmonths needmore = False else: @@ -186,7 +107,7 @@ self.w(u'</div>') -class BlogEntryArchiveBox(BoxTemplate): +class BlogEntryArchiveBox(boxes.BoxTemplate): """blog side box displaying a Blog Archive""" id = 'blog_archives_box' title = _('boxes_blog_archives_box') @@ -196,18 +117,17 @@ """display blogs archive""" count_blogentry = self.req.execute('Any COUNT(B) WHERE B is BlogEntry') _ = self.req._ - + if count_blogentry[0][0] > 0: box = BoxWidget(_(self.title), id=self.id, islist=False) - box.append(BoxHtml(self.view('blog_archive', None, maxentries=12))) + box.append(boxes.BoxHtml(self.view('blog_archive', None, maxentries=12))) box.render(self.w) -class BlogEntryListBox(BoxTemplate): +class BlogEntryListBox(boxes.BoxTemplate): """display a box with latest blogs and rss""" id = 'blog_latest_box' title = _('blog_latest_box') - __selectors__ = BoxTemplate.__selectors__ visible = True # enabled by default order = 34 @@ -234,14 +154,14 @@ self.req._(u'subscribe'), rss_icon, self.req._('rss icon')) rss_url = self.build_url(vid='rss', rql=rql) box.append(BoxLink(rss_url, rss_label)) - box.render(self.w) + box.render(self.w) ## list views ################################################################# class BlogEntryListView(baseviews.ListView): - accepts = ('BlogEntry',) - + __select__ = implements('BlogEntry') + def call(self, klass='invisible', title=None, **kwargs): """display a list of entities by calling their <item_vid> view """ @@ -253,15 +173,17 @@ self.w(u'<h1>%s</h1>' % display_name(self.req, 'BlogEntry', form='plural')) super(BlogEntryListView, self).call(klass=klass, **kwargs) + class BlogEntryListItemView(baseviews.ListItemView): - id="full_list" - accepts = ('BlogEntry',) + id = 'full_list' + __select__ = implements('BlogEntry') redirect_vid = 'blog' - + class BlogEntryBlogView(baseviews.ListItemView): id = 'blog' - accepts = ('BlogEntry',) + __select__ = implements('BlogEntry') + def cell_call(self, row, col): entity = self.entity(row, col) w = self.w @@ -285,13 +207,13 @@ body = entity.printable_value('content') w(body) w(u'</div>') - w(u'<p class="postmetadata">%s</p>' % entity.view('post-reldata')) + w(u'<div class="postmetadata">%s</div>' % entity.view('post-reldata')) w(u'</div>') class BlogEntryPostMetaData(EntityView): id = 'post-reldata' - accepts = ('BlogEntry',) + __select__ = implements('BlogEntry') def cell_call(self, row, col): entity = self.entity(row, col) @@ -317,9 +239,8 @@ self.w(u' | '.join(reldata)) -class BlogNavigation(PageNavigation): - accepts = ('BlogEntry', ) - __selectors__ = (paginated_rset, sorted_rset, accept) +class BlogNavigation(navigation.PageNavigation): + __select__ = paginated_rset() & sorted_rset() & implements('BlogEntry') def index_display(self, start, stop): return u'%s' % (int(start / self.page_size)+1)