From 71f1cb658ecacc159f47396e3e0a15b8d949b572 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Thu, 14 Apr 2016 16:49:00 +0200 Subject: [PATCH 1/4] housekeeping: cleanup, less files, simplify viewlet proxy code --- CHANGES.rst | 10 + plone/__init__.py | 7 +- plone/app/__init__.py | 7 +- plone/app/standardtiles/attachment.py | 14 +- plone/app/standardtiles/common.py | 326 +++++------------- plone/app/standardtiles/content.zcml | 4 +- plone/app/standardtiles/contentlisting.py | 22 +- plone/app/standardtiles/embed.py | 1 + plone/app/standardtiles/existingcontent.py | 16 +- plone/app/standardtiles/field.py | 35 +- plone/app/standardtiles/head.py | 226 +++--------- plone/app/standardtiles/image.py | 28 +- plone/app/standardtiles/keywords.py | 31 +- plone/app/standardtiles/metadata.py | 5 +- plone/app/standardtiles/navigation.py | 152 ++++---- plone/app/standardtiles/portlets/__init__.py | 1 + plone/app/standardtiles/portlets/add.py | 14 +- .../app/standardtiles/portlets/assignment.py | 3 +- plone/app/standardtiles/portlets/delete.py | 2 - plone/app/standardtiles/portlets/edit.py | 26 +- .../standardtiles/portlets/portletmanager.py | 2 +- plone/app/standardtiles/portlets/utils.py | 3 +- .../standardtiles/portlets/vocabularies.py | 10 +- plone/app/standardtiles/raw.py | 8 +- plone/app/standardtiles/rss.py | 6 +- plone/app/standardtiles/sitemap.py | 7 +- plone/app/standardtiles/tableofcontents.py | 31 +- plone/app/standardtiles/testing.py | 55 ++- plone/app/standardtiles/tests/test_content.py | 77 ++--- plone/app/standardtiles/tests/test_head.py | 18 +- plone/app/standardtiles/tests/test_layout.py | 166 ++++----- plone/app/standardtiles/tests/test_media.py | 55 ++- plone/app/standardtiles/upgrades.py | 4 +- plone/app/standardtiles/utils.py | 6 +- plone/app/standardtiles/viewletmanager.py | 9 +- 35 files changed, 471 insertions(+), 916 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f397a0d2..a94e09ed 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,8 +4,18 @@ Changelog 2.0.0 (unreleased) ------------------ +- Housekeeping and minor cleanup. + [jensens] + +- Moved KeywordTile and TableOfContentsTile to common.py. + [jensens] + +- Simplify basic viewlet proxy tiles. + [jensens] + - Removed support for Plone 4.3. For Plone 4.3 support, please use plone.app.standardtiles < 2.0. + [datakurre, jensens] 1.0 (2016-04-11) diff --git a/plone/__init__.py b/plone/__init__.py index 85880ef0..68c04af4 100644 --- a/plone/__init__.py +++ b/plone/__init__.py @@ -1,7 +1,2 @@ # -*- coding: utf-8 -*- -# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages -try: - __import__('pkg_resources').declare_namespace(__name__) -except ImportError: - from pkgutil import extend_path - __path__ = extend_path(__path__, __name__) +__import__('pkg_resources').declare_namespace(__name__) diff --git a/plone/app/__init__.py b/plone/app/__init__.py index 85880ef0..68c04af4 100644 --- a/plone/app/__init__.py +++ b/plone/app/__init__.py @@ -1,7 +1,2 @@ # -*- coding: utf-8 -*- -# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages -try: - __import__('pkg_resources').declare_namespace(__name__) -except ImportError: - from pkgutil import extend_path - __path__ = extend_path(__path__, __name__) +__import__('pkg_resources').declare_namespace(__name__) diff --git a/plone/app/standardtiles/attachment.py b/plone/app/standardtiles/attachment.py index 4287a8b1..f44b5f30 100644 --- a/plone/app/standardtiles/attachment.py +++ b/plone/app/standardtiles/attachment.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from Products.CMFCore.utils import getToolByName -from Products.MimetypesRegistry.common import MimeTypeException from plone.app.standardtiles import PloneMessageFactory as _ from plone.autoform.directives import widget from plone.formwidget.multifile.widget import MultiFileFieldWidget @@ -10,8 +8,10 @@ from plone.namedfile.utils import stream_data from plone.supermodel.model import Schema from plone.tiles import PersistentTile +from Products.CMFCore.utils import getToolByName +from Products.MimetypesRegistry.common import MimeTypeException from zope import schema -from zope.interface import implements +from zope.interface import implementer from zope.publisher.interfaces import IPublishTraverse from zope.publisher.interfaces import NotFound @@ -21,7 +21,11 @@ class IAttachmentTile(Schema): widget(files=MultiFileFieldWidget) files = schema.List( title=_(u'Upload files'), - value_type=NamedBlobFile(title=_(u"Please upload a file"), required=True)) + value_type=NamedBlobFile( + title=_(u"Please upload a file"), + required=True + ) + ) class AttachmentTile(PersistentTile): @@ -87,13 +91,13 @@ def lookupMime(self, name): return name +@implementer(IPublishTraverse) class AttachmentTileDownload(object): """Implementation of the @@download view on the attachment tile. This is a view onto the AttachmentTile tile view. """ - implements(IPublishTraverse) index = None def publishTraverse(self, request, name): diff --git a/plone/app/standardtiles/common.py b/plone/app/standardtiles/common.py index d5d047de..6fdaa9bc 100644 --- a/plone/app/standardtiles/common.py +++ b/plone/app/standardtiles/common.py @@ -16,104 +16,57 @@ from zope.viewlet.interfaces import IViewletManager -class FooterTile(Tile): - """A footer tile.""" +class BaseViewletTile(Tile): + + manager = None + viewlet = None def __call__(self): alsoProvides(self, IViewView) manager = queryMultiAdapter( (self.context, self.request, self), - IViewletManager, name='plone.portalfooter' + IViewletManager, + name=self.manager ) viewlet = queryMultiAdapter( (self.context, self.request, self, manager), - IViewlet, name='plone.footer' + IViewlet, + name=self.viewlet ) if viewlet is not None: viewlet.update() return u'%s' % viewlet.render() - else: - return u'' + return u'' -class ColophonTile(Tile): - """A colophon tile.""" +class FooterTile(BaseViewletTile): + """A footer tile.""" + manager = 'plone.portalfooter' + viewlet = 'plone.footer' - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.portalfooter' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.colophon' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +class ColophonTile(BaseViewletTile): + """A colophon tile.""" + manager = 'plone.portalfooter' + viewlet = 'plone.colophon' -class SiteActionsTile(Tile): - """A site actions tile.""" - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.portalfooter' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.site_actions' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +class SiteActionsTile(BaseViewletTile): + """A site actions tile.""" + manager = 'plone.portalfooter' + viewlet = 'plone.site_actions' -class AnalyticsTile(Tile): +class AnalyticsTile(BaseViewletTile): """A analytics tile.""" + manager = 'plone.portalfooter' + viewlet = 'plone.analytics' - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.portalfooter' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.analytics' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - -class SkipLinksTile(Tile): +class SkipLinksTile(BaseViewletTile): """A skip links tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.portalheader' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.skip_links' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' + manager = 'plone.portalheader' + viewlet = 'plone.skip_links' class LoginTile(Tile): @@ -196,124 +149,40 @@ def update(self): pass -class PersonalBarTile(Tile): +class PersonalBarTile(BaseViewletTile): """A personal bar tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.toolbar' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.personal_bar' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' + manager = 'plone.portalheader' + viewlet = 'plone.personal_bar' -class SearchBoxTile(Tile): +class SearchBoxTile(BaseViewletTile): """A search box tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.portalheader' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.searchbox' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' + manager = 'plone.portalheader' + viewlet = 'plone.searchbox' -class AnonToolsTile(Tile): +class AnonToolsTile(BaseViewletTile): """An anon tools tile.""" + manager = 'plone.portalheader' + viewlet = 'plone.anontools' - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.portalheader' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.anontools' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - -class LogoTile(Tile): +class LogoTile(BaseViewletTile): """A logo tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.portalheader' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.logo' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' + manager = 'plone.portalheader' + viewlet = 'plone.logo' -class GlobalSectionsTile(Tile): +class GlobalSectionsTile(BaseViewletTile): """A global sections tile.""" + manager = 'plone.mainnavigation' + viewlet = 'plone.global_sections' - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.mainnavigation' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.global_sections' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - -class PathBarTile(Tile): +class PathBarTile(BaseViewletTile): """A path bar tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.abovecontent' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.path_bar' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' + manager = 'plone.abovecontent' + viewlet = 'plone.path_bar' class ToolbarTile(Tile): @@ -330,24 +199,10 @@ def __call__(self): return u'%s' % toolbar() -class GlobalStatusMessageTile(Tile): +class GlobalStatusMessageTile(BaseViewletTile): """Display messages to the current user""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.globalstatusmessage' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.globalstatusmessage' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' + manager = 'plone.globalstatusmessage' + viewlet = 'plone.globalstatusmessage' class DocumentBylineTile(Tile): @@ -372,7 +227,10 @@ def show(self): return not self.anonymous or allowAnonymousViewAbout def show_history(self): - if not _checkPermission('CMFEditions: Access previous versions', self.context): + if not _checkPermission( + 'CMFEditions: Access previous versions', + self.context + ): return False if IViewView.providedBy(self.__parent__): return True @@ -392,7 +250,8 @@ def locked_icon(self): locked = lock_info.is_locked() else: context = aq_inner(self.context) - lockable = getattr(context.aq_explicit, 'wl_isLocked', None) is not None + is_locked = getattr(context.aq_explicit, 'wl_isLocked', None) + lockable = is_locked is not None locked = lockable and context.wl_isLocked() if not locked: @@ -418,7 +277,7 @@ def isExpired(self): return self.context.expires().isPast() return False - def toLocalizedTime(self, time, long_format=None, time_only = None): + def toLocalizedTime(self, time, long_format=None, time_only=None): """Convert time to localized time """ util = getToolByName(self.context, 'translation_service') @@ -446,24 +305,10 @@ def pub_date(self): return DateTime(date) -class LockInfoTile(Tile): +class LockInfoTile(BaseViewletTile): """A lockinfo tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.abovecontent' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.lockinfo' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' + manager = 'plone.abovecontent' + viewlet = 'plone.lockinfo' class NextPreviousTile(Tile): @@ -504,44 +349,28 @@ def __call__(self): return u'' -class DocumentActionsTile(Tile): - """Shows the document actions.""" +class KeywordsTile(BaseViewletTile): + """A tile that displays the context's keywords, if any.""" + manager = 'plone.belowcontent' + viewlet = 'plone.belowcontenttitle.keywords' - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.belowcontentbody' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.abovecontenttitle.documentactions' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +class TableOfContentsTile(BaseViewletTile): + """A Table of contents tile.""" + manager = 'plone.abovecontentbody' + viewlet = 'plone.tableofcontents' -class RelatedItemsTile(Tile): - """A related items tile.""" - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.belowcontentbody' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.belowcontentbody.relateditems' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +class DocumentActionsTile(BaseViewletTile): + """Shows the document actions.""" + manager = 'plone.belowcontentbody' + viewlet = 'plone.abovecontenttitle.documentactions' + + +class RelatedItemsTile(BaseViewletTile): + """A related items tile.""" + manager = 'plone.belowcontentbody' + viewlet = 'plone.belowcontentbody.relateditems' class HistoryTile(Tile): @@ -576,5 +405,4 @@ def __call__(self): if viewlet is not None: viewlet.update() return u'%s' % viewlet.render() - else: - return u'' + return u'' diff --git a/plone/app/standardtiles/content.zcml b/plone/app/standardtiles/content.zcml index 1bf91197..1e86fd56 100644 --- a/plone/app/standardtiles/content.zcml +++ b/plone/app/standardtiles/content.zcml @@ -22,7 +22,7 @@ title="Table of contents" description="A tile which display a Table of contents" add_permission="cmf.ModifyPortalContent" - class="plone.app.standardtiles.tableofcontents.TableOfContentsTile" + class=".common.TableOfContentsTile" permission="zope.Public" /> @@ -31,7 +31,7 @@ title="Context keywords" description='A tile which displays the keywords of this item' add_permission="cmf.ModifyPortalContent" - class=".keywords.KeywordsTile" + class=".common.KeywordsTile" for="*" permission="zope2.View" /> diff --git a/plone/app/standardtiles/contentlisting.py b/plone/app/standardtiles/contentlisting.py index 4a671610..fc31ffd0 100644 --- a/plone/app/standardtiles/contentlisting.py +++ b/plone/app/standardtiles/contentlisting.py @@ -1,36 +1,24 @@ # -*- coding: utf-8 -*- -from plone.registry.interfaces import IRegistry -from zope.component import getUtility -from Products.CMFCore.interfaces import IFolderish from plone.app.standardtiles import PloneMessageFactory as _ +from plone.app.z3cform.widget import QueryStringFieldWidget from plone.autoform.directives import widget +from plone.registry.interfaces import IRegistry from plone.supermodel.model import Schema from plone.tiles import Tile +from Products.CMFCore.interfaces import IFolderish from z3c.form.interfaces import IValue from z3c.form.util import getSpecification from zope import schema from zope.component import adapter from zope.component import getMultiAdapter -from zope.interface import Interface +from zope.component import getUtility from zope.interface import alsoProvides from zope.interface import directlyProvides from zope.interface import implementer +from zope.interface import Interface from zope.schema.interfaces import IVocabularyFactory from zope.schema.vocabulary import SimpleVocabulary -try: - from plone.app.z3cform.widget import QueryStringFieldWidget -except ImportError: - try: - from plone.app.widgets.dx import QueryStringFieldWidget - except ImportError: - from z3c.form.interfaces import IFieldWidget - from z3c.form.widget import FieldWidget - from plone.app.widgets.dx import QueryStringWidget - @implementer(IFieldWidget) - def QueryStringFieldWidget(field, request): - return FieldWidget(field, QueryStringWidget(request)) - class IContentListingTile(Schema): """A tile that displays a listing of content items""" diff --git a/plone/app/standardtiles/embed.py b/plone/app/standardtiles/embed.py index d97ab9e0..88ec261c 100644 --- a/plone/app/standardtiles/embed.py +++ b/plone/app/standardtiles/embed.py @@ -4,6 +4,7 @@ from plone.supermodel.model import Schema from plone.tiles import Tile from zope import schema + import requests NOEMBED_ENDPOINT = 'https://noembed.com/embed?callback=embed_data=&url=' diff --git a/plone/app/standardtiles/existingcontent.py b/plone/app/standardtiles/existingcontent.py index fab55bee..7e30fd47 100644 --- a/plone/app/standardtiles/existingcontent.py +++ b/plone/app/standardtiles/existingcontent.py @@ -39,10 +39,7 @@ def content_context(self): item = uuidToObject(uuid) if item is not None: return item - else: - return None - else: - return None + return None @property @memoize @@ -52,8 +49,7 @@ def default_view(self): item_layout = context.getLayout() default_view = context.restrictedTraverse(item_layout) return default_view - else: - return None + return None @property def item_macros(self): @@ -62,13 +58,10 @@ def item_macros(self): # IBrowserView if getattr(default_view, 'index', None): return default_view.index.macros - else: - return None elif default_view: # FSPageTemplate return default_view.macros - else: - return None + return None @property def item_panels(self): @@ -93,5 +86,4 @@ def item_panels(self): return [''.join([serializer.serializer(child) for child in node.getchildren()]) for name, node in panels.items()] + [clear] - else: - return [] + return [] diff --git a/plone/app/standardtiles/field.py b/plone/app/standardtiles/field.py index 0783dc96..3c49b4c1 100644 --- a/plone/app/standardtiles/field.py +++ b/plone/app/standardtiles/field.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- - -from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from plone.app.dexterity.behaviors.metadata import IDublinCore from plone.app.standardtiles.utils import PermissionChecker from plone.app.tiles.interfaces import ITilesFormLayer @@ -9,8 +7,10 @@ from plone.dexterity.interfaces import IDexterityFTI from plone.dexterity.utils import getAdditionalSchemata from plone.formwidget.namedfile import NamedImageWidget +from plone.protect.interfaces import IDisableCSRFProtection from plone.supermodel.utils import mergedTaggedValueDict from plone.tiles import Tile +from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from z3c.form.browser.text import TextWidget from z3c.form.browser.textarea import TextAreaWidget from z3c.form.field import Fields @@ -22,11 +22,6 @@ from zope.interface import alsoProvides from zope.interface import implementer from zope.pagetemplate.interfaces import IPageTemplate -try: - from plone.protect.interfaces import IDisableCSRFProtection - HAS_PLONE_PROTECT = True -except ImportError: - HAS_PLONE_PROTECT = False @implementer(IAddForm) @@ -49,6 +44,7 @@ def additionalSchemata(self): return getAdditionalSchemata(context=self.context) def __init__(self, context, request): + # xxx usually a super is the way to go here? why not? Tile.__init__(self, context, request) WidgetsView.__init__(self, context, request) @@ -91,7 +87,7 @@ def isVisible(self): ).allowed(self.field) def _wrap_widget(self, render): - return u"%s" % render + return ''.join([u'', render, '']) def updateWidgets(self, prefix=None): if self.field is not None: @@ -124,8 +120,18 @@ def __call__(self): return u'' -_titleDisplayTemplate = ViewPageTemplateFile('templates/title.pt', - content_type='text/html') +_titleDisplayTemplate = ViewPageTemplateFile( + 'templates/title.pt', + content_type='text/html' +) +_descriptionDisplayTemplate = ViewPageTemplateFile( + 'templates/description.pt', + content_type='text/html' +) +_namedImageDisplayTemplate = ViewPageTemplateFile( + 'templates/namedimage.pt', + content_type='text/html') + @implementer(IPageTemplate) @adapter(None, ITilesFormLayer, DexterityFieldTile, @@ -134,9 +140,6 @@ def titleDisplayTemplate(context, request, form, field, widget): return _titleDisplayTemplate -_descriptionDisplayTemplate = ViewPageTemplateFile('templates/description.pt', - content_type='text/html') - @implementer(IPageTemplate) @adapter(None, ITilesFormLayer, DexterityFieldTile, getSpecification(IDublinCore['description']), TextAreaWidget) @@ -144,14 +147,10 @@ def descriptionDisplayTemplate(context, request, form, field, widget): return _descriptionDisplayTemplate -_namedImageDisplayTemplate= ViewPageTemplateFile('templates/namedimage.pt', - content_type='text/html') - @implementer(IPageTemplate) @adapter(None, ITilesFormLayer, DexterityFieldTile, None, NamedImageWidget) def namedImageDisplayTemplate(context, request, form, field, widget): # Disable CSRF, because imagescales may save a new scale into ZODB - if HAS_PLONE_PROTECT: - alsoProvides(request, IDisableCSRFProtection) + alsoProvides(request, IDisableCSRFProtection) return _namedImageDisplayTemplate diff --git a/plone/app/standardtiles/head.py b/plone/app/standardtiles/head.py index 2ab98b50..f53c02ec 100644 --- a/plone/app/standardtiles/head.py +++ b/plone/app/standardtiles/head.py @@ -1,111 +1,37 @@ # -*- coding: utf-8 -*- -from plone.app.layout.globals.interfaces import IViewView from plone.tiles.tile import Tile from zope.component import getMultiAdapter -from zope.component import queryMultiAdapter -from zope.interface import alsoProvides -from zope.viewlet.interfaces import IViewlet -from zope.viewlet.interfaces import IViewletManager +from plone.app.standardtiles.common import BaseViewletTile -class TitleTile(Tile): +class TitleTile(BaseViewletTile): """A tile rendering the title tag to be inserted in the HTML headers.""" + manager = 'plone.htmlhead' + viewlet = 'plone.htmlhead.title' - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.htmlhead.title' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class StylesheetsTile(Tile): + +class StylesheetsTile(BaseViewletTile): + """A stylesheets rendering tile.""" + manager = 'plone.htmlhead.links' + viewlet = 'plone.resourceregistries.styles' + + +class JavascriptsTile(BaseViewletTile): """A stylesheets rendering tile.""" + manager = 'plone.scripts' + viewlet = 'plone.resourceregistries.scripts' + - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead.links' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.resourceregistries.styles' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class JavascriptsTile(Tile): - """A javascripts rendering tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.scripts' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.resourceregistries.scripts' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class FaviconLinkTile(Tile): +class FaviconLinkTile(BaseViewletTile): """Favicon link tile implementation.""" + manager = 'plone.htmlhead.links' + viewlet = 'plone.links.favicon' - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead.links' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.links.favicon' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class AuthorLinkTile(Tile): - """Author link tile implementation.""" - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead.links' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.links.author' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +class AuthorLinkTile(BaseViewletTile): + """Author link tile implementation.""" + manager = 'plone.htmlhead.links' + viewlet = 'plone.links.author' class NavigationLinkTile(Tile): @@ -118,97 +44,29 @@ def navigation_root_url(self): return portal_state.navigation_root_url() -class SearchLinkTile(Tile): +class SearchLinkTile(BaseViewletTile): """Search link tile implementation.""" + manager = 'plone.htmlhead.links' + viewlet = 'plone.links.search' + - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead.links' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.links.search' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class RSSLinkTile(Tile): +class RSSLinkTile(BaseViewletTile): """RSS link tile implementation.""" + manager = 'plone.htmlhead.links' + viewlet = 'plone.links.RSS' + - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead.links' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.links.RSS' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class CanonicalUrlTile(Tile): +class CanonicalUrlTile(BaseViewletTile): """Canonical url tile implementation.""" + manager = 'plone.htmlhead.links' + viewlet = 'plone.links.canonical_url' + + +class DublinCoreTile(BaseViewletTile): + manager = 'plone.htmlhead' + viewlet = 'plone.htmlhead.dublincore' + - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead.links' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.links.canonical_url' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class DublinCoreTile(Tile): - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.htmlhead.dublincore' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' - - -class SocialTile(Tile): - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.htmlhead' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.htmlhead.socialtags' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +class SocialTile(BaseViewletTile): + manager = 'plone.htmlhead' + viewlet = 'plone.htmlhead.socialtags' diff --git a/plone/app/standardtiles/image.py b/plone/app/standardtiles/image.py index ec78fbbe..2d3d0c56 100644 --- a/plone/app/standardtiles/image.py +++ b/plone/app/standardtiles/image.py @@ -5,44 +5,30 @@ from plone.registry.interfaces import IRegistry from plone.supermodel.model import Schema from plone.tiles import PersistentTile +from Products.CMFPlone.interfaces.controlpanel import IImagingSchema from z3c.form.browser.radio import RadioFieldWidget from zope import schema from zope.component import getUtility -from zope.component.hooks import getSite from zope.interface import provider from zope.schema.interfaces import IContextSourceBinder from zope.schema.vocabulary import SimpleTerm from zope.schema.vocabulary import SimpleVocabulary -try: - from Products.CMFPlone.interfaces.controlpanel import IImagingSchema - HAS_PLONE_5 = True -except ImportError: - from plone.app.imaging.interfaces import IImagingSchema - HAS_PLONE_5 = False - -try: - from plone.protect.interfaces import IDisableCSRFProtection - HAS_PLONE_PROTECT = True -except ImportError: - HAS_PLONE_PROTECT = False - def get_settings(): registry = getUtility(IRegistry) - settings = registry.forInterface(IImagingSchema, - prefix="plone", - check=False) + settings = registry.forInterface( + IImagingSchema, + prefix="plone", + check=False + ) return settings @provider(IContextSourceBinder) def image_scales(context): values = [] - if HAS_PLONE_5: - settings = get_settings() - else: - settings = IImagingSchema(getSite()) + settings = get_settings() for allowed_size in settings.allowed_sizes: name = allowed_size.split()[0] if name not in ("thumb", "tile", "icon", "listing"): diff --git a/plone/app/standardtiles/keywords.py b/plone/app/standardtiles/keywords.py index c3c8bffa..464f3e4c 100644 --- a/plone/app/standardtiles/keywords.py +++ b/plone/app/standardtiles/keywords.py @@ -1,27 +1,10 @@ # -*- coding: utf-8 -*- -from plone.app.layout.globals.interfaces import IViewView -from plone.tiles import Tile -from zope.component import queryMultiAdapter -from zope.interface import alsoProvides -from zope.viewlet.interfaces import IViewlet -from zope.viewlet.interfaces import IViewletManager +import zope.deferredimport +zope.deferredimport.initialize() +# remove with 3.0 -class KeywordsTile(Tile): - """A tile that displays the context's keywords, if any.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.belowcontent' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.belowcontenttitle.keywords' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +zope.deferredimport.deprecated( + "Import from plone.app.standardtiles.common instead", + KeywordsTile='plone.app.standardtiles.common:KeywordsTile', +) diff --git a/plone/app/standardtiles/metadata.py b/plone/app/standardtiles/metadata.py index d73f76de..e39c4a05 100644 --- a/plone/app/standardtiles/metadata.py +++ b/plone/app/standardtiles/metadata.py @@ -1,14 +1,13 @@ # -*- coding: utf-8 -*- from plone.app.standardtiles.interfaces import IMetadataTile from plone.tiles.tile import Tile -from zope.interface import implements +from zope.interface import implementer +@implementer(IMetadataTile) class BaseMetadataTile(Tile): """The base class for metadata tiles (such as title and description).""" - implements(IMetadataTile) - def get_value(self): return u"" diff --git a/plone/app/standardtiles/navigation.py b/plone/app/standardtiles/navigation.py index 0fc2ec93..c58bac14 100644 --- a/plone/app/standardtiles/navigation.py +++ b/plone/app/standardtiles/navigation.py @@ -2,13 +2,6 @@ from Acquisition import aq_base from Acquisition import aq_inner from Acquisition import aq_parent -from Products.CMFCore.interfaces import IFolderish -from Products.CMFCore.utils import getToolByName -from Products.CMFDynamicViewFTI.interface import IBrowserDefault -from Products.CMFPlone.browser.navtree import NavtreeQueryBuilder -from Products.CMFPlone.browser.navtree import SitemapNavtreeStrategy -from Products.CMFPlone.interfaces import INonStructuralFolder -from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from plone.app.layout.navigation.defaultpage import isDefaultPage from plone.app.layout.navigation.interfaces import INavigationQueryBuilder from plone.app.layout.navigation.interfaces import INavtreeStrategy @@ -21,16 +14,21 @@ from plone.supermodel.model import Schema from plone.tiles import Tile from plone.uuid.interfaces import IUUID +from Products.CMFCore.interfaces import IFolderish +from Products.CMFCore.utils import getToolByName +from Products.CMFDynamicViewFTI.interface import IBrowserDefault +from Products.CMFPlone.browser.navtree import NavtreeQueryBuilder +from Products.CMFPlone.browser.navtree import SitemapNavtreeStrategy +from Products.CMFPlone.interfaces import INonStructuralFolder +from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from z3c.form.interfaces import IValue from z3c.form.util import getSpecification from zope import schema from zope.component import adapter -from zope.component import adapts from zope.component import getMultiAdapter from zope.component import queryUtility -from zope.interface import Interface from zope.interface import implementer -from zope.interface import implements +from zope.interface import Interface def uuidToFolderishPath(context, uuid): @@ -64,46 +62,54 @@ class INavigationTile(Schema): root = schema.Choice( title=_(u"Root node"), - description=_(u"You may search for and choose a folder to act as " - "the root of the navigation tree. Leave blank to " - "use the Plone site root."), + description=_( + u'You may search for and choose a folder to act as the root ' + u'of the navigation tree. Leave blank to use the Plone site ' + u'root.' + ), source=CatalogSource(), required=False) includeTop = schema.Bool( title=_(u"Include top node"), - description=_(u"Whether or not to show the top, or 'root', node " - "in the navigation tree. This is affected by the " - "'Start level' setting."), + description=_( + u"Whether or not to show the top, or 'root', node in the " + u"navigation tree. This is affected by the 'Start level' " + u"setting." + ), default=False, required=False) currentFolderOnly = schema.Bool( title=_(u"Only show the contents of the current folder."), - description=_(u"If selected, the navigation tree will only show " - "the current folder and its children at all " - "times."), + description=_( + u"If selected, the navigation tree will only show the current " + u"folder and its children at all times." + ), default=False, required=False) topLevel = schema.Int( title=_(u"Start level"), - description=_(u"An integer value that specifies the number of " - "folder levels below the site root that must be " - "exceeded before the navigation tree will display. " - "0 means that the navigation tree should be " - "displayed everywhere including pages in the root " - "of the site. 1 means the tree only shows up " - "inside folders located in the root and downwards, " - "never showing at the top level."), + description=_( + u"An integer value that specifies the number of folder levels " + u"below the site root that must be exceeded before the " + u"navigation tree will display. 0 means that the navigation " + u"tree should be displayed everywhere including pages in the " + u"root of the site. 1 means the tree only shows up inside " + u"folders located in the root and downwards, never showing at " + u"the top level." + ), default=0, required=False) bottomLevel = schema.Int( title=_(u"Navigation tree depth"), - description=_(u"How many folders should be included before the " - "navigation tree stops. 0 means no limit. 1 only " - "includes the root folder."), + description=_( + u"How many folders should be included before the navigation " + u"tree stops. 0 means no limit. 1 only includes the root " + u"folder." + ), default=0, required=False) @@ -122,10 +128,9 @@ def get(self): return IUUID(self.context, None) +@implementer(INavigationTile) class NavigationTile(Tile): - implements(INavigationTile) - def __init__(self, *arg, **kw): super(NavigationTile, self).__init__(*arg, **kw) self.urltool = getToolByName(self.context, 'portal_url') @@ -156,9 +161,12 @@ def root_item_class(self): context = aq_inner(self.context) root = self.getNavRoot() container = aq_parent(context) - if (aq_base(root) is aq_base(context) or - (aq_base(root) is aq_base(container) and - isDefaultPage(container, context))): + if ( + aq_base(root) is aq_base(context) or ( + aq_base(root) is aq_base(container) and + isDefaultPage(container, context) + ) + ): return 'navTreeCurrentItem' return '' @@ -198,29 +206,29 @@ def getNavRoot(self, _marker=[]): if rootPath == self.urltool.getPortalPath(): return portal - else: - try: - return portal.unrestrictedTraverse(rootPath) - except (AttributeError, KeyError,): - return portal + try: + return portal.unrestrictedTraverse(rootPath) + except (AttributeError, KeyError,): + return portal @memoize def getNavTree(self, _marker=[]): context = aq_inner(self.context) - queryBuilder = getMultiAdapter((context, self), - INavigationQueryBuilder) + queryBuilder = getMultiAdapter( + (context, self), + INavigationQueryBuilder + ) strategy = getMultiAdapter((context, self), INavtreeStrategy) - return buildFolderTree(context, obj=context, query=queryBuilder(), strategy=strategy) +@implementer(INavigationQueryBuilder) +@adapter(Interface, INavigationTile) class QueryBuilder(NavtreeQueryBuilder): """Build a navtree query based on the settings in navtree_properties and those set on the tile. """ - implements(INavigationQueryBuilder) - adapts(Interface, INavigationTile) def __init__(self, context, tile): super(QueryBuilder, self).__init__(context) @@ -239,15 +247,16 @@ def __init__(self, context, tile): else: self.query['path'] = {'query': currentPath, 'navtree': 1} - topLevel = tile.data.get('topLevel') or navtree_properties.getProperty('topLevel', 0) + topLevel = (tile.data.get('topLevel') or + navtree_properties.getProperty('topLevel', 0)) if topLevel and topLevel > 0: self.query['path']['navtree_start'] = topLevel + 1 +@implementer(INavtreeStrategy) +@adapter(Interface, INavigationTile) class NavtreeStrategy(SitemapNavtreeStrategy): """The navtree strategy used for the default navigation tile.""" - implements(INavtreeStrategy) - adapts(Interface, INavigationTile) def __init__(self, context, tile): SitemapNavtreeStrategy.__init__(self, context, tile) @@ -255,36 +264,38 @@ def __init__(self, context, tile): navtree_properties = getattr(portal_properties, 'navtree_properties') # XXX: We can't do this with a 'depth' query to EPI... - self.bottomLevel = tile.data.get('bottomLevel') or \ - navtree_properties.getProperty('bottomLevel', 0) - - currentFolderOnly = tile.data.get('currentFolderOnly') or \ - navtree_properties.getProperty( - 'currentFolderOnlyInNavtree', False) - topLevel = tile.data.get('topLevel') or \ - navtree_properties.getProperty('topLevel', 0) + self.bottomLevel = ( + tile.data.get('bottomLevel') or + navtree_properties.getProperty('bottomLevel', 0) + ) + currentFolderOnly = ( + tile.data.get('currentFolderOnly') or + navtree_properties.getProperty('currentFolderOnlyInNavtree', False) + ) + topLevel = ( + tile.data.get('topLevel') or + navtree_properties.getProperty('topLevel', 0) + ) tileRoot = uuidToFolderishPath(context, tile.data.get('root')) self.rootPath = getRootPath(context, currentFolderOnly, topLevel, tileRoot) def subtreeFilter(self, node): sitemapDecision = SitemapNavtreeStrategy.subtreeFilter(self, node) - if sitemapDecision == False: + if not sitemapDecision: return False depth = node.get('depth', 0) - if depth > 0 and self.bottomLevel > 0 and depth >= self.bottomLevel: - return False - else: - return True + return not ( + depth > 0 and self.bottomLevel > 0 and depth >= self.bottomLevel + ) def getRootPath(context, currentFolderOnly, topLevel, root): """Helper function to calculate the real root path.""" context = aq_inner(context) if currentFolderOnly: - folderish = getattr(aq_base(context), - 'isPrincipiaFolderish', False) and \ - not INonStructuralFolder.providedBy(context) + folderish = getattr(aq_base(context), 'isPrincipiaFolderish', False) + folderish &= not INonStructuralFolder.providedBy(context) parent = aq_parent(context) is_default_page = False @@ -306,13 +317,10 @@ def getRootPath(context, currentFolderOnly, topLevel, root): if not contextPath.startswith(rootPath): return None contextSubPathElements = contextPath[len(rootPath) + 1:] - if contextSubPathElements: - contextSubPathElements = contextSubPathElements.split('/') - if len(contextSubPathElements) < topLevel: - return None - rootPath = '%s/%s' % (rootPath, - '/'.join(contextSubPathElements[:topLevel])) - else: + if not contextSubPathElements: return None - + contextSubPathElements = contextSubPathElements.split('/') + if len(contextSubPathElements) < topLevel: + return None + rootPath = '/'.join([rootPath] + contextSubPathElements[:topLevel]) return rootPath diff --git a/plone/app/standardtiles/portlets/__init__.py b/plone/app/standardtiles/portlets/__init__.py index e69de29b..40a96afc 100644 --- a/plone/app/standardtiles/portlets/__init__.py +++ b/plone/app/standardtiles/portlets/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/plone/app/standardtiles/portlets/add.py b/plone/app/standardtiles/portlets/add.py index 96cfb279..dbc9971c 100644 --- a/plone/app/standardtiles/portlets/add.py +++ b/plone/app/standardtiles/portlets/add.py @@ -1,13 +1,14 @@ -#-*- coding: utf-8 -*- +# -*- coding: utf-8 -*- from Acquisition import aq_base from Acquisition import aq_inner from Acquisition import aq_parent -from plone.app.portlets.browser.adding import PortletAdding as BasePortletAdding +from plone.app.portlets.browser.adding import PortletAdding as BasePortletAdding # noqa from plone.app.portlets.interfaces import IPortletPermissionChecker from plone.app.tiles import MessageFactory as _ from plone.app.tiles.browser.add import DefaultAddForm from plone.app.tiles.browser.add import DefaultAddView from plone.portlets.utils import hashPortletInfo +from plone.protect.utils import addTokenToUrl from plone.tiles.interfaces import ITileDataManager from plone.uuid.interfaces import IUUIDGenerator from z3c.form import button @@ -18,12 +19,6 @@ from zope.lifecycleevent import ObjectCreatedEvent from zope.traversing.browser.absoluteurl import absoluteURL -try: - from plone.protect.utils import addTokenToUrl - HAS_PLONE_PROTECT = True -except ImportError: - HAS_PLONE_PROTECT = False - class PortletAdding(BasePortletAdding): """Overrides portlet manager '+' view in order to get the hash of the @@ -102,8 +97,7 @@ def handleAdd(self, action): '++contextportlets++{0}/+'.format(mgr_name), data['portlet_type'] ]) - if HAS_PLONE_PROTECT: - add_portlet_url = addTokenToUrl(add_portlet_url, self.request) + add_portlet_url = addTokenToUrl(add_portlet_url, self.request) self.request.response.redirect(add_portlet_url) @button.buttonAndHandler(_(u'Cancel'), name='cancel') diff --git a/plone/app/standardtiles/portlets/assignment.py b/plone/app/standardtiles/portlets/assignment.py index e898c6ec..6f1c6e34 100644 --- a/plone/app/standardtiles/portlets/assignment.py +++ b/plone/app/standardtiles/portlets/assignment.py @@ -5,8 +5,8 @@ from plone.app.standardtiles.interfaces import IPortletManagerAssignment from plone.portlets.constants import CONTEXT_ASSIGNMENT_KEY from plone.portlets.constants import CONTEXT_CATEGORY -from plone.portlets.interfaces import IPortletAssignmentMapping from plone.portlets.interfaces import ILocalPortletAssignable +from plone.portlets.interfaces import IPortletAssignmentMapping from zope.annotation.interfaces import IAnnotations from zope.component import adapter from zope.interface import implementer @@ -16,6 +16,7 @@ # We need a custom marker interface for the assignment # of our portlet manager... here is it! + @implementer(IPortletManagerAssignment) class Mapping(PortletAssignmentMapping): pass diff --git a/plone/app/standardtiles/portlets/delete.py b/plone/app/standardtiles/portlets/delete.py index 009fd8d9..861c2b45 100644 --- a/plone/app/standardtiles/portlets/delete.py +++ b/plone/app/standardtiles/portlets/delete.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- - from plone.app.tiles.browser.delete import DefaultDeleteView @@ -12,4 +11,3 @@ def __call__(self): result = super(PortletTileDeleteView, self).__call__() # delete the portlet # TODO - diff --git a/plone/app/standardtiles/portlets/edit.py b/plone/app/standardtiles/portlets/edit.py index 334e1eb8..58637048 100644 --- a/plone/app/standardtiles/portlets/edit.py +++ b/plone/app/standardtiles/portlets/edit.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- -from zope.component import getUtility -from plone.uuid.interfaces import IUUIDGenerator - -from plone.portlets.utils import unhashPortletInfo from plone.app.tiles.browser.edit import DefaultEditView +from plone.portlets.utils import unhashPortletInfo +from plone.uuid.interfaces import IUUIDGenerator +from zope.component import getUtility import urllib @@ -15,8 +14,10 @@ class PortletTileEditView(DefaultEditView): def __call__(self): portlet_hash = self.request['portlet_hash'] info = unhashPortletInfo(portlet_hash) - url = '{}/++contextportlets++plone.app.standardtiles.portletManager/{}/edit'.format(self.context.absolute_url(), info['name']) - + url = ( + '{0}/++contextportlets++plone.app.standardtiles.portletManager/' + '{1}/edit'.format(self.context.absolute_url(), info['name']) + ) if not self.tileId: generator = getUtility(IUUIDGenerator) tileId = generator() @@ -24,7 +25,14 @@ def __call__(self): tileId = self.tileId typeName = 'plone.app.standardtiles.portlet' - tile_url = '{}/@@{}/{}?portlet_hash={}'.format(self.context.absolute_url(), typeName, tileId, portlet_hash) - + tile_url = '{0}/@@{1}/{2}?portlet_hash={3}'.format( + self.context.absolute_url(), + typeName, + tileId, + portlet_hash + ) self.request.form['referer'] = tile_url - self.request.response.redirect('{}?referer={}'.format(url, urllib.quote(tile_url))) + self.request.response.redirect( + '{0}?referer={0}'.format(url, urllib.quote(tile_url)) + ) + diff --git a/plone/app/standardtiles/portlets/portletmanager.py b/plone/app/standardtiles/portlets/portletmanager.py index 4919ccb4..34e353b2 100644 --- a/plone/app/standardtiles/portlets/portletmanager.py +++ b/plone/app/standardtiles/portlets/portletmanager.py @@ -1,4 +1,4 @@ -#-*- coding: utf-8 -*- +# -*- coding: utf-8 -*- from zope import schema from zope.interface import Interface from zope.interface import implements diff --git a/plone/app/standardtiles/portlets/utils.py b/plone/app/standardtiles/portlets/utils.py index 060e5d37..f24e7cab 100644 --- a/plone/app/standardtiles/portlets/utils.py +++ b/plone/app/standardtiles/portlets/utils.py @@ -1,5 +1,4 @@ -#-*- coding: utf-8 -*- - +# -*- coding: utf-8 -*- from zope.browser.interfaces import IView from zope.component import queryMultiAdapter diff --git a/plone/app/standardtiles/portlets/vocabularies.py b/plone/app/standardtiles/portlets/vocabularies.py index 2098dad6..26c86608 100644 --- a/plone/app/standardtiles/portlets/vocabularies.py +++ b/plone/app/standardtiles/portlets/vocabularies.py @@ -1,19 +1,19 @@ -#-*- coding: utf-8 -*- -from plone.portlets.interfaces import IPortletManager +# -*- coding: utf-8 -*- from plone.app.standardtiles import PloneMessageFactory as _ -from zope.interface import implements +from plone.portlets.interfaces import IPortletManager from zope.component import getUtility from zope.globalrequest import getRequest +from zope.interface import implementer +from zope.schema.interfaces import IVocabularyFactory from zope.schema.vocabulary import SimpleTerm from zope.schema.vocabulary import SimpleVocabulary -from zope.schema.interfaces import IVocabularyFactory PORTLET_MANAGER = 'plone.app.standardtiles.portletManager' +@implementer(IVocabularyFactory) class BaseVocabulary(object): - implements(IVocabularyFactory) def __call__(self, context): terms = self.get_terms(context) diff --git a/plone/app/standardtiles/raw.py b/plone/app/standardtiles/raw.py index 220020fe..0711bbfc 100644 --- a/plone/app/standardtiles/raw.py +++ b/plone/app/standardtiles/raw.py @@ -29,8 +29,12 @@ def __call__(self): if not self.request.get('_layouteditor'): # Here we skip legacy portal_transforms and call # plone.outputfilters directly by purpose - filters = [f for _, f - in getAdapters((self.context, self.request), IFilter)] + filters = [ + f for _, f in getAdapters( + (self.context, self.request), + IFilter + ) + ] content = apply_filters(filters, content) else: content = u'

