Last active
August 29, 2015 14:07
-
-
Save djowett/3b7f40318d01f10db670 to your computer and use it in GitHub Desktop.
z3cform portlet example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<configure | |
xmlns="http://namespaces.zope.org/zope" | |
xmlns:plone="http://namespaces.plone.org/plone" | |
xmlns:i18n="http://namespaces.zope.org/i18n" | |
xmlns:five="http://namespaces.zope.org/five" | |
i18n_domain="your.package"> | |
<include package="plone.app.portlets"/> | |
<!-- I think these lines /could/ also help get rid of a nasty | |
ComponentLookupError similar to this one http://pastebin.com/ZDkN8P0d | |
but just when I thought I'd been clever I realised I'd stuck them in | |
another project (Ho hum) | |
<include package="plone.app.z3cform" /> | |
<include package="plone.z3cform" /> | |
<include package="z3c.form" /> | |
--> | |
<plone:portlet | |
name="your.package.exampleportlet" | |
interface=".exampleportlet.IExamplePortlet" | |
assignment=".exampleportlet.Assignment" | |
view_permission="zope2.View" | |
edit_permission="cmf.ManagePortal" | |
renderer=".exampleportlet.Renderer" | |
addview=".exampleportlet.AddForm" | |
editview=".exampleportlet.EditForm" | |
/> | |
</configure> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dl class="portlet portletExamplePortlet" | |
tal:define="portal_url context/@@plone_portal_state/portal_url;" | |
i18n:domain="your.package"> | |
<dt class="portletHeader"> | |
<span class="portletTopLeft"></span> | |
<span tal:condition="view/title" tal:content="view/title"> | |
My example portlet | |
</span> | |
<span class="portletTopRight"></span> | |
</dt> | |
<dd class="portletItem odd"> | |
Something more to add? | |
</dd> | |
</dl> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from zope.interface import implements | |
from plone.portlets.interfaces import IPortletDataProvider | |
from plone.app.portlets.portlets import base | |
# NOTE: If you do not define any fields for the portlet configuration schema below | |
# you can remove comment the following import of 'zope.schema', also see other Notes | |
# below | |
from zope import schema | |
from zope.schema.fieldproperty import FieldProperty | |
from z3c.form import field | |
from plone.app.portlets.browser import z3cformhelper | |
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile | |
# TODO: If you require i18n translation for any of your schema fields below, | |
# uncomment one of the following to import your package MessageFactory | |
from your.package import MessageFactory as _ | |
# from your.package import _ | |
class IExamplePortlet(IPortletDataProvider): | |
"""A portlet | |
It inherits from IPortletDataProvider because for this portlet, the | |
data that is being rendered and the portlet assignment itself are the | |
same. | |
""" | |
# TODO: Add any zope.schema fields here to capture portlet configuration | |
# information. | |
# NOTE: Alternatively, if there are no settings, remove this field and | |
# leave this as an empty interface - see also notes around the add form | |
# and edit form below. | |
some_field = schema.TextLine(title=_(u"Some field"), | |
description=_(u"A field to use"), | |
required=True) | |
class Assignment(base.Assignment): | |
"""Portlet assignment. | |
This is what is actually managed through the portlets UI and associated | |
with columns. | |
""" | |
implements(IExamplePortlet) | |
# TODO: Set default values for the configurable parameters here | |
some_field = u"Thingummyjig" | |
# TODO: Add keyword parameters for configurable parameters here | |
def __init__(self, some_field="Thingummyjig"): | |
self.some_field = some_field | |
@property | |
def title(self): | |
"""This property is used to give the title of the portlet in the | |
"manage portlets" screen. | |
""" | |
return "Example Portlet" | |
class Renderer(base.Renderer): | |
"""Portlet renderer. | |
This is registered in configure.zcml. The referenced page template is | |
rendered, and the implicit variable 'view' will refer to an instance | |
of this class. Other methods can be added and referenced in the template. | |
""" | |
render = ViewPageTemplateFile('exampleportlet.pt') | |
@property | |
def title(self): | |
"""Portlet title""" | |
return "Important: %s" % self.data.some_field | |
class AddForm(z3cformhelper.AddForm): | |
"""Portlet add form. | |
This is registered in configure.zcml. [(?) The form_fields variable tells | |
z3c.form which fields to display.] The create() method actually | |
constructs the assignment that is being added. | |
""" | |
fields = field.Fields(IExamplePortlet) | |
def create(self, data): | |
return Assignment(**data) | |
# NOTE: If this portlet does not have any configurable parameters, you | |
# can use the next AddForm implementation instead of the previous. | |
# class AddForm(base.NullAddForm): | |
# """Portlet add form. | |
# """ | |
# def create(self): | |
# return Assignment() | |
# NOTE: If this portlet does not have any configurable parameters, you | |
# can remove the EditForm class definition and delete the editview | |
# attribute from the <plone:portlet /> registration in configure.zcml | |
class EditForm(z3cformhelper.EditForm): | |
"""Portlet edit form. | |
This is registered with configure.zcml. [(?) The form_fields variable tells | |
z3c.form which fields to display.] | |
""" | |
fields = field.Fields(IExamplePortlet) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<portlets | |
xmlns:i18n="http://xml.zope.org/namespaces/i18n" | |
i18n:domain="your.package"> | |
<portlet | |
addview="your.package.exampleportlet" | |
title="An example Portlet" | |
description="A portlet which ..." | |
i18n:attributes="title title_recent_portlet; | |
description description_recent_portlet"> | |
<for interface="plone.app.portlets.interfaces.IColumn" /> | |
<for interface="plone.app.portlets.interfaces.IDashboard" /> | |
</portlet> | |
</portlets> |
Note using plone.reload with portlets is known to produce the following kind of error, so we just have to be content to restart your Plone when editing portlets code.
...
Module Products.CMFPlone.browser.ploneview, line 309, in have_portlets
Module plone.app.layout.globals.layout, line 75, in have_portlets
Module plone.portlets.manager, line 48, in visible
Module plone.portlets.manager, line 67, in portletsToShow
Module plone.portlets.manager, line 70, in allPortlets
Module plone.memoize.view, line 47, in memogetter
Module plone.portlets.manager, line 108, in _lazyLoadPortlets
Module plone.app.portlets.manager, line 32, in _dataToPortlet
Module zope.component._api, line 109, in getMultiAdapter
ComponentLookupError: ((<ATDocument at /plone4/whats-on/sunday/homepage>, <HTTPRequest, URL=http://localhost:8080/plone4/whats-on/sunday/homepage/document_view>, <Products.Five.metaclass.Plone object at 0x82113d0>, <plone.portlets.manager.PortletManager object at 0x7274398>, <your.package.portlets.thisSundayPortlet.Assignment object at 0x7f2e9c3c1de8>), <InterfaceClass plone.portlets.interfaces.IPortletRenderer>, u'')
> /home/daniel/dev/Plone/Development/buildout-cache/eggs/zope.component-3.9.5-py2.7.egg/zope/component/_api.py(109)getMultiAdapter()
-> raise ComponentLookupError(objects, interface, name)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Portlets with z3c.form
Plone Portlets normally use zope.formlib, so this is a more modern approach
I got started on this by this StackOverflow question which gave some hints, but not a full solution, so I thought I'd outline one here, which I got by piecing together info from various places.
So portlets.xml goes in your profiles/default directory, and the other files can all go in a your/package/portlets directory. The only other change which is required is in your/package/configure.zcml.
I've tweaked the package & field names since having it working, so perhaps I've busted something in the process, so please let me know if it doesn't work out of the box.