added viewlet that overrides the standard plone commenting viewlet (no tests so far!).
svn path=/plone.app.discussion/trunk/; revision=27045
This commit is contained in:
parent
afb07e5f0b
commit
895105b2c9
@ -1,10 +1,11 @@
|
|||||||
<configure
|
<configure
|
||||||
xmlns="http://namespaces.zope.org/zope"
|
xmlns="http://namespaces.zope.org/zope"
|
||||||
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
|
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
|
||||||
i18n_domain="plone.app.discussion">
|
i18n_domain="plone.app.discussion">
|
||||||
|
|
||||||
<include file="permissions.zcml" />
|
<include file="permissions.zcml" />
|
||||||
<include package=".browser" />
|
<include package=".browser" />
|
||||||
|
<include package=".viewlets" />
|
||||||
|
|
||||||
<!-- Register the installation GenericSetup extension profile -->
|
<!-- Register the installation GenericSetup extension profile -->
|
||||||
<genericsetup:registerProfile
|
<genericsetup:registerProfile
|
||||||
@ -15,28 +16,28 @@
|
|||||||
provides="Products.GenericSetup.interfaces.EXTENSION"
|
provides="Products.GenericSetup.interfaces.EXTENSION"
|
||||||
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
|
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Comments -->
|
<!-- Comments -->
|
||||||
<class class=".comment.Comment">
|
<class class=".comment.Comment">
|
||||||
<require interface=".interfaces.IComment" permission="zope2.View" />
|
<require interface=".interfaces.IComment" permission="zope2.View" />
|
||||||
<require attributes="Title Creator getId" permission="zope2.View" />
|
<require attributes="Title Creator getId" permission="zope2.View" />
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
<utility
|
<utility
|
||||||
component=".comment.CommentFactory"
|
component=".comment.CommentFactory"
|
||||||
name="plone.Comment"
|
name="plone.Comment"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Conversations -->
|
<!-- Conversations -->
|
||||||
<class class=".conversation.Conversation">
|
<class class=".conversation.Conversation">
|
||||||
<require interface=".interfaces.IConversation" permission="zope2.View" />
|
<require interface=".interfaces.IConversation" permission="zope2.View" />
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
<adapter factory=".conversation.conversationAdapterFactory" />
|
<adapter factory=".conversation.conversationAdapterFactory" />
|
||||||
|
|
||||||
<adapter factory=".conversation.ConversationReplies" />
|
<adapter factory=".conversation.ConversationReplies" />
|
||||||
<adapter factory=".conversation.CommentReplies" />
|
<adapter factory=".conversation.CommentReplies" />
|
||||||
|
|
||||||
<!-- Event subscribers -->
|
<!-- Event subscribers -->
|
||||||
<subscriber
|
<subscriber
|
||||||
for="plone.app.discussion.interfaces.IComment
|
for="plone.app.discussion.interfaces.IComment
|
||||||
|
6
plone/app/discussion/overrides.zcml
Normal file
6
plone/app/discussion/overrides.zcml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<configure xmlns="http://namespaces.zope.org/zope">
|
||||||
|
|
||||||
|
<include
|
||||||
|
file="viewlets/overrides.zcml" />
|
||||||
|
|
||||||
|
</configure>
|
0
plone/app/discussion/viewlets/__init__.py
Normal file
0
plone/app/discussion/viewlets/__init__.py
Normal file
90
plone/app/discussion/viewlets/comments.pt
Normal file
90
plone/app/discussion/viewlets/comments.pt
Normal 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
plone/app/discussion/viewlets/comments.py
Normal file
70
plone/app/discussion/viewlets/comments.py
Normal 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')
|
3
plone/app/discussion/viewlets/configure.zcml
Normal file
3
plone/app/discussion/viewlets/configure.zcml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<configure xmlns="http://namespaces.zope.org/zope">
|
||||||
|
|
||||||
|
</configure>
|
14
plone/app/discussion/viewlets/overrides.zcml
Normal file
14
plone/app/discussion/viewlets/overrides.zcml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<configure xmlns="http://namespaces.zope.org/zope"
|
||||||
|
xmlns:browser="http://namespaces.zope.org/browser">
|
||||||
|
|
||||||
|
<!-- comments viewlet -->
|
||||||
|
<browser:viewlet
|
||||||
|
name="plone.comments"
|
||||||
|
for="Products.CMFCore.interfaces.IContentish"
|
||||||
|
manager="plone.app.layout.viewlets.interfaces.IBelowContent"
|
||||||
|
view="plone.app.layout.globals.interfaces.IViewView"
|
||||||
|
template="comments.pt"
|
||||||
|
class="plone.app.discussion.viewlets.comments.CommentsViewlet"
|
||||||
|
permission="zope2.View" />
|
||||||
|
|
||||||
|
</configure>
|
Loading…
Reference in New Issue
Block a user