How to override enable_conversation added.

This commit is contained in:
Timo Stollenwerk 2012-01-25 15:57:10 +01:00
parent 80d70bbf08
commit 943661cf42
6 changed files with 96 additions and 87 deletions

View File

@ -3,12 +3,12 @@ Howto extend the comment form with additional fields
==================================================== ====================================================
This document explains how to extend the plone.app.discussion comment form with This document explains how to extend the plone.app.discussion comment form with
additional fields in an add-on product. additional fields in an add-on product.
plone.app.discussion uses the plone.app.discussion uses the
`plone.z3cform.fieldsets <http://pypi.python.org/pypi/plone.z3cform#fieldsets-and-form-extenders>`_ `plone.z3cform.fieldsets <http://pypi.python.org/pypi/plone.z3cform#fieldsets-and-form-extenders>`_
package which provides support for modifications via "extender" adapters. The package which provides support for modifications via "extender" adapters. The
idea is that a third party component can modify the fields in a form and the idea is that a third party component can modify the fields in a form and the
way that they are grouped and ordered. way that they are grouped and ordered.
.. note:: .. note::
@ -29,58 +29,58 @@ First, create a new plone package::
$ paster create -t plone example.commentextender $ paster create -t plone example.commentextender
Go to the main directory of the package Go to the main directory of the package
(example.commentextender/example/commentextender) and create a new file (example.commentextender/example/commentextender) and create a new file
*commentextender.py*. *commentextender.py*.
This file contains the ICommentExtenderFields interface definition with a This file contains the ICommentExtenderFields interface definition with a
"website" field, a persistent CommentExtenderFields class to store the value of "website" field, a persistent CommentExtenderFields class to store the value of
the "website" field, a CommentExtenderFactory to create the the "website" field, a CommentExtenderFactory to create the
CommentExtenderFields, and a CommentExtender class to extend the default CommentExtenderFields, and a CommentExtender class to extend the default
comment form with the "website" field:: comment form with the "website" field::
from persistent import Persistent from persistent import Persistent
from z3c.form.field import Fields from z3c.form.field import Fields
from zope import interface from zope import interface
from zope import schema from zope import schema
from zope.annotation import factory from zope.annotation import factory
from zope.component import adapts from zope.component import adapts
from zope.interface import Interface from zope.interface import Interface
from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.publisher.interfaces.browser import IDefaultBrowserLayer
from plone.z3cform.fieldsets import extensible from plone.z3cform.fieldsets import extensible
from plone.app.discussion.browser.comments import CommentForm from plone.app.discussion.browser.comments import CommentForm
from plone.app.discussion.comment import Comment from plone.app.discussion.comment import Comment
# Interface to define the fields we want to add to the comment form. # Interface to define the fields we want to add to the comment form.
class ICommentExtenderFields(Interface): class ICommentExtenderFields(Interface):
website = schema.TextLine(title=u"Website", required=False) website = schema.TextLine(title=u"Website", required=False)
# Persistent class that implements the ICommentExtenderFields interface # Persistent class that implements the ICommentExtenderFields interface
class CommentExtenderFields(Persistent): class CommentExtenderFields(Persistent):
interface.implements(ICommentExtenderFields) interface.implements(ICommentExtenderFields)
adapts(Comment) adapts(Comment)
website = u"" website = u""
# CommentExtenderFields factory # CommentExtenderFields factory
CommentExtenderFactory = factory(CommentExtenderFields) CommentExtenderFactory = factory(CommentExtenderFields)
# Extending the comment form with the fields defined in the # Extending the comment form with the fields defined in the
# ICommentExtenderFields interface. # ICommentExtenderFields interface.
class CommentExtender(extensible.FormExtender): class CommentExtender(extensible.FormExtender):
adapts(Interface, IDefaultBrowserLayer, CommentForm) adapts(Interface, IDefaultBrowserLayer, CommentForm)
fields = Fields(ICommentExtenderFields) fields = Fields(ICommentExtenderFields)
def __init__(self, context, request, form): def __init__(self, context, request, form):
self.context = context self.context = context
self.request = request self.request = request
self.form = form self.form = form
def update(self): def update(self):
# Add the fields defined in ICommentExtenderFields to the form. # Add the fields defined in ICommentExtenderFields to the form.
self.add(ICommentExtenderFields, prefix="") self.add(ICommentExtenderFields, prefix="")
@ -90,7 +90,7 @@ comment form with the "website" field::
.. seealso:: .. seealso::
* See the plone.z3cform pypi page for more documentation about how to add, * See the plone.z3cform pypi page for more documentation about how to add,
hide, and reorder fields: hide, and reorder fields:
http://pypi.python.org/pypi/plone.z3cform#fieldsets-and-form-extenders http://pypi.python.org/pypi/plone.z3cform#fieldsets-and-form-extenders
Now register the CommentExtenderFactory and CommentExtender Classes that has Now register the CommentExtenderFactory and CommentExtender Classes that has
@ -99,7 +99,7 @@ been created by adding the following lines to your configure.zcml::
<adapter <adapter
factory=".commentextender.CommentExtenderFactory" factory=".commentextender.CommentExtenderFactory"
provides=".commentextender.ICommentExtenderFields" /> provides=".commentextender.ICommentExtenderFields" />
<adapter <adapter
factory=".commentextender.CommentExtender" factory=".commentextender.CommentExtender"
provides="plone.z3cform.fieldsets.interfaces.IFormExtender" /> provides="plone.z3cform.fieldsets.interfaces.IFormExtender" />
@ -112,33 +112,33 @@ Since we do not only want to store the "website" value on the comments, but also
to show these values for existing comments, we have to override the comments to show these values for existing comments, we have to override the comments
viewlet. The easiest way to do this is to use z3c.jbot. viewlet. The easiest way to do this is to use z3c.jbot.
First, add `z3c.jbot <http://pypi.python.org/pypi/z3c.jbot>`_. to the setup.py First, add `z3c.jbot <http://pypi.python.org/pypi/z3c.jbot>`_. to the setup.py
of the example.commentextender package:: of the example.commentextender package::
install_requires=[ install_requires=[
... ...
'z3c.jbot', 'z3c.jbot',
], ],
Next, create a new directory called "overrides" inside the Next, create a new directory called "overrides" inside the
example.commentextender package and register it together with z3c.jbot in your example.commentextender package and register it together with z3c.jbot in your
configure.zcml:: configure.zcml::
<configure <configure
... ...
xmlns:browser="http://namespaces.zope.org/browser"> xmlns:browser="http://namespaces.zope.org/browser">
... ...
<include package="z3c.jbot" file="meta.zcml" /> <include package="z3c.jbot" file="meta.zcml" />
<browser:jbot <browser:jbot
directory="overrides" /> directory="overrides" />
</configure> </configure>
Copy plone.app.discussion/plone/app/discussion/browser/comments.pt to the Copy plone.app.discussion/plone/app/discussion/browser/comments.pt to the
overrides directory we just created and rename comments.pt to overrides directory we just created and rename comments.pt to
plone.app.discussion.browser.comments.pt. plone.app.discussion.browser.comments.pt.
You can now add code to show the website attribute to the documentByLine:: You can now add code to show the website attribute to the documentByLine::
@ -153,5 +153,5 @@ You can now add code to show the website attribute to the documentByLine::
</div> </div>
</div> </div>
Restart your Plone instance and you will see the "website" field in the Restart your Plone instance and you will see the "website" field in the
documentByLine next to the comments. documentByLine next to the comments.

