Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into plip10886-event-imp…
Browse files Browse the repository at this point in the history
…rovements
  • Loading branch information
thet committed Jul 10, 2012
2 parents 4633f1f + 3f51db6 commit 436b22a
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 8 deletions.
21 changes: 17 additions & 4 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
Changelog
=========

2.3a2 (unreleased)
------------------

- portlets/login.py, portlets/navigation.py:
Don't use list as default parameter value.
[kleist]

2.3a1 (2012-06-29)
------------------

- Make it possible to create portlets using z3c.form.
[ggozad]

2.2.6 (unreleased)
------------------

- Remove hard dependency on Archetypes.
[davisagli]

- accessibility improvements for screen readers regarding "more" links, see https://dev.plone.org/ticket/11982
[rmattb, applied by polyester]
- accessibility improvements for screen readers regarding "more" links, see https://dev.plone.org/ticket/11982
[rmattb, applied by polyester]

2.2.5 (2012-05-07)
------------------
Expand All @@ -33,8 +46,8 @@ Changelog
- Do not display 'Manage portlets' when using portal_factory.
https://dev.plone.org/ticket/12376
[runyaga]
- Fixed the two high priority scenarios (global sections viewlet and nav

- Fixed the two high priority scenarios (global sections viewlet and nav
portlet) of http://dev.plone.org/ticket/11189.
[fulv]

Expand Down
97 changes: 97 additions & 0 deletions plone/app/portlets/browser/z3cformhelper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from z3c.form import button
from z3c.form import form
from zope.component import getMultiAdapter
from zope.interface import implements

from Acquisition import aq_parent, aq_inner

from plone.app.portlets import PloneMessageFactory as _
from plone.app.portlets.browser.interfaces import IPortletAddForm
from plone.app.portlets.browser.interfaces import IPortletEditForm
from plone.app.portlets.interfaces import IPortletPermissionChecker


class AddForm(form.AddForm):
implements(IPortletAddForm)

label = _(u"Configure portlet")

def add(self, object):
ob = self.context.add(object)
self._finishedAdd = True
return ob

def __call__(self):
IPortletPermissionChecker(aq_parent(aq_inner(self.context)))()
return super(AddForm, self).__call__()

def nextURL(self):
addview = aq_parent(aq_inner(self.context))
context = aq_parent(aq_inner(addview))
url = str(getMultiAdapter((context, self.request),
name=u"absolute_url"))
return url + '/@@manage-portlets'

@button.buttonAndHandler(_(u"label_save", default=u"Save"), name='add')
def handleAdd(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
obj = self.createAndAdd(data)
if obj is not None:
# mark only as finished if we get the new object
self._finishedAdd = True

@button.buttonAndHandler(_(u"label_cancel", default=u"Cancel"),
name='cancel_add')
def handleCancel(self, action):
nextURL = self.nextURL()
if nextURL:
self.request.response.redirect(nextURL)
return ''


class EditForm(form.EditForm):
"""An edit form for portlets.
"""

implements(IPortletEditForm)

label = _(u"Modify portlet")

def __call__(self):
IPortletPermissionChecker(aq_parent(aq_inner(self.context)))()
return super(EditForm, self).__call__()

def nextURL(self):
editview = aq_parent(aq_inner(self.context))
context = aq_parent(aq_inner(editview))
url = str(getMultiAdapter((context, self.request),
name=u"absolute_url"))
return url + '/@@manage-portlets'

@button.buttonAndHandler(_(u"label_save", default=u"Save"), name='apply')
def handleSave(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
changes = self.applyChanges(data)
if changes:
self.status = "Changes saved"
else:
self.status = "No changes"

nextURL = self.nextURL()
if nextURL:
self.request.response.redirect(self.nextURL())
return ''

@button.buttonAndHandler(_(u"label_cancel", default=u"Cancel"),
name='cancel_add')
def handleCancel(self, action):
nextURL = self.nextURL()
if nextURL:
self.request.response.redirect(nextURL)
return ''
4 changes: 3 additions & 1 deletion plone/app/portlets/portlets/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ def can_request_password(self):
return self.membership.checkPermission('Mail forgotten password', self.context)

@memoize
def auth(self, _marker=[]):
def auth(self, _marker=None):
if _marker is None:
_marker = []
acl_users = getToolByName(self.context, 'acl_users')
return getattr(acl_users, 'credentials_cookie_auth', None)

Expand Down
8 changes: 6 additions & 2 deletions plone/app/portlets/portlets/navigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ def getNavRootPath(self):
return getRootPath(self.context, currentFolderOnly, topLevel, self.data.root)

@memoize
def getNavRoot(self, _marker=[]):
def getNavRoot(self, _marker=None):
if _marker is None:
_marker = []
portal = self.urltool.getPortalObject()
rootPath = self.getNavRootPath()
if rootPath is None:
Expand All @@ -196,7 +198,9 @@ def getNavRoot(self, _marker=[]):
return portal

@memoize
def getNavTree(self, _marker=[]):
def getNavTree(self, _marker=None):
if _marker is None:
_marker = []
context = aq_inner(self.context)
queryBuilder = getMultiAdapter((context, self.data), INavigationQueryBuilder)
strategy = getMultiAdapter((context, self.data), INavtreeStrategy)
Expand Down
15 changes: 15 additions & 0 deletions plone/app/portlets/tests/profiles/z3ctesting/portlets.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<portlets
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
i18n:domain="plone">


<portlet
addview="portlet.z3cTest"
title="Test portlet"
description="A test portlet"
i18n:attributes="title title_test_portlet;
description description_test_portlet"
/>

</portlets>
158 changes: 158 additions & 0 deletions plone/app/portlets/tests/test_z3cforms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import time
from z3c.form import field
from zope import schema
from zope.component import getUtility, getMultiAdapter, queryMultiAdapter
from zope.interface import implements
from zope.site.hooks import setHooks, setSite

from Products.PloneTestCase.layer import PloneSite

from plone.portlets.interfaces import IPortletType
from plone.portlets.interfaces import IPortletManager
from plone.portlets.interfaces import IPortletAssignment
from plone.portlets.interfaces import IPortletDataProvider
from plone.portlets.interfaces import IPortletRenderer
from plone.app.portlets.portlets import base
from plone.app.portlets.browser import z3cformhelper
from plone.app.portlets.storage import PortletAssignmentMapping
from plone.app.portlets.tests.base import PortletsTestCase
# BBB Zope 2.12
try:
from Zope2.App import zcml
from OFS import metaconfigure
zcml # pyflakes
metaconfigure
except ImportError:
from Products.Five import zcml
from Products.Five import fiveconfigure as metaconfigure


class Iz3cPortlet(IPortletDataProvider):
"""A dummy z3c portlet.
"""

foo = schema.Text(title=u"Foo")


class Assignment(base.Assignment):

implements(Iz3cPortlet)

def __init__(self, foo=u''):
self.foo = foo


class Renderer(base.Renderer):

def render(self, context, request):
return self.data.foo


class AddForm(z3cformhelper.AddForm):

fields = field.Fields(Iz3cPortlet)

def create(self, data):
return Assignment(**data)


class EditForm(z3cformhelper.EditForm):

fields = field.Fields(Iz3cPortlet)


zcml_string = """\
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:plone="http://namespaces.plone.org/plone"
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
package="plone.app.portlets"
i18n_domain="test">
<plone:portlet
name="portlet.z3cTest"
interface="plone.app.portlets.tests.test_z3cforms.Iz3cPortlet"
assignment="plone.app.portlets.tests.test_z3cforms.Assignment"
renderer="plone.app.portlets.tests.test_z3cforms.Renderer"
addview="plone.app.portlets.tests.test_z3cforms.AddForm"
editview="plone.app.portlets.tests.test_z3cforms.EditForm"
/>
<genericsetup:registerProfile
name="z3ctesting"
title="plone.app.portlets z3c testing"
description="Used for testing only"
directory="tests/profiles/z3ctesting"
for="Products.CMFCore.interfaces.ISiteRoot"
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
</configure>
"""


class z3cPortletZCMLLayer(PloneSite):

@classmethod
def setUp(cls):
metaconfigure.debug_mode = True
zcml.load_string(zcml_string)
metaconfigure.debug_mode = False

@classmethod
def tearDown(cls):
pass


class TestPortlet(PortletsTestCase):

layer = z3cPortletZCMLLayer

def afterSetUp(self):
setHooks()
setSite(self.portal)
self.setRoles(('Manager', ))
portal_setup = self.portal.portal_setup
# wait a bit or we get duplicate ids on import
time.sleep(0.2)
portal_setup.runAllImportStepsFromProfile('profile-plone.app.portlets:z3ctesting')

def testInterfaces(self):
portlet = Assignment()
self.failUnless(IPortletAssignment.providedBy(portlet))
self.failUnless(IPortletDataProvider.providedBy(portlet.data))

def testInvokeAddview(self):
portlet = getUtility(IPortletType, name='portlet.z3cTest')
mapping = self.portal.restrictedTraverse('++contextportlets++plone.leftcolumn')
for m in mapping.keys():
del mapping[m]

addview = mapping.restrictedTraverse('+/' + portlet.addview)
addview.createAndAdd(data={'foo': 'bar'})

self.assertEquals(len(mapping), 1)
self.failUnless(isinstance(mapping.values()[0], Assignment))

def testInvokeEditView(self):
mapping = PortletAssignmentMapping()
request = self.folder.REQUEST
mapping['foo'] = Assignment(foo='bar')
editview = queryMultiAdapter((mapping['foo'], request), name='edit', default=None)
self.assertTrue(editview is not None)

def testRenderer(self):
context = self.folder
request = self.folder.REQUEST
view = self.folder.restrictedTraverse('@@plone')
manager = getUtility(IPortletManager, name='plone.leftcolumn', context=self.portal)
assignment = Assignment(foo='bar')
renderer = getMultiAdapter((context, request, view, manager, assignment), IPortletRenderer)
self.failUnless(isinstance(renderer, Renderer))
self.assertEqual(renderer.render(context, request), 'bar')


def test_suite():
from unittest import TestSuite, makeSuite
suite = TestSuite()
suite.addTest(makeSuite(TestPortlet))
return suite
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages

version = '2.2.6.dev0'
version = '2.3a2.dev0'

setup(name='plone.app.portlets',
version=version,
Expand Down

0 comments on commit 436b22a

Please sign in to comment.