Move viewlets to browser package, use a layer instead of an overrides.zcml. Also add ++comment++ namespace, though it may require refactoring

svn path=/plone.app.discussion/trunk/; revision=27055
This commit is contained in:
Martin Aspeli
2009-05-23 04:55:06 +00:00
parent 895105b2c9
commit edf956f01c
14 changed files with 60 additions and 29 deletions
+90
View File
@@ -0,0 +1,90 @@
<tal:block define="userHasReplyPermission view/can_reply;
isDiscussionAllowed view/is_discussion_allowed;
replies view/get_replies;
isAnon view/is_anonymous"
i18n:domain="plone">
<div class="discussion"
tal:condition="python:replies or (userHasReplyPermission and isDiscussionAllowed) or (isAnon and not userHasReplyPermission and isDiscussionAllowed)">
<p>plone.app.discussion viewlet:</p>
<form name="reply"
action=""
method="post"
tal:condition="python:userHasReplyPermission and isDiscussionAllowed"
tal:attributes="action string:${context/absolute_url}/discussion_reply_form">
<input class="standalone"
style="margin-bottom: 1.25em;"
type="submit"
value="Add Comment"
i18n:attributes="value label_add_comment;"
/>
</form>
<form tal:condition="python:isAnon and not userHasReplyPermission and isDiscussionAllowed"
tal:attributes="action view/login_action">
<input class="standalone"
style="margin-bottom: 1.25em;"
type="submit"
value="Log in to add comments"
i18n:attributes="value label_login_to_add_comments;"
/>
</form>
<tal:getreplies repeat="reply_dict replies">
<div class="comment" style=""
tal:define="indent python:reply_dict['depth']*2;
reply python:reply_dict['object']"
tal:attributes="style string:margin-left:${indent}em;">
<h3>
<a name="comments" tal:attributes="name reply/id">
<span tal:replace="reply/pretty_title_or_id">Comment title</span>
</a>
</h3>
<div class="documentByLine"
tal:define="creator reply/Creator;
anonymous_creator python:creator in ('Anonymous User', '');
mi python:not anonymous_creator and view.member_info(creator);
fullname python: mi and mi['fullname'] or creator;" >
<tal:posted i18n:translate="label_comment_by">Posted by</tal:posted>
<tal:name content="fullname"
condition="not:anonymous_creator">Poster Name</tal:name>
<tal:name i18n:translate="label_anonymous_user"
condition="anonymous_creator">Anonymous User</tal:name>
<tal:at i18n:translate="label_commented_at">at</tal:at>
<span tal:replace="python:view.format_time(reply.ModificationDate())">8/23/2001 12:40:44 PM</span>
</div>
<div class="commentBody"
tal:content="structure reply/CookedBody">
This is the body text of the comment.
</div>
<form name="reply"
action="discussion_reply_form"
method="post"
style="display: inline;"
tal:attributes="action string:${reply/absolute_url}/discussion_reply_form"
tal:condition="python:userHasReplyPermission and isDiscussionAllowed">
<input type="hidden"
name="subject"
tal:attributes="value reply/pretty_title_or_id" />
<input class="standalone"
type="submit"
value="Reply"
i18n:attributes="value label_reply;"
/>
</form>
<form name="delete"
action=""
method="post"
style="display: inline;"
tal:condition="view/can_manage"
tal:attributes="action string:${reply/absolute_url}/deleteDiscussion">
<input class="destructive"
type="submit"
value="Remove"
i18n:attributes="value label_remove;"
/>
</form>
</div>
</tal:getreplies>
</div>
</tal:block>
+70
View File
@@ -0,0 +1,70 @@
from urllib import quote as url_quote
from Acquisition import aq_inner, aq_parent
from AccessControl import getSecurityManager
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.CMFCore.utils import getToolByName
from Products.CMFDefault.DiscussionTool import DiscussionNotAllowed
from plone.app.layout.viewlets.common import ViewletBase
class CommentsViewlet(ViewletBase):
index = ViewPageTemplateFile('comments.pt')
def update(self):
super(CommentsViewlet, self).update()
self.portal_discussion = getToolByName(self.context, 'portal_discussion', None)
self.portal_membership = getToolByName(self.context, 'portal_membership', None)
def can_reply(self):
return getSecurityManager().checkPermission('Reply to item', aq_inner(self.context))
def is_discussion_allowed(self):
if self.portal_discussion is None:
return False
else:
return self.portal_discussion.isDiscussionAllowedFor(aq_inner(self.context))
def get_replies(self):
replies = []
context = aq_inner(self.context)
container = aq_parent(context)
pd = self.portal_discussion
def getRs(obj, replies, counter):
rs = pd.getDiscussionFor(obj).getReplies()
if len(rs) > 0:
rs.sort(lambda x, y: cmp(x.modified(), y.modified()))
for r in rs:
replies.append({'depth':counter, 'object':r})
getRs(r, replies, counter=counter + 1)
try:
getRs(context, replies, 0)
except DiscussionNotAllowed:
# We tried to get discussions for an object that has not only
# discussions turned off but also no discussion container.
return []
return replies
def is_anonymous(self):
return self.portal_state.anonymous()
def login_action(self):
return '%s/login_form?came_from=%s' % (self.navigation_root_url, url_quote(self.request.get('URL', '')),)
def can_manage(self):
return getSecurityManager().checkPermission('Manage portal', aq_inner(self.context))
def member_info(self, creator):
if self.portal_membership is None:
return None
else:
return self.portal_membership.getMemberInfo(creator)
def format_time(self, time):
context = aq_inner(self.context)
util = getToolByName(context, 'translation_service')
return util.ulocalized_time(time, 1, context, domain='plonelocales')
@@ -2,6 +2,20 @@
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="plone.app.discussion">
<!-- Traversal adapter -->
<adapter factory=".traversal.ConversationNamespace" name="comment" />
<!-- Comments viewlet -->
<browser:viewlet
name="plone.comments"
for="Products.CMFCore.interfaces.IContentish"
layer="..interfaces.IDiscussionLayer"
view="plone.app.layout.globals.interfaces.IViewView"
manager="plone.app.layout.viewlets.interfaces.IBelowContent"
template="comments.pt"
class=".comments.CommentsViewlet"
permission="zope2.View"
/>
</configure>
+25
View File
@@ -3,3 +3,28 @@ IDiscussion container for the context, from which traversal will continue
into an actual comment object.
"""
from zope.interface import Interface, implements
from zope.component import adapts
from zope.traversing.interfaces import ITraversable, TraversalError
from zope.publisher.interfaces.browser import IBrowserRequest
from plone.app.discussion.interfaces import IConversation
class ConversationNamespace(object):
"""Allow traversal into a conversation
"""
implements(ITraversable)
adapts(Interface, IBrowserRequest)
def __init__(self, context, request=None):
self.context = context
self.request = request
def traverse(self, name, ignore):
conversation = IConversation(self.context, None)
if conversation is None:
raise TraversalError('++comment++')
return conversation.__of__(self.context)