Skip to content

Commit

Permalink
Issue 89 - Remove hard dependency on five.grok (#108)
Browse files Browse the repository at this point in the history
* Remove Grok markup

* Add ZCMl registration for views, utility, subscribers. Add/Edit form for Polls

* Fix template path, bad copy/past

* Fix path for PollPortetRender. Rename IPoll/Poll to IPollUtility, the content model already uses IPoll. Fix implements for utility

* Flake8

* Remove dependency on plone.directives.dexterity

* BrowserViews do not use update method, call it

* Improve tile logic. Poll can be None, meaning none is inserted or no closed one can be found

* Refactor

* Do not rename the poll utility

* Add entry on changelog
  • Loading branch information
rodfersou authored and hvelarde committed Apr 5, 2017
1 parent 4d0b95f commit 85655ee
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 50 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Expand Up @@ -6,6 +6,9 @@ There's a frood who really knows where his towel is.
1.9b2 (unreleased)
^^^^^^^^^^^^^^^^^^

- Remove hard dependency on five.grok.
[rodfersou, puittenbroek, hvelarde]

- Remove soft dependency on zope.formlib under Plone 5 (HT @ale-rt).
[hvelarde]

Expand Down
2 changes: 1 addition & 1 deletion buildout.cfg
Expand Up @@ -24,7 +24,7 @@ multiprocessing = True
pre-commit-hook = True
return-status-codes = True
flake8 = True
flake8-ignore = E501,D001,P001,T000
flake8-ignore = E501,P001,T000

[i18ndude]
recipe = zc.recipe.egg
Expand Down
9 changes: 5 additions & 4 deletions setup.py
Expand Up @@ -43,17 +43,18 @@
include_package_data=True,
zip_safe=False,
install_requires=[
'Acquisition',
'AccessControl',
'Acquisition',
'collective.z3cform.widgets >=1.0b3',
'five.grok',
'plone.api',
'plone.app.content',
'plone.app.dexterity [grok, relations]',
'plone.app.dexterity [relations]',
'plone.app.portlets',
'plone.directives.dexterity',
'plone.autoform',
'plone.dexterity',
'plone.memoize',
'plone.portlets',
'plone.supermodel',
'plone.uuid',
'Products.CMFCore',
'Products.CMFPlone >=4.2',
Expand Down
37 changes: 37 additions & 0 deletions src/collective/polls/browser/configure.zcml
Expand Up @@ -2,6 +2,36 @@
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">

<browser:page
name="view"
for="collective.polls.content.poll.IPoll"
class="..content.poll.View"
permission="zope2.View"
/>

<browser:page
name="edit"
for="collective.polls.content.poll.IPoll"
class="..content.poll.PollEditForm"
permission="cmf.ModifyPortalContent"
/>

<adapter
name="collective.polls.poll"
for="Products.CMFCore.interfaces.IFolderish
zope.publisher.interfaces.browser.IDefaultBrowserLayer
plone.dexterity.interfaces.IDexterityFTI"
provides="zope.publisher.interfaces.browser.IBrowserPage"
factory="..content.poll.PollAddView"
/>

<class class="..content.poll.PollAddView">
<require
permission="cmf.AddPortalContent"
interface="zope.publisher.interfaces.browser.IBrowserPage"
/>
</class>

<browser:page
name="poll-macros"
template="templates/poll_macros.pt"
Expand All @@ -17,4 +47,11 @@
permission="zope2.View"
/>

<browser:page
name="poll_portlet_render"
for="*"
class="..polls.PollPortletRender"
permission="zope2.View"
/>

</configure>
23 changes: 18 additions & 5 deletions src/collective/polls/configure.zcml
Expand Up @@ -3,7 +3,6 @@
xmlns:five="http://namespaces.zope.org/five"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:i18n="http://namespaces.zope.org/i18n"
xmlns:grok="http://namespaces.zope.org/grok"
xmlns:plone="http://namespaces.plone.org/plone"
xmlns:zcml="http://namespaces.zope.org/zcml"
i18n_domain="collective.polls">
Expand All @@ -27,10 +26,6 @@
title="collective.polls: Vote"
/>

<grok:grok package=".content" />
<grok:grok package=".polls" />
<grok:grok package=".subscribers" />

<browser:resourceDirectory
name="collective.polls"
directory="static"
Expand All @@ -43,4 +38,22 @@

<include package=".tiles" zcml:condition="installed collective.cover" />

<subscriber
for="collective.polls.content.poll.IPoll
Products.CMFCore.interfaces.IActionSucceededEvent"
handler=".subscribers.fix_permissions"
/>

<subscriber
for="collective.polls.content.poll.IPoll
Products.CMFCore.interfaces.IActionSucceededEvent"
handler=".subscribers.remove_votes"
/>

<utility
name="collective.polls"
provides="collective.polls.polls.IPolls"
factory="collective.polls.polls.Polls"
/>

</configure>
49 changes: 31 additions & 18 deletions src/collective/polls/content/poll.py
Expand Up @@ -10,15 +10,21 @@
from collective.polls.config import VOTE_ANNO_KEY
from collective.polls.polls import IPolls
from collective.z3cform.widgets.enhancedtextlines import EnhancedTextLinesFieldWidget
from five import grok
from plone import api
from plone.directives import dexterity
from plone.directives import form
from plone.autoform import directives as form
from plone.dexterity.browser.add import DefaultAddForm
from plone.dexterity.browser.add import DefaultAddView
from plone.dexterity.browser.edit import DefaultEditForm
from plone.dexterity.content import Item
from plone.supermodel import model
from Products.CMFCore.interfaces import ISiteRoot
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope import schema
from zope.annotation.interfaces import IAnnotations
from zope.component import getMultiAdapter
from zope.component import queryUtility
from zope.interface import implementer
from zope.interface import Invalid
from zope.interface import invariant
from zope.schema.vocabulary import SimpleTerm
Expand All @@ -35,7 +41,8 @@ class InsuficientOptions(Invalid):
__doc__ = _(u'Not enought options provided')


class IPoll(form.Schema):
# TODO: move to interfaces module
class IPoll(model.Schema):

"""A Poll in a Plone site."""

Expand Down Expand Up @@ -86,12 +93,11 @@ def validate_options(data):
_(u'You need to provide at least two options for a poll.'))


class Poll(dexterity.Item):
@implementer(IPoll)
class Poll(Item):

"""A Poll in a Plone site."""

grok.implements(IPoll)

__ac_permissions__ = (
(PERMISSION_VOTE, ('setVote', '_setVoter', )),
)
Expand Down Expand Up @@ -208,11 +214,11 @@ def setVote(self, options=[], request=None):
return True


class PollAddForm(dexterity.AddForm):

# TODO: move to browser module
class PollAddForm(DefaultAddForm):
"""Form to handle creation of new Polls."""

grok.name('collective.polls.poll')
portal_type = 'collective.polls.poll'

def create(self, data):
options = data['options']
Expand All @@ -226,11 +232,14 @@ def create(self, data):
return super(PollAddForm, self).create(data)


class PollEditForm(dexterity.EditForm):
# TODO: move to browser module
class PollAddView(DefaultAddView):
form = PollAddForm

"""Form to handle edition of existing polls."""

grok.context(IPoll)
# TODO: move to browser module
class PollEditForm(DefaultEditForm):
"""Form to handle edition of existing polls."""

def updateWidgets(self):
"""Update form widgets to hide column option_id from end user."""
Expand Down Expand Up @@ -260,15 +269,19 @@ def applyChanges(self, data):
super(PollEditForm, self).applyChanges(data)


class View(PollsViewMixin, grok.View):
# TODO: move to browser module
class View(PollsViewMixin, BrowserView):

index = ViewPageTemplateFile('templates/view.pt')

grok.context(IPoll)
grok.require('zope2.View')
def render(self):
return self.index()

grok.name('view')
def __call__(self):
self.update()
return self.render()

def update(self):
super(View, self).update()
context = aq_inner(self.context)
self.context = context
self.state = getMultiAdapter(
Expand Down
19 changes: 7 additions & 12 deletions src/collective/polls/polls.py
@@ -1,15 +1,16 @@
# -*- coding: utf-8 -*-
from AccessControl import Unauthorized
from collective.polls.config import COOKIE_KEY
from five import grok
from plone import api
from plone.portlets.interfaces import IPortletManager
from plone.portlets.interfaces import IPortletRenderer
from plone.portlets.interfaces import IPortletRetriever
from Products.Five.browser import BrowserView
from zope.component import ComponentLookupError
from zope.component import getMultiAdapter
from zope.component import getUtility
from zope.component import queryMultiAdapter
from zope.interface import implementer
from zope.interface import Interface

import random
Expand All @@ -18,7 +19,7 @@

class IPolls(Interface):

"""A poll."""
"""Interface for poll utility."""

def recent_polls(show_all=False, limit=5, kw={}):
"""Return recent polls."""
Expand All @@ -45,14 +46,11 @@ def anonymous_vote_id(poll_uid):
"""Return a identifier for vote_id."""


class Polls(grok.GlobalUtility):
@implementer(IPolls)
class Polls(object):

"""Utility methods for dealing with polls."""

grok.implements(IPolls)
grok.provides(IPolls)
grok.name('collective.polls')

@property
def ct(self):
return api.portal.get_tool(name='portal_catalog')
Expand Down Expand Up @@ -143,14 +141,11 @@ def anonymous_vote_id(self):
return vote_id


class PollPortletRender(grok.View):
# TODO: move to browser module
class PollPortletRender(BrowserView):

"""This methods allow to use the portlet render in a view."""

grok.context(Interface)
grok.name('poll_portlet_render')
grok.require('zope2.View')

def get_portlet_manager(self, column=''):
"""Return one of default Plone portlet managers.
Expand Down
5 changes: 0 additions & 5 deletions src/collective/polls/subscribers.py
Expand Up @@ -3,17 +3,13 @@
from collective.polls.config import MEMBERS_ANNO_KEY
from collective.polls.config import PERMISSION_VOTE
from collective.polls.config import VOTE_ANNO_KEY
from collective.polls.content.poll import IPoll
from five import grok
from Products.CMFCore.interfaces import IActionSucceededEvent
from Products.CMFCore.interfaces import ISiteRoot


ALL_ROLES = ['Anonymous', 'Contributor', 'Editor', 'Manager', 'Member',
'Reader', 'Reviewer', 'Site Administrator']


@grok.subscribe(IPoll, IActionSucceededEvent)
def fix_permissions(poll, event):
"""Fix permission on poll object if allow_anonymous is enabled."""
if event.action in ['open', ]:
Expand All @@ -31,7 +27,6 @@ def fix_permissions(poll, event):
acquire=0)


@grok.subscribe(IPoll, IActionSucceededEvent)
def remove_votes(poll, event):
"""Remove existing votes on poll object if reject transaction happens."""
if event.action in ['reject', ]:
Expand Down
8 changes: 7 additions & 1 deletion src/collective/polls/tiles/poll.pt
Expand Up @@ -3,9 +3,15 @@
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
i18n:domain="collective.polls">
<body>

<body tal:define="is_empty view/is_empty">
<p tal:condition="python: is_empty and view.is_compose_mode()" i18n:translate="" >
Drag&amp;drop a poll here to populate the tile.
</p>

<div class="poll poll-tile vote-container"
tal:define="poll view/poll"
tal:condition="not: is_empty"
tal:attributes="data-poll-uid view/poll_uid;
data-poll-closed view/is_closed;
data-poll-totalvotes view/total_votes;
Expand Down
13 changes: 9 additions & 4 deletions src/collective/polls/tiles/poll.py
Expand Up @@ -4,9 +4,11 @@
from collective.polls import MessageFactory as _
from collective.polls.browser import PollsViewMixin
from plone.app.uuid.utils import uuidToObject
from plone.memoize import view
from plone.tiles.interfaces import ITileDataManager
from plone.uuid.interfaces import IUUID
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.interface import implementer
from zope.schema import TextLine


Expand All @@ -20,6 +22,7 @@ class IPollTile(IPersistentCoverTile):
)


@implementer(IPollTile)
class PollTile(PollsViewMixin, PersistentCoverTile):

"""A tile that shows a poll."""
Expand All @@ -34,7 +37,9 @@ def results(self):
obj = uuidToObject(uuid)
return obj

@view.memoize
def poll(self):
"""Get the inserted poll or a closed one."""
utility = self.utility
uid = uuid = self.data.get('uuid', None)
poll = None
Expand All @@ -48,6 +53,10 @@ def poll(self):
poll = results and results[0].getObject() or None
return poll

def is_empty(self):
"""If there is no poll, or none can be found, tile is empty."""
return self.poll() is None

def populate_with_object(self, obj):
super(PollTile, self).populate_with_object(obj)
uuid = IUUID(obj, None)
Expand All @@ -60,7 +69,3 @@ def delete(self):

def accepted_ct(self):
return ['collective.polls.poll']

def has_data(self):
uuid = self.data.get('uuid', None)
return uuid is not None

0 comments on commit 85655ee

Please sign in to comment.