' diff --git a/plone/app/standardtiles/rss.py b/plone/app/standardtiles/rss.py index 86cd0c60..a35e2210 100644 --- a/plone/app/standardtiles/rss.py +++ b/plone/app/standardtiles/rss.py @@ -5,8 +5,9 @@ from plone.tiles.tile import Tile from zope import schema from zope.component import getMultiAdapter +from zope.interface import implementer from zope.interface import Interface -from zope.interface import implements + import feedparser import time @@ -157,11 +158,10 @@ def ok(): """Is this feed ok to display?""" +@implementer(IFeed) class RSSFeed(object): """An RSS feed.""" - implements(IFeed) - # TODO: discuss whether we want an increasing update time here, probably # not though FAILURE_DELAY = 10 # time in minutes after which we retry to load it diff --git a/plone/app/standardtiles/sitemap.py b/plone/app/standardtiles/sitemap.py index 8c53a48a..b7829cd9 100644 --- a/plone/app/standardtiles/sitemap.py +++ b/plone/app/standardtiles/sitemap.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -from Products.CMFCore.utils import getToolByName from plone.app.standardtiles import PloneMessageFactory as _ from plone.app.standardtiles.navigation import NavigationTile from plone.registry.interfaces import IRegistry from plone.supermodel.model import Schema +from Products.CMFCore.utils import getToolByName from zope import schema from zope.component import getUtility -from zope.interface import implements +from zope.interface import implementer try: from Products.CMFPlone.interfaces.controlpanel import INavigationSchema @@ -25,10 +25,9 @@ class ISitemapTile(Schema): ) +@implementer(ISitemapTile) class SitemapTile(NavigationTile): - implements(ISitemapTile) - def __init__(self, *arg, **kw): super(SitemapTile, self).__init__(*arg, **kw) self.data['root'] = None diff --git a/plone/app/standardtiles/tableofcontents.py b/plone/app/standardtiles/tableofcontents.py index 2ecd4ea3..cab4d674 100644 --- a/plone/app/standardtiles/tableofcontents.py +++ b/plone/app/standardtiles/tableofcontents.py @@ -1,27 +1,10 @@ # -*- coding: utf-8 -*- -from plone.app.layout.globals.interfaces import IViewView -from plone.tiles import Tile -from zope.component import queryMultiAdapter -from zope.interface import alsoProvides -from zope.viewlet.interfaces import IViewlet -from zope.viewlet.interfaces import IViewletManager +import zope.deferredimport +zope.deferredimport.initialize() +# remove with 3.0 -class TableOfContentsTile(Tile): - """A Table of contents tile.""" - - def __call__(self): - alsoProvides(self, IViewView) - manager = queryMultiAdapter( - (self.context, self.request, self), - IViewletManager, name='plone.abovecontentbody' - ) - viewlet = queryMultiAdapter( - (self.context, self.request, self, manager), - IViewlet, name='plone.tableofcontents' - ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - else: - return u'' +zope.deferredimport.deprecated( + "Import from plone.app.standardtiles.common instead", + TableOfContentsTile='plone.app.standardtiles.common:TableOfContentsTile', +) diff --git a/plone/app/standardtiles/testing.py b/plone/app/standardtiles/testing.py index 3f8e3506..453a1ab8 100644 --- a/plone/app/standardtiles/testing.py +++ b/plone/app/standardtiles/testing.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- -from Products.CMFCore.utils import getToolByName -from plone.app.testing import PLONE_FIXTURE -from plone.app.testing import PloneSandboxLayer from plone.app.testing import applyProfile from plone.app.testing import login from plone.app.testing import logout +from plone.app.testing import PLONE_FIXTURE +from plone.app.testing import PloneSandboxLayer from plone.app.testing.layers import FunctionalTesting from plone.app.testing.layers import IntegrationTesting from plone.autoform import directives @@ -13,6 +12,7 @@ from plone.portlets.manager import PortletManager from plone.portlets.manager import PortletManagerRenderer from plone.supermodel.model import Schema +from Products.CMFCore.utils import getToolByName from z3c.form import interfaces from z3c.form.browser import widget from z3c.form.widget import FieldWidget @@ -24,23 +24,13 @@ from zope.component import provideAdapter from zope.configuration import xmlconfig from zope.contentprovider.interfaces import UpdateNotCalled -from zope.interface import Interface from zope.interface import implementer from zope.interface import implements from zope.interface import implementsOnly +from zope.interface import Interface from zope.publisher.interfaces.browser import IBrowserRequest from zope.publisher.interfaces.browser import IBrowserView -import pkg_resources - -HAS_PLONE_5 = \ - int(pkg_resources.get_distribution('Products.CMFPlone').version[0]) > 4 -try: - pkg_resources.get_distribution('plone.app.theming') -except pkg_resources.DistributionNotFound: - HAS_PLONE_APP_THEMING = False -else: - HAS_PLONE_APP_THEMING = True NORMAL_USER_NAME = 'user' NORMAL_USER_PASSWORD = 'secret' @@ -162,28 +152,24 @@ def setUpZope(self, app, configurationContext): xmlconfig.file('testing.zcml', plone.app.standardtiles, context=configurationContext) - if HAS_PLONE_5: - import plone.app.contenttypes - xmlconfig.file('configure.zcml', plone.app.contenttypes, - context=configurationContext) + import plone.app.contenttypes + xmlconfig.file('configure.zcml', plone.app.contenttypes, + context=configurationContext) def setUpPloneSite(self, portal): # install into the Plone site applyProfile(portal, 'plone.app.dexterity:default') applyProfile(portal, 'plone.app.widgets:default') applyProfile(portal, 'plone.app.standardtiles:default') - - if HAS_PLONE_5: - applyProfile(portal, 'plone.app.contenttypes:default') + applyProfile(portal, 'plone.app.contenttypes:default') # ensure plone.app.theming disabled - if HAS_PLONE_APP_THEMING: - from plone.registry.interfaces import IRegistry - from zope.component import getUtility - registry = getUtility(IRegistry) - key = 'plone.app.theming.interfaces.IThemeSettings.enabled' - if key in registry: - registry[key] = False + from plone.registry.interfaces import IRegistry + from zope.component import getUtility + registry = getUtility(IRegistry) + key = 'plone.app.theming.interfaces.IThemeSettings.enabled' + if key in registry: + registry[key] = False # creates some users acl_users = getToolByName(portal, 'acl_users') @@ -243,13 +229,12 @@ def setUpPloneSite(self, portal): applyProfile(portal, 'plone.app.standardtiles:default') # ensure plone.app.theming disabled - if HAS_PLONE_APP_THEMING: - from plone.registry.interfaces import IRegistry - from zope.component import getUtility - registry = getUtility(IRegistry) - key = 'plone.app.theming.interfaces.IThemeSettings.enabled' - if key in registry: - registry[key] = False + from plone.registry.interfaces import IRegistry + from zope.component import getUtility + registry = getUtility(IRegistry) + key = 'plone.app.theming.interfaces.IThemeSettings.enabled' + if key in registry: + registry[key] = False # creates some users acl_users = getToolByName(portal, 'acl_users') diff --git a/plone/app/standardtiles/tests/test_content.py b/plone/app/standardtiles/tests/test_content.py index 579070b1..96453740 100644 --- a/plone/app/standardtiles/tests/test_content.py +++ b/plone/app/standardtiles/tests/test_content.py @@ -1,28 +1,27 @@ # -*- coding: utf-8 -*- -from Products.CMFCore.utils import getToolByName from lxml import html -from plone.app.standardtiles.image import HAS_PLONE_5 from plone.app.standardtiles.testing import EDITOR_USER_NAME from plone.app.standardtiles.testing import EDITOR_USER_PASSWORD from plone.app.standardtiles.testing import PASTANDARDTILES_FUNCTIONAL_TESTING # noqa +from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.app.testing import TEST_USER_NAME from plone.app.testing import TEST_USER_PASSWORD -from plone.app.testing import setRoles from plone.locking.interfaces import ILockable from plone.testing.z2 import Browser +from Products.CMFCore.utils import getToolByName from unittest import TestCase +from z3c.relationfield import RelationValue +from zope.component import getUtility +from zope.intid import IIntIds + import transaction + def fromstring(s): html_parser = html.HTMLParser(encoding='utf-8') return html.fromstring(s, parser=html_parser).getroottree().getroot() -if HAS_PLONE_5: - from z3c.relationfield import RelationValue - from zope.component import getUtility - from zope.intid import IIntIds - class ContentTileTests(TestCase): """Here we show up the main tiles used for the content usage. @@ -72,8 +71,8 @@ def test_document_actions_tile(self): transaction.commit() self.unprivileged_browser.open( - self.pageURL - + '/@@plone.app.standardtiles.document_actions' + self.pageURL + + '/@@plone.app.standardtiles.document_actions' ) self.assertIn('document-action-print', @@ -88,12 +87,12 @@ def test_keywords_tile(self): assigned to the context. """ - # We will use the page we created before for the tests. Since we have not - # added any keyword to it yet, the tile contents are empty: + # We will use the page we created before for the tests. Since we have + # not added any keyword to it yet, the tile contents are empty: self.unprivileged_browser.open( - self.pageURL - + '/@@plone.app.standardtiles.keywords' + self.pageURL + + '/@@plone.app.standardtiles.keywords' ) self.assertNotIn('category', self.unprivileged_browser.contents) @@ -111,8 +110,8 @@ def test_keywords_tile(self): # The tile will show them: self.unprivileged_browser.open( - self.pageURL - + '/@@plone.app.standardtiles.keywords' + self.pageURL + + '/@@plone.app.standardtiles.keywords' ) self.assertIn('category', self.unprivileged_browser.contents) @@ -125,8 +124,8 @@ def test_keywords_tile(self): def test_related_items_tiles(self): self.browser.open( - self.pageURL - + '/@@plone.app.standardtiles.related_items' + self.pageURL + + '/@@plone.app.standardtiles.related_items' ) self.assertNotIn('relatedItems', self.browser.contents) @@ -137,23 +136,17 @@ def test_related_items_tiles(self): self.portal.invokeFactory('Document', 'doc1', title='Document 1') self.portal.invokeFactory('Document', 'doc2', title='Document 2') - if HAS_PLONE_5: - int_ids = getUtility(IIntIds) - self.page.relatedItems = [ - RelationValue(int_ids.getId(self.portal.doc1)), - RelationValue(int_ids.getId(self.portal.doc2)) - ] - else: - self.page.setRelatedItems([ - self.portal.doc1, - self.portal.doc2 - ]) + int_ids = getUtility(IIntIds) + self.page.relatedItems = [ + RelationValue(int_ids.getId(self.portal.doc1)), + RelationValue(int_ids.getId(self.portal.doc2)) + ] transaction.commit() self.browser.open( - self.pageURL - + '/@@plone.app.standardtiles.related_items' + self.pageURL + + '/@@plone.app.standardtiles.related_items' ) self.assertIn('relatedItems', self.browser.contents) @@ -164,27 +157,21 @@ def test_related_items_tiles(self): nodes = root.xpath('//body//*[@class="relatedItems"]') self.assertEqual(len(nodes), 1) - if HAS_PLONE_5: - nodes = root.xpath('//body//*[@class="relatedItems"]//ul/li') - else: - nodes = root.xpath('//body//*[@class="relatedItems"]//dl/dd') + nodes = root.xpath('//body//*[@class="relatedItems"]//ul/li') self.assertEqual(len(nodes), 2) def test_history_tile(self): # First edit a page so we have an edit history: self.browser.open(self.pageURL + '/edit') - if HAS_PLONE_5: - self.browser.getControl(name='form.widgets.IDublinCore.title').value = 'A different title' # noqa - else: - self.browser.getControl(name='title').value = 'A different title' + self.browser.getControl(name='form.widgets.IDublinCore.title').value = 'A different title' # noqa self.browser.getControl(label='Save').click() self.assertIn('A different title', self.browser.contents) # The tile will show them: self.browser.open( - self.pageURL - + '/@@plone.app.standardtiles.history' + self.pageURL + + '/@@plone.app.standardtiles.history' ) self.assertIn('content-history', self.browser.contents) @@ -199,8 +186,8 @@ def test_history_tile(self): def test_lockinfo_tile(self): self.other_browser.open( - self.pageURL - + '/@@plone.app.standardtiles.lockinfo' + self.pageURL + + '/@@plone.app.standardtiles.lockinfo' ) self.assertIn('plone-lock-status', self.other_browser.contents) @@ -217,8 +204,8 @@ def test_lockinfo_tile(self): # The tile will show them: self.other_browser.open( - self.pageURL - + '/@@plone.app.standardtiles.lockinfo' + self.pageURL + + '/@@plone.app.standardtiles.lockinfo' ) self.assertIn('plone-lock-status', self.other_browser.contents) diff --git a/plone/app/standardtiles/tests/test_head.py b/plone/app/standardtiles/tests/test_head.py index dbda1f0b..7e4f5b13 100644 --- a/plone/app/standardtiles/tests/test_head.py +++ b/plone/app/standardtiles/tests/test_head.py @@ -1,24 +1,20 @@ # -*- coding: utf-8 -*- from lxml import html -from Products.CMFCore.utils import getToolByName -from plone.registry.interfaces import IRegistry -from zope.component import getUtility from plone.app.standardtiles.testing import PASTANDARDTILES_FUNCTIONAL_TESTING +from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.app.testing import TEST_USER_NAME from plone.app.testing import TEST_USER_PASSWORD -from plone.app.testing import setRoles +from plone.registry.interfaces import IRegistry from plone.testing.z2 import Browser +from Products.CMFCore.utils import getToolByName +from Products.CMFPlone.interfaces import ISecuritySchema +from Products.CMFPlone.interfaces import ISiteSchema from unittest import TestCase +from zope.component import getUtility + import transaction -try: - from Products.CMFPlone.interfaces import ISecuritySchema - from Products.CMFPlone.interfaces import ISiteSchema - HAS_PLONE_5 = True -except ImportError: - from plone.app.controlpanel.security import ISecuritySchema - HAS_PLONE_5 = False def fromstring(s): html_parser = html.HTMLParser(encoding='utf-8') diff --git a/plone/app/standardtiles/tests/test_layout.py b/plone/app/standardtiles/tests/test_layout.py index 5c920723..47db9564 100644 --- a/plone/app/standardtiles/tests/test_layout.py +++ b/plone/app/standardtiles/tests/test_layout.py @@ -1,25 +1,21 @@ # -*- coding: utf-8 -*- -from Products.CMFCore.utils import getToolByName from lxml import html from plone.app.discussion.interfaces import IDiscussionSettings from plone.app.standardtiles.testing import PASTANDARDTILES_FUNCTIONAL_TESTING +from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.app.testing import TEST_USER_NAME from plone.app.testing import TEST_USER_PASSWORD -from plone.app.testing import setRoles from plone.registry.interfaces import IRegistry from plone.testing.z2 import Browser +from Products.CMFCore.utils import getToolByName +from Products.CMFPlone.interfaces import ISecuritySchema +from Products.CMFPlone.interfaces import ISiteSchema from unittest import TestCase from zope.component import queryUtility + import transaction -try: - from Products.CMFPlone.interfaces import ISecuritySchema - from Products.CMFPlone.interfaces import ISiteSchema - HAS_PLONE_5 = True -except ImportError: - from plone.app.controlpanel.security import ISecuritySchema - HAS_PLONE_5 = False def fromstring(s): html_parser = html.HTMLParser(encoding='utf-8') @@ -58,8 +54,8 @@ def setUp(self): def test_colophon_tile(self): self.unprivileged_browser.open( - self.portalURL - + '/@@plone.app.standardtiles.colophon' + self.portalURL + + '/@@plone.app.standardtiles.colophon' ) self.assertIn('portal-colophon', self.unprivileged_browser.contents) @@ -70,23 +66,20 @@ def test_colophon_tile(self): def test_footer_tile(self): self.unprivileged_browser.open( - self.portalURL - + '/@@plone.app.standardtiles.footer' + self.portalURL + + '/@@plone.app.standardtiles.footer' ) self.assertIn('portal-footer', self.unprivileged_browser.contents) root = fromstring(self.unprivileged_browser.contents) - if HAS_PLONE_5: - nodes = root.xpath('//body//*[@id="portal-footer-signature"]') - else: - nodes = root.xpath('//body//*[@id="portal-footer"]') + nodes = root.xpath('//body//*[@id="portal-footer-signature"]') self.assertEqual(len(nodes), 1) def test_site_actions_tile(self): self.unprivileged_browser.open( - self.portalURL - + '/@@plone.app.standardtiles.site_actions' + self.portalURL + + '/@@plone.app.standardtiles.site_actions' ) self.assertIn('portal-siteactions', self.unprivileged_browser.contents) @@ -97,8 +90,8 @@ def test_site_actions_tile(self): def test_empty_analytics_tile(self): self.unprivileged_browser.open( - self.portalURL - + '/@@plone.app.standardtiles.analytics' + self.portalURL + + '/@@plone.app.standardtiles.analytics' ) root = fromstring(self.unprivileged_browser.contents) @@ -107,19 +100,13 @@ def test_empty_analytics_tile(self): def test_analytics_tile(self): snippet = u"" # noqa - if HAS_PLONE_5: - site_settings = self.registry.forInterface(ISiteSchema, - prefix='plone') - site_settings.webstats_js = snippet - else: - ptool = getToolByName(self.portal, 'portal_properties') - ptool.site_properties.webstats_js = snippet - + site_settings = self.registry.forInterface(ISiteSchema, prefix='plone') + site_settings.webstats_js = snippet transaction.commit() self.unprivileged_browser.open( - self.portalURL - + '/@@plone.app.standardtiles.analytics' + self.portalURL + + '/@@plone.app.standardtiles.analytics' ) self.assertIn(' Date: Thu, 14 Apr 2016 17:25:23 +0200 Subject: [PATCH 2/4] fix in test --- plone/app/standardtiles/tests/test_head.py | 53 ++++++++++------------ 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/plone/app/standardtiles/tests/test_head.py b/plone/app/standardtiles/tests/test_head.py index 7e4f5b13..6cb5ef38 100644 --- a/plone/app/standardtiles/tests/test_head.py +++ b/plone/app/standardtiles/tests/test_head.py @@ -7,7 +7,6 @@ from plone.app.testing import TEST_USER_PASSWORD from plone.registry.interfaces import IRegistry from plone.testing.z2 import Browser -from Products.CMFCore.utils import getToolByName from Products.CMFPlone.interfaces import ISecuritySchema from Products.CMFPlone.interfaces import ISiteSchema from unittest import TestCase @@ -50,8 +49,8 @@ def setUp(self): def test_title_tile(self): self.unprivileged_browser.open( - self.portalURL - + '/@@plone.app.standardtiles.headtitle' + self.portalURL + + '/@@plone.app.standardtiles.headtitle' ) self.assertIn(' Date: Thu, 14 Apr 2016 17:31:34 +0200 Subject: [PATCH 3/4] fix head tiles --- plone/app/standardtiles/common.py | 13 +++++++++---- plone/app/standardtiles/head.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/plone/app/standardtiles/common.py b/plone/app/standardtiles/common.py index 6fdaa9bc..df3e82e0 100644 --- a/plone/app/standardtiles/common.py +++ b/plone/app/standardtiles/common.py @@ -20,6 +20,7 @@ class BaseViewletTile(Tile): manager = None viewlet = None + section = u'body' def __call__(self): alsoProvides(self, IViewView) @@ -33,10 +34,14 @@ def __call__(self): IViewlet, name=self.viewlet ) - if viewlet is not None: - viewlet.update() - return u'%s' % viewlet.render() - return u'' + if viewlet is None: + return u'' + + viewlet.update() + return u'<{section}>{rendered}'.format( + rendered=viewlet.render(), + section=self.section + ) class FooterTile(BaseViewletTile): diff --git a/plone/app/standardtiles/head.py b/plone/app/standardtiles/head.py index f53c02ec..abea1c4c 100644 --- a/plone/app/standardtiles/head.py +++ b/plone/app/standardtiles/head.py @@ -8,30 +8,35 @@ class TitleTile(BaseViewletTile): """A tile rendering the title tag to be inserted in the HTML headers.""" manager = 'plone.htmlhead' viewlet = 'plone.htmlhead.title' + section = u'head' class StylesheetsTile(BaseViewletTile): """A stylesheets rendering tile.""" manager = 'plone.htmlhead.links' viewlet = 'plone.resourceregistries.styles' + section = u'head' class JavascriptsTile(BaseViewletTile): """A stylesheets rendering tile.""" manager = 'plone.scripts' viewlet = 'plone.resourceregistries.scripts' + section = u'head' class FaviconLinkTile(BaseViewletTile): """Favicon link tile implementation.""" manager = 'plone.htmlhead.links' viewlet = 'plone.links.favicon' + section = u'head' class AuthorLinkTile(BaseViewletTile): """Author link tile implementation.""" manager = 'plone.htmlhead.links' viewlet = 'plone.links.author' + section = u'head' class NavigationLinkTile(Tile): @@ -48,25 +53,30 @@ class SearchLinkTile(BaseViewletTile): """Search link tile implementation.""" manager = 'plone.htmlhead.links' viewlet = 'plone.links.search' + section = u'head' class RSSLinkTile(BaseViewletTile): """RSS link tile implementation.""" manager = 'plone.htmlhead.links' viewlet = 'plone.links.RSS' + section = u'head' class CanonicalUrlTile(BaseViewletTile): """Canonical url tile implementation.""" manager = 'plone.htmlhead.links' viewlet = 'plone.links.canonical_url' + section = u'head' class DublinCoreTile(BaseViewletTile): manager = 'plone.htmlhead' viewlet = 'plone.htmlhead.dublincore' + section = u'head' class SocialTile(BaseViewletTile): manager = 'plone.htmlhead' viewlet = 'plone.htmlhead.socialtags' + section = u'head' From 29925e801712c046c3a9ab90b98ca3087cce17b7 Mon Sep 17 00:00:00 2001 From: "Jens W. Klein" Date: Thu, 14 Apr 2016 17:46:05 +0200 Subject: [PATCH 4/4] isort cfg added --- setup.cfg | 7 +++++++ setup.py | 1 + 2 files changed, 8 insertions(+) create mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..bd868016 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,7 @@ +[isort] +force_alphabetical_sort=True +force_single_line=True +lines_after_imports=2 +line_length=200 +not_skip=__init__.py + diff --git a/setup.py b/setup.py index 621c0fa4..f9cf07f4 100644 --- a/setup.py +++ b/setup.py @@ -2,6 +2,7 @@ from setuptools import find_packages from setuptools import setup + version = '2.0.0.dev0'