diff --git a/i18n/en.po b/i18n/en.po index e96428b232ebc70545146719483faa8f5edd32ef_aTE4bi9lbi5wbw==..6c9687eb82ba140e29cd41207cfd999c837d3643_aTE4bi9lbi5wbw== 100644 --- a/i18n/en.po +++ b/i18n/en.po @@ -24,6 +24,9 @@ msgid "Comment_plural" msgstr "Comments" +msgid "Latest comments" +msgstr "" + msgid "New Comment" msgstr "New comment" @@ -67,6 +70,9 @@ msgid "add comment" msgstr "" +msgid "comment content" +msgstr "comment" + # #-#-#-#-# schema.pot #-#-#-#-# # subject and object forms for each relation type # (no object form for final relation types) @@ -106,6 +112,12 @@ "section containing comments thread an allowing to post comment on " "commentable entities" +msgid "contentnavigation_latestcomments" +msgstr "" + +msgid "contentnavigation_latestcomments_description" +msgstr "" + msgid "delete comment" msgstr "" @@ -115,12 +127,9 @@ msgid "i18n_by_author_field" msgstr "by" -msgid "latest comment(s):" -msgstr "" - msgid "login" msgstr "" msgid "new comment for" msgstr "" @@ -121,9 +130,12 @@ msgid "login" msgstr "" msgid "new comment for" msgstr "" +msgid "on date" +msgstr "date" + msgid "register" msgstr "" diff --git a/i18n/fr.po b/i18n/fr.po index e96428b232ebc70545146719483faa8f5edd32ef_aTE4bi9mci5wbw==..6c9687eb82ba140e29cd41207cfd999c837d3643_aTE4bi9mci5wbw== 100644 --- a/i18n/fr.po +++ b/i18n/fr.po @@ -24,6 +24,9 @@ msgid "Comment_plural" msgstr "Commentaires" +msgid "Latest comments" +msgstr "Derniers commentaires" + msgid "New Comment" msgstr "Nouveau commentaire" @@ -68,6 +71,9 @@ msgid "add comment" msgstr "ajouter un commentaire" +msgid "comment content" +msgstr "commentaire" + # #-#-#-#-# schema.pot #-#-#-#-# # subject and object forms for each relation type # (no object form for final relation types) @@ -104,7 +110,14 @@ msgid "contentnavigation_commentsection_description" msgstr "" -"partie affichant la liste des commentaires à propos de l'entité visualisée" +"section affichant la liste des commentaires à propos de l'entité visualisée" + +msgid "contentnavigation_latestcomments" +msgstr "derniers commentaires de l'utilisateur" + +msgid "contentnavigation_latestcomments_description" +msgstr "" +"section affichant la liste des dernierscommentaires postés par un utilisateur" msgid "delete comment" msgstr "supprimer ce commentaire" @@ -115,12 +128,9 @@ msgid "i18n_by_author_field" msgstr "par" -msgid "latest comment(s):" -msgstr "derniers commentaire(s) :" - msgid "login" msgstr "s'authentifier" msgid "new comment for" msgstr "nouveau commentaire pour" @@ -121,9 +131,12 @@ msgid "login" msgstr "s'authentifier" msgid "new comment for" msgstr "nouveau commentaire pour" +msgid "on date" +msgstr "date" + msgid "register" msgstr "s'enregistrer" @@ -142,6 +155,3 @@ msgid "written by" msgstr "écrit par" - -#~ msgid "to comment" -#~ msgstr "pour commenter" diff --git a/schema.py b/schema.py index e96428b232ebc70545146719483faa8f5edd32ef_c2NoZW1hLnB5..6c9687eb82ba140e29cd41207cfd999c837d3643_c2NoZW1hLnB5 100644 --- a/schema.py +++ b/schema.py @@ -3,11 +3,7 @@ :copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr """ -from yams.buildobjs import EntityType, RelationType, SubjectRelation -try: - from yams.buildobjs import RichString -except: - from cubicweb.schema import RichString +from yams.buildobjs import EntityType, RelationType, SubjectRelation, RichString from cubicweb.schema import RRQLExpression class Comment(EntityType): diff --git a/views.py b/views.py index e96428b232ebc70545146719483faa8f5edd32ef_dmlld3MucHk=..6c9687eb82ba140e29cd41207cfd999c837d3643_dmlld3MucHk= 100644 --- a/views.py +++ b/views.py @@ -14,10 +14,8 @@ from simplejson import dumps -from cubicweb.selectors import (one_line_rset, implements, - has_permission, relation_possible, yes, - match_kwargs, score_entity, - authenticated_user) +from cubicweb.selectors import (implements, has_permission, authenticated_user, + score_entity, relation_possible, one_line_rset) from cubicweb.view import EntityView from cubicweb.uilib import rql_for_eid, cut, safe_cut from cubicweb.mixins import TreeViewMixIn @@ -21,5 +19,5 @@ from cubicweb.view import EntityView from cubicweb.uilib import rql_for_eid, cut, safe_cut from cubicweb.mixins import TreeViewMixIn -from cubicweb.web import stdmsgs, uicfg +from cubicweb.web import stdmsgs, uicfg, component, form, formwidgets as fw from cubicweb.web.action import LinkToEntityAction, Action @@ -25,7 +23,3 @@ from cubicweb.web.action import LinkToEntityAction, Action -from cubicweb.web.form import FormViewMixIn -from cubicweb.web.formwidgets import Button -from cubicweb.web.views import primary, baseviews, xmlrss -from cubicweb.web.component import EntityVComponent -from cubicweb.web.views.basecontrollers import JSonController, jsonize +from cubicweb.web.views import primary, baseviews, xmlrss, basecontrollers @@ -31,2 +25,5 @@ +_afs = uicfg.autoform_section +_afs.tag_subject_of(('*', 'comments', '*'), formtype='main', section='hidden') +_afs.tag_object_of(('*', 'comments', '*'), formtype='main', section='hidden') @@ -32,16 +29,11 @@ -uicfg.autoform_section.tag_subject_of(('*', 'comments', '*'), formtype='main', section='hidden') -uicfg.autoform_section.tag_object_of(('*', 'comments', '*'), formtype='main', section='hidden') -uicfg.actionbox_appearsin_addmenu.tag_subject_of(('*', 'comments', '*'), False) -uicfg.actionbox_appearsin_addmenu.tag_object_of(('*', 'comments', '*'), False) -uicfg.primaryview_section.tag_subject_of(('*', 'comments', '*'), 'hidden') -uicfg.primaryview_section.tag_object_of(('*', 'comments', '*'), 'hidden') -# XXX this is probably *very* inefficient since we'll fetch all entities created by the user -uicfg.primaryview_section.tag_object_of(('*', 'created_by', 'CWUser'), 'relations') -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')}) +_abaa = uicfg.actionbox_appearsin_addmenu +_abaa.tag_subject_of(('*', 'comments', '*'), False) +_abaa.tag_object_of(('*', 'comments', '*'), False) + +_pvs = uicfg.primaryview_section +_pvs.tag_subject_of(('*', 'comments', '*'), 'hidden') +_pvs.tag_object_of(('*', 'comments', '*'), 'hidden') # comment views ############################################################### @@ -80,9 +72,32 @@ self.w(u'</div>\n') +class CommentRootView(EntityView): + __regid__ = 'commentroot' + __select__ = implements('Comment') + + def cell_call(self, row, col, **kwargs): + entity = self.cw_rset.get_entity(row, col) + root = entity.root() + self.w(u'<a href="%s">%s %s</a> ' % ( + xml_escape(root.absolute_url()), + xml_escape(root.dc_type()), + xml_escape(cut(root.dc_title(), 40)))) + + +class CommentSummary(EntityView): + __regid__ = 'commentsummary' + __select__ = implements('Comment') + + def cell_call(self, row, col, **kwargs): + entity = self.cw_rset.get_entity(row, col) + maxsize = self._cw.property_value('navigation.short-line-size') + content = entity.printable_value('content', format='text/plain') + self.w(xml_escape(cut(content, maxsize))) + class CommentOneLineView(baseviews.OneLineView): __select__ = implements('Comment') def cell_call(self, row, col, **kwargs): entity = self.cw_rset.get_entity(row, col) @@ -83,18 +98,13 @@ class CommentOneLineView(baseviews.OneLineView): __select__ = implements('Comment') def cell_call(self, row, col, **kwargs): entity = self.cw_rset.get_entity(row, col) - root = entity.root() - self.w(u'[<a href="%s">#%s</a>] ' - % (xml_escape(root.absolute_url()), root.eid)) - maxsize = self._cw.property_value('navigation.short-line-size') - maxsize = maxsize - len(str(root.eid)) - content = entity.printable_value('content', format='text/plain') - content = xml_escape(cut(content, maxsize)) - self.w(u'<a href="%s">#%s <i>%s</i></a>\n' % ( - xml_escape(entity.absolute_url()), entity.eid, content)) + self.w(u'[%s] ' % self.entity.view('commentroot')) + self.w(u'<a href="%s"><i>%s</i></a>\n' % ( + xml_escape(entity.absolute_url()), + entity.view('commentsummary'))) class CommentTreeItemView(baseviews.ListItemView): @@ -161,5 +171,6 @@ self.w(u'<li id="comment%s" class="comment">\n' % entity.eid) -# comment edition views ####################################################### +class RssItemCommentView(xmlrss.RSSItemView): + __select__ = implements('Comment') @@ -165,5 +176,24 @@ -class InlineEditCommentForm(FormViewMixIn, EntityView): + def cell_call(self, row, col): + entity = self.cw_rset.complete_entity(row, col) + self.w(u'<item>\n') + self.w(u'<guid isPermaLink="true">%s</guid>\n' + % xml_escape(entity.absolute_url())) + self.render_title_link(entity) + description = entity.dc_description(format='text/html') + \ + self._cw._(u'about') + \ + u' <a href=%s>%s</a>' % (entity.root().absolute_url(), + entity.root().dc_title()) + self._marker('description', description) + self._marker('dc:date', entity.dc_date(self.date_format)) + self.render_entity_creator(entity) + self.w(u'</item>\n') + self.wview('rssitem', entity.related('comments', 'object'), 'null') + + +# comment forms ################################################################ + +class InlineEditCommentForm(form.FormViewMixIn, EntityView): __regid__ = 'editcommentform' __select__ = implements('Comment') @@ -191,9 +221,9 @@ self._cw.next_tabindex = count(20).next jseid = dumps(commented.eid) cancel_action = self.jsfunc % (jseid, '') - buttons = [Button(onclick=self.jsfunc % (jseid, self.jsonmeth)), - Button(stdmsgs.BUTTON_CANCEL, - onclick=cancel_action)] + buttons = [fw.Button(onclick=self.jsfunc % (jseid, self.jsonmeth)), + fw.Button(stdmsgs.BUTTON_CANCEL, + onclick=cancel_action)] form = self._cw.vreg['forms'].select('edition', self._cw, entity=newcomment, form_buttons=buttons) @@ -217,5 +247,5 @@ self.comment_form(commented, newcomment) -# comment component ########################################################### +# contextual components ######################################################## @@ -221,6 +251,6 @@ -class CommentSectionVComponent(EntityVComponent): +class CommentSectionVComponent(component.EntityVComponent): """a component to display a <div> html section including comments related to an object """ __regid__ = 'commentsection' @@ -223,8 +253,8 @@ """a component to display a <div> html section including comments related to an object """ __regid__ = 'commentsection' - __select__ = (EntityVComponent.__select__ + __select__ = (component.EntityVComponent.__select__ & relation_possible('comments', 'object', 'Comment')) context = 'navcontentbottom' @@ -260,7 +290,32 @@ # req.fckeditor_config() -# comment actions ############################################################# +class UserLatestCommentsSection(component.EntityVComponent): + """a section to display latest comments by a user""" + __select__ = component.EntityVComponent.__select__ & implements('CWUser') + __regid__ = 'latestcomments' + + def cell_call(self, row, col, view=None): + user = self.cw_rset.get_entity(row, col) + maxrelated = self._cw.property_value('navigation.related-limit') + 1 + rset = self._cw.execute( + 'Any C,CD,C,CCF ORDERBY CD DESC LIMIT %s WHERE C is Comment, ' + 'C creation_date CD, C content CC, C content_format CCF, ' + 'C created_by U, U eid %%(u)s' % maxrelated, + {'u': user.eid}) + if rset: + self.w(u'<div class="section">') + self.w(u'<h4>%s</h4>\n' % self._cw._('Latest comments').capitalize()) + self.wview('table', rset, + headers=[_('about'), _('on date'), + _('comment content')], + cellvids={0: 'commentroot', + 2: 'commentsummary', + }) + self.w(u'</div>') + + +# actions ###################################################################### class ReplyCommentAction(LinkToEntityAction): __regid__ = 'reply_comment' @@ -310,8 +365,7 @@ class DeleteCommentAction(Action): __regid__ = 'delete_comment' - __select__ = implements('Comment') & \ - authenticated_user() & \ + __select__ = implements('Comment') & authenticated_user() & \ score_entity(lambda x: not x.reverse_comments and x.has_perm('delete')) title = _('delete comment') @@ -321,5 +375,6 @@ def url(self): return self._cw.build_url(rql=self.cw_rset.printable_rql(), vid='deleteconf') -# add some comments related methods to the Jsoncontroller ##################### + +# JSONController extensions through monkey-patching ############################ @@ -325,8 +380,8 @@ -@monkeypatch(JSonController) -@jsonize +@monkeypatch(basecontrollers.JSonController) +@basecontrollers.jsonize def js_add_comment(self, commented, text, format): return self._cw.execute('INSERT Comment C: C comments X, C content %(text)s, ' 'C content_format %(format)s WHERE X eid %(x)s', {'format' : format, 'text' : text, 'x' : commented}, 'x')[0][0] @@ -328,11 +383,11 @@ def js_add_comment(self, commented, text, format): return self._cw.execute('INSERT Comment C: C comments X, C content %(text)s, ' 'C content_format %(format)s WHERE X eid %(x)s', {'format' : format, 'text' : text, 'x' : commented}, 'x')[0][0] -@monkeypatch(JSonController) -@jsonize +@monkeypatch(basecontrollers.JSonController) +@basecontrollers.jsonize def js_edit_comment(self, comment, text, format): self._cw.execute('SET C content %(text)s, C content_format %(format)s ' 'WHERE C eid %(x)s', {'format' : format, 'text' : text, 'x' : comment}, 'x') @@ -335,26 +390,4 @@ def js_edit_comment(self, comment, text, format): self._cw.execute('SET C content %(text)s, C content_format %(format)s ' 'WHERE C eid %(x)s', {'format' : format, 'text' : text, 'x' : comment}, 'x') - - -# RSS view #################################################################### - -class RssItemCommentView(xmlrss.RSSItemView): - __select__ = implements('Comment') - - def cell_call(self, row, col): - entity = self.cw_rset.complete_entity(row, col) - self.w(u'<item>\n') - self.w(u'<guid isPermaLink="true">%s</guid>\n' - % xml_escape(entity.absolute_url())) - self.render_title_link(entity) - description = entity.dc_description(format='text/html') + \ - self._cw._(u'about') + \ - u' <a href=%s>%s</a>' % (entity.root().absolute_url(), - entity.root().dc_title()) - self._marker('description', description) - self._marker('dc:date', entity.dc_date(self.date_format)) - self.render_entity_creator(entity) - self.w(u'</item>\n') - self.wview('rssitem', entity.related('comments', 'object'), 'null')