Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix URLs in folder_contents action buttons. #167

Merged
merged 1 commit into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ New features:

Bug fixes:

- *add item here*
- Fix URLs in folder_contents action buttons.
They need to be relative to the site root (resp. top site from url due to path handling in the structure pattern) and contain a {path} placeholder.
Fixes: https://github.com/plone/mockup/issues/857
[thet]


3.5.4 (2018-09-23)
Expand Down
5 changes: 4 additions & 1 deletion plone/app/content/browser/contents/copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from plone.app.content.browser.contents import ContentsBaseAction
from plone.app.content.interfaces import IStructureAction
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from zope.i18n import translate
from zope.interface import implementer

Expand All @@ -19,11 +20,13 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
return {
'tooltip': translate(_('Copy'), context=self.request),
'id': 'copy',
'icon': 'duplicate',
'url': self.context.absolute_url() + '/@@fc-copy'
'url': '%s{path}/@@fc-copy' % base_url,
}


Expand Down
5 changes: 4 additions & 1 deletion plone/app/content/browser/contents/cut.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from plone.app.content.browser.contents import ContentsBaseAction
from plone.app.content.interfaces import IStructureAction
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from zope.i18n import translate
from zope.interface import implementer

Expand All @@ -19,11 +20,13 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
return {
'tooltip': translate(_('Cut'), context=self.request),
'id': 'cut',
'icon': 'scissors',
'url': self.context.absolute_url() + '/@@fc-cut'
'url': '%s{path}/@@fc-cut' % base_url,
}


Expand Down
7 changes: 5 additions & 2 deletions plone/app/content/browser/contents/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from plone.app.content.interfaces import IStructureAction
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.component import getMultiAdapter
from zope.component.hooks import getSite
Expand All @@ -25,19 +26,21 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
return {
'tooltip': translate(_('Delete'), context=self.request),
'id': 'delete',
'icon': 'trash',
'context': 'danger',
'url': self.context.absolute_url() + '/@@fc-delete',
'url': '%s{path}/@@fc-delete' % base_url,
'form': {
'title': translate(_('Delete selected items'), context=self.request),
'submitText': translate(_('Yes'), context=self.request),
'submitContext': 'danger',
'template': self.template(),
'closeText': translate(_('No'), context=self.request),
'dataUrl': self.context.absolute_url() + '/@@fc-delete'
'dataUrl': '%s{path}/@@fc-delete' % base_url,
}
}

Expand Down
5 changes: 4 additions & 1 deletion plone/app/content/browser/contents/paste.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from plone.app.content.browser.contents import ContentsBaseAction
from plone.app.content.interfaces import IStructureAction
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from ZODB.POSException import ConflictError
from zope.i18n import translate
from zope.interface import implementer
Expand All @@ -18,11 +19,13 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
return {
'tooltip': translate(_('Paste'), context=self.request),
'id': 'paste',
'icon': 'open-file',
'url': self.context.absolute_url() + '/@@fc-paste'
'url': '%s{path}/@@fc-paste' % base_url,
}


Expand Down
7 changes: 5 additions & 2 deletions plone/app/content/browser/contents/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from Products.CMFCore.interfaces._content import IFolderish
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.component import getUtility
from zope.component.hooks import getSite
Expand All @@ -26,19 +27,21 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
base_vocabulary = '%s/@@getVocabulary?name=' % getSite().absolute_url()
return {
'tooltip': translate(_('Properties'), context=self.request),
'id': 'properties',
'icon': 'edit',
'url': self.context.absolute_url() + '/@@fc-properties',
'url': '%s{path}/@@fc-properties' % base_url,
'form': {
'title': _('Modify properties on items'),
'template': self.template(
vocabulary_url='%splone.app.vocabularies.Users' % (
base_vocabulary)
),
'dataUrl': self.context.absolute_url() + '/@@fc-properties',
'dataUrl': '%s{path}/@@fc-properties' % base_url,
}
}

