Skip to content

Commit

Permalink
Restructure and extend CMS_PLACEHOLDER_CONF to handle regexp
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Federighi authored and yakky committed Jun 18, 2016
1 parent efc7484 commit ff85155
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 18 deletions.
14 changes: 13 additions & 1 deletion cms/plugin_pool.py
Expand Up @@ -172,13 +172,25 @@ def get_all_plugins(self, placeholder=None, page=None, setting_key="plugins", in
template,
) or ()

excluded_plugins = get_placeholder_conf(
'excluded plugins',
placeholder,
template,
) or ()
allowed_plugins = list(set(allowed_plugins) - set(excluded_plugins))

if not include_page_only:
# Filters out any plugin marked as page only because
# the include_page_only flag has been set to False
plugins = (plugin for plugin in plugins if not plugin.page_only)

if allowed_plugins:
plugins = (plugin for plugin in plugins if plugin.__name__ in allowed_plugins)
# Check that plugins are in the list of the allowed ones and not in the list
# of excluded ones
plugins = (
plugin for plugin in plugins if plugin.__name__ in allowed_plugins and
not plugin.__name__ not in excluded_plugins
)

if placeholder:
# Filters out any plugin that requires a parent or has set parent classes
Expand Down
72 changes: 72 additions & 0 deletions cms/tests/test_placeholder.py
Expand Up @@ -274,7 +274,53 @@ def test_get_placeholder_conf(self):
'inherit':'layout/home.html main',
'limits': {},
},
'*': {
'name': u'All',
'plugins': ['FilerImagePlugin', 'LinkPlugin',],
'limits': {},
},
}

TEST_CONF_LIST = [
('^main$', {
'name': 'main content',
'plugins': ['TextPlugin', 'LinkPlugin'],
'default_plugins':[
{
'plugin_type':'TextPlugin',
'values':{
'body':'<p>Some default text</p>'
},
},
],
}),
('^layout\/home\.html main$', {
'name': u'main content with FilerImagePlugin and limit',
'plugins': ['TextPlugin', 'FilerImagePlugin', 'LinkPlugin',],
'inherit':'main',
'limits': {'global': 1,},
}),
('^layout\/other\.html main$', {
'name': u'main content with FilerImagePlugin and no limit',
'inherit':'layout/home.html main',
'limits': {},
}),
('^foo-.*?$', {
'name': u'Foo type',
'plugins': ['TextPlugin', 'LinkPlugin',],
'limits': {},
}),
('^.*?foo-.*?$', {
'name': u'Random head Foo type',
'plugins': ['FilerImagePlugin',],
'limits': {},
}),
('^.*$', {
'name': u'All',
'plugins': ['FilerImagePlugin', 'LinkPlugin',],
'limits': {},
}),
]
with self.settings(CMS_PLACEHOLDER_CONF=TEST_CONF):
#test no inheritance
returned = get_placeholder_conf('plugins', 'main')
Expand All @@ -288,6 +334,32 @@ def test_get_placeholder_conf(self):
#test grandparent inherited value
returned = get_placeholder_conf('default_plugins', 'main', 'layout/other.html')
self.assertEqual(returned, TEST_CONF['main']['default_plugins'])
#test generic configuration
returned = get_placeholder_conf('plugins', 'something')
self.assertEqual(returned, TEST_CONF['*']['plugins'])

with self.settings(CMS_PLACEHOLDER_CONF=TEST_CONF_LIST):
#test no inheritance
returned = get_placeholder_conf('plugins', 'main')
self.assertEqual(returned, TEST_CONF_LIST[0][1]['plugins'])
#test no inherited value with inheritance enabled
returned = get_placeholder_conf('plugins', 'main', 'layout/home.html')
self.assertEqual(returned, TEST_CONF_LIST[1][1]['plugins'])
#test direct inherited value
returned = get_placeholder_conf('plugins', 'main', 'layout/other.html')
self.assertEqual(returned, TEST_CONF_LIST[1][1]['plugins'])
#test grandparent inherited value
returned = get_placeholder_conf('default_plugins', 'main', 'layout/other.html')
self.assertEqual(returned, TEST_CONF_LIST[0][1]['default_plugins'])
#test generic configuration
returned = get_placeholder_conf('plugins', 'something')
self.assertEqual(returned, TEST_CONF_LIST[5][1]['plugins'])
#test regex
returned = get_placeholder_conf('plugins', 'foo-one')
self.assertEqual(returned, TEST_CONF_LIST[3][1]['plugins'])
returned = get_placeholder_conf('plugins', 'somethingfoo-one')
self.assertEqual(returned, TEST_CONF_LIST[4][1]['plugins'])


def test_placeholder_context_leaking(self):
TEST_CONF = {'test': {'extra_context': {'extra_width': 10}}}
Expand Down
36 changes: 36 additions & 0 deletions cms/tests/test_plugins.py
Expand Up @@ -219,6 +219,42 @@ def test_plugin_add_form_integrity(self):
FilteredSelectMultiple,
)

def test_not_add_plugin(self):
"""
Test that you can't add a text plugin
"""