View File

@ -1,17 +1,17 @@
================================================================================ ===============================================================================
How to override plone.app.discussion's comments viewlet How to override plone.app.discussion's comments viewlet
================================================================================ ===============================================================================
This document explains how to override the plone.app.discussion comments This document explains how to override the plone.app.discussion comments
viewlet that controls the way existing comments are displayed. viewlet that controls the way existing comments are displayed.
There are three different ways to override plone.app.discussion's comments There are three different ways to override plone.app.discussion's comments
viewlet: through-the-web, on the file system with z3c.jbot, and by overriding viewlet: through-the-web, on the file system with z3c.jbot, and by overriding
the comments viewlet class on the file system. the comments viewlet class on the file system.
Overriding the comments viewlet template throught-the-web is the quick and Overriding the comments viewlet template throught-the-web is the quick and
dirty approach. Using z3c.jbot is the recommended approach if you just want to dirty approach. Using z3c.jbot is the recommended approach if you just want to
override the comments viewlet template. If you want full control over the override the comments viewlet template. If you want full control over the
comments viewlet class, for instance if you want to add/customize view methods, comments viewlet class, for instance if you want to add/customize view methods,
overriding the comments viewlet class on the file system is the recommended overriding the comments viewlet class on the file system is the recommended
approach. approach.
@ -20,7 +20,7 @@ approach.
Override the comments template through-the web Override the comments template through-the web
---------------------------------------------- ----------------------------------------------
Overriding the comments template through-the web is the easiest way to Overriding the comments template through-the web is the easiest way to
customize the comments viewlet:: customize the comments viewlet::
* Go to the ZMI (http://localhost:8080/Plone/manage_main) * Go to the ZMI (http://localhost:8080/Plone/manage_main)
@ -62,10 +62,10 @@ Create the template directory we just registered::
Copy the comments viewlet template we want to override to the Copy the comments viewlet template we want to override to the
overrides directory we just created and registered:: overrides directory we just created and registered::
$ cp ../parts/omelette/plone/app/discussion/browser/comments.pt overrides/plone.app.discussion.browser.comments.pt $ cp ../parts/omelette/plone/app/discussion/browser/comments.pt overrides/plone.app.discussion.browser.comments.pt
Restart your Plone instance and you can start to customize Restart your Plone instance and you can start to customize
the plone.app.discussion.browser.comments.pt we just created. the plone.app.discussion.browser.comments.pt we just created.
@ -73,7 +73,7 @@ Override the comments viewlet class on the file system
------------------------------------------------------ ------------------------------------------------------
Overriding/subclassing the comments viewlet class is allows you not only to Overriding/subclassing the comments viewlet class is allows you not only to
override the comments viewlet template, but also the comment viewlets view override the comments viewlet template, but also the comment viewlets view
methods. There are many ways to override components in Plone with the Zope methods. There are many ways to override components in Plone with the Zope
Component Architecture (ZCA), which is beyond the scope of this howto. Component Architecture (ZCA), which is beyond the scope of this howto.
@ -118,16 +118,16 @@ Once we registered the custom discussion browser layer and the viewlet, we can c
comments.py file with our custom version of the comments viewlet:: comments.py file with our custom version of the comments viewlet::
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from plone.app.discussion.browser.comments import CommentsViewlet as PloneAppDiscussionCommentsViewlet from plone.app.discussion.browser.comments import CommentsViewlet as PloneAppDiscussionCommentsViewlet
from plone.app.discussion.browser.comments import CommentForm from plone.app.discussion.browser.comments import CommentForm
class CommentsViewlet(PloneAppDiscussionCommentsViewlet): class CommentsViewlet(PloneAppDiscussionCommentsViewlet):
form = CommentForm form = CommentForm
index = ViewPageTemplateFile('comments.pt') index = ViewPageTemplateFile('comments.pt')
def get_commenter_home_url(self, username=None): def get_commenter_home_url(self, username=None):
if username is None: if username is None:
return None return None
@ -145,7 +145,7 @@ Override the comments viewlet Javascript
Overriding the comments viewlet javascript works just like overriding the Overriding the comments viewlet javascript works just like overriding the
comments viewlet. We register the javascript file for our custom browser comments viewlet. We register the javascript file for our custom browser
layer and remove the existing javascript file in layer and remove the existing javascript file in
profiles/default/jsregistry.xml:: profiles/default/jsregistry.xml::
<?xml version="1.0"?> <?xml version="1.0"?>

View File

@ -1,13 +1,26 @@
==============================================================================
Howto override the enable_conversation method.
==============================================================================
configure.zcml:: plone.app.discussion way to decide if commenting is enabled on a content
object can be quite complex and cumbersome due to the need to be backward
compatible with the way the old commenting system in Plone (<4.1) worked.
The comments viewlet calls the enabled method of the ConversationView to
decide if the add comment form should show up:
.. literalinclude:: ../../../plone/app/discussion/browser/conversation.py
:language: python
:pyobject: ConversationView
If you want to override this behavior, you just have to create your own enabled method. To do so, we first have to register our custom
ConversationView by overriding the existing one in our configure.zcml::
<configure <configure
xmlns="http://namespaces.zope.org/zope" xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser" xmlns:browser="http://namespaces.zope.org/browser"
xmlns:plone="http://namespaces.plone.org/plone" i18n_domain="mycustompackage.discussion">
xmlns:grok="http://namespaces.zope.org/grok"
i18n_domain="freitag.behavior.allowdiscussion">
<!-- Override plone.app.discussion's conversation view --> <!-- Override plone.app.discussion's conversation view -->
<browser:page <browser:page
name="conversation_view" name="conversation_view"
@ -15,45 +28,40 @@ configure.zcml::
class=".conversation.ConversationView" class=".conversation.ConversationView"
permission="zope2.View" permission="zope2.View"
/> />
</configure> </configure>
conversation.py Now we implement the conversation view with a single "enable" method in
conversation.py::
from zope.component import queryUtility from zope.component import queryUtility
from plone.registry.interfaces import IRegistry from plone.registry.interfaces import IRegistry
from Acquisition import aq_base
from Acquisition import aq_chain
from Acquisition import aq_inner from Acquisition import aq_inner
from Products.CMFCore.utils import getToolByName from Products.CMFCore.utils import getToolByName
from Products.CMFCore.interfaces import IFolderish
from Products.CMFPlone.interfaces import IPloneSiteRoot
from Products.CMFPlone.interfaces import INonStructuralFolder
from plone.app.discussion.interfaces import IDiscussionSettings from plone.app.discussion.interfaces import IDiscussionSettings
class ConversationView(object): class ConversationView(object):
def enabled(self): def enabled(self):
context = aq_inner(self.context) context = aq_inner(self.context)
# Fetch discussion registry # Fetch discussion registry
registry = queryUtility(IRegistry) registry = queryUtility(IRegistry)
settings = registry.forInterface(IDiscussionSettings, check=False) settings = registry.forInterface(IDiscussionSettings, check=False)
# Check if discussion is allowed globally # Check if discussion is allowed globally
if not settings.globally_enabled: if not settings.globally_enabled:
return False return False
# Check if discussion is allowed on the content object # Check if discussion is allowed on the content object
if context.allow_discussion is not None: if context.allow_discussion is not None:
return context.allow_discussion return context.allow_discussion
# Check if discussion is allowed on the content type # Check if discussion is allowed on the content type
portal_types = getToolByName(self, 'portal_types') portal_types = getToolByName(self, 'portal_types')
document_fti = getattr(portal_types, context.portal_type) document_fti = getattr(portal_types, context.portal_type)

View File

@ -3,7 +3,7 @@ How to set discussion settings with generic setup
================================================= =================================================
This document explains how to set plone.app.discussion's settings with a This document explains how to set plone.app.discussion's settings with a
generic setup profile. generic setup profile.
plone.app.discussion uses plone.app.registry ... plone.app.discussion uses plone.app.registry ...

View File

@ -1,6 +1,6 @@
================================================================================ ===============================================================================
Howto write a custom email notification Howto write a custom email notification
================================================================================ ===============================================================================
This document explains how to write a custom email notification for This document explains how to write a custom email notification for
plone.app.discussion. plone.app.discussion.

View File

@ -6,3 +6,4 @@ Howtos
:maxdepth: 1 :maxdepth: 1
howto_extend_the_comment_form.txt howto_extend_the_comment_form.txt
howto_override_enable_conversation.txt