Expand Down
6 changes: 4 additions & 2 deletions plone/app/content/browser/contents/rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from plone.app.content.interfaces import IStructureAction
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from ZODB.POSException import ConflictError
from zope.component import getMultiAdapter
Expand All @@ -15,7 +16,6 @@
from zope.interface import implementer
from zope.lifecycleevent import ObjectModifiedEvent


import logging
import six
import transaction
Expand All @@ -35,11 +35,13 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
return {
'tooltip': translate(_('Rename'), context=self.request),
'id': 'rename',
'icon': 'random',
'url': self.context.absolute_url() + '/@@fc-rename',
'url': '%s{path}/@@fc-rename' % base_url,
'form': {
'template': self.template()
}
Expand Down
5 changes: 4 additions & 1 deletion plone/app/content/browser/contents/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from plone.app.content.browser.contents import ContentsBaseAction
from plone.app.content.interfaces import IStructureAction
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.component.hooks import getSite
from zope.i18n import translate
Expand All @@ -19,12 +20,14 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
base_vocabulary = '%s/@@getVocabulary?name=' % getSite().absolute_url()
return {
'tooltip': translate(_('Tags'), context=self.request),
'id': 'tags',
'icon': 'tags',
'url': self.context.absolute_url() + '/@@fc-tags',
'url': '%s{path}/@@fc-tags' % base_url,
'form': {
'template': self.template(
vocabulary_url='%splone.app.vocabularies.Keywords' % (
Expand Down
7 changes: 5 additions & 2 deletions plone/app/content/browser/contents/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from Products.CMFCore.interfaces._content import IFolderish
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory as _
from Products.CMFPlone.utils import get_top_site_from_url
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from ZODB.POSException import ConflictError
from zope.i18n import translate
Expand All @@ -22,15 +23,17 @@ def __init__(self, context, request):
self.request = request

def get_options(self):
site = get_top_site_from_url(self.context, self.request)
base_url = site.absolute_url()
return {
'tooltip': translate(_('State'), context=self.request),
'id': 'workflow',
'icon': 'lock',
'url': self.context.absolute_url() + '/@@fc-workflow',
'url': '%s{path}/@@fc-workflow' % base_url,
'form': {
'title': _('Change workflow of selected items'),
'template': self.template(),
'dataUrl': self.context.absolute_url() + '/@@fc-workflow'
'dataUrl': '%s{path}/@@fc-workflow' % base_url,
}
}

Expand Down
41 changes: 41 additions & 0 deletions plone/app/content/tests/test_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,47 @@
import unittest


class FolderContentsTests(unittest.TestCase):
layer = PLONE_APP_CONTENT_DX_INTEGRATION_TESTING

def setUp(self):
self.portal = self.layer['portal']
self.request = self.layer['request']

# TYPE 1
type1_fti = DexterityFTI('type1')
type1_fti.klass = 'plone.dexterity.content.Container'
type1_fti.filter_content_types = True
type1_fti.allowed_content_types = ['type1']
type1_fti.behaviors = (
'Products.CMFPlone.interfaces.constrains.ISelectableConstrainTypes', # noqa
'plone.app.dexterity.behaviors.metadata.IBasic'
)
self.portal.portal_types._setObject('type1', type1_fti)
self.type1_fti = type1_fti

login(self.portal, TEST_USER_NAME)
setRoles(self.portal, TEST_USER_ID, ['Manager'])

def test_fc_buttonurls(self):
"""Test for correct URLs in folder_contents action buttons.
Refs: https://github.com/plone/plone.app.content/pull/166
"""
self.portal.invokeFactory('type1', id='f1', title='Folder 1')

fc = self.portal.f1.restrictedTraverse('@@folder_contents')

options = fc.get_options()
for button in options['buttons']:
url = button['url']
self.assertTrue('f1' not in url)
self.assertTrue('plone{path}/@@fc-' in url)
if button.get('form', {}).get('dataUrl', None):
url = button['form']['dataUrl']
self.assertTrue('f1' not in url)
self.assertTrue('plone{path}/@@fc-' in url)


class ContentsCopyTests(unittest.TestCase):
layer = PLONE_APP_CONTENT_DX_INTEGRATION_TESTING

Expand Down