CMS_PLACEHOLDER_CONF = {
'body': {
'excluded plugins': ['TextPlugin']
}
}

# try to add a new text plugin
with self.settings(CMS_PLACEHOLDER_CONF=CMS_PLACEHOLDER_CONF):
page_data = self.get_new_page_data()
self.client.post(URL_CMS_PAGE_ADD, page_data)
page = Page.objects.all()[0]
installed_plugins = plugin_pool.get_all_plugins('body', page)
installed_plugins = [cls.__name__ for cls in installed_plugins]
self.assertNotIn('TextPlugin', installed_plugins)

CMS_PLACEHOLDER_CONF = {
'body': {
'plugins': ['TextPlugin'],
'excluded plugins': ['TextPlugin']
}
}

# try to add a new text plugin
with self.settings(CMS_PLACEHOLDER_CONF=CMS_PLACEHOLDER_CONF):
page_data = self.get_new_page_data()
self.client.post(URL_CMS_PAGE_ADD, page_data)
page = Page.objects.all()[0]
installed_plugins = plugin_pool.get_all_plugins('body', page)
installed_plugins = [cls.__name__ for cls in installed_plugins]
self.assertNotIn('TextPlugin', installed_plugins)

def test_plugin_edit_marks_page_dirty(self):
page_data = self.get_new_page_data()
response = self.client.post(URL_CMS_PAGE_ADD, page_data)
Expand Down
8 changes: 8 additions & 0 deletions cms/utils/conf.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from collections import OrderedDict
from functools import update_wrapper
import os

Expand Down Expand Up @@ -254,6 +255,12 @@ def get_unihandecode_host():
return host + '/'


def get_placeholder_config():
name = 'PLACEHOLDER_CONF'
placeholder_conf = getattr(settings, 'CMS_%s' % name, DEFAULTS[name])
return OrderedDict(placeholder_conf)


COMPLEX = {
'CACHE_DURATIONS': get_cache_durations,
'MEDIA_ROOT': get_media_root,
Expand All @@ -266,6 +273,7 @@ def get_unihandecode_host():
'CMS_TOOLBAR_URL__EDIT_OFF': get_toolbar_url__edit_off,
'CMS_TOOLBAR_URL__BUILD': get_toolbar_url__build,
'CMS_TOOLBAR_URL__DISABLE': get_toolbar_url__disable,
'PLACEHOLDER_CONF': get_placeholder_config
}

DEPRECATED_CMS_SETTINGS = {
Expand Down
71 changes: 54 additions & 17 deletions cms/utils/placeholder.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import operator
import re
import warnings

from django.conf import settings
Expand All @@ -11,6 +12,7 @@
from django.template.loader_tags import BlockNode, ExtendsNode, IncludeNode
from django.utils import six
from django.utils.encoding import force_text
from django.utils.six import iteritems

from sekizai.helpers import get_varname, is_variable_extend_node

Expand Down Expand Up @@ -46,30 +48,65 @@ def get_placeholder_conf(setting, placeholder, template=None, default=None):
CMS_PLACEHOLDER_CONF['placeholder']
CMS_PLACEHOLDER_CONF['template placeholder'] (if template is given)
"""
# Ideas:
# 1)using real regex as keys
# 2)turn the setting in an orderedict
# 3)handling dictionary and list both

# Use regex or normal string (in this case exact match)
# compatibility with old structure
# convert all to orderedict

if placeholder:
keys = []
placeholder_conf = get_cms_setting('PLACEHOLDER_CONF')
# 1st level
if template:
keys.append("%s %s" % (template, placeholder))
keys.append(placeholder)
# 2nd level
keys.append(str(placeholder))
# 3rd level
if template:
keys.append(template)
keys.append(str(template))
# 4th level
keys.append('*')
for key in keys:
conf = get_cms_setting('PLACEHOLDER_CONF').get(key)
if not conf:
continue
value = conf.get(setting)
if value is not None:
return value
inherit = conf.get('inherit')
if inherit:
if ' ' in inherit:
inherit = inherit.split(' ')
else:
inherit = (None, inherit,)
value = get_placeholder_conf(setting, inherit[1], inherit[0], default)
if value is not None:
return value
for regex, conf in iteritems(placeholder_conf):
if key == regex:
if not conf:
continue
value = conf.get(setting)
if value is not None:
return value
inherit = conf.get('inherit')
if inherit:
if ' ' in inherit:
inherit = inherit.split(' ')
else:
inherit = (None, inherit,)
value = get_placeholder_conf(setting, inherit[1], inherit[0], default)
if value is not None:
return value
# turn placeholder confs keys into real regular expressions
for key in keys:
# turn them in real regex string
for regex, conf in iteritems(placeholder_conf):
compiled_regex = re.compile(regex)
if compiled_regex.match(key):
if not conf:
continue
value = conf.get(setting)
if value is not None:
return value
inherit = conf.get('inherit')
if inherit:
if ' ' in inherit:
inherit = inherit.split(' ')
else:
inherit = (None, inherit,)
value = get_placeholder_conf(setting, inherit[1], inherit[0], default)
if value is not None:
return value
return default


Expand Down

0 comments on commit ff85155

Please sign in to comment.