Skip to content

Commit

Permalink
Merge pull request #4957 from yakky/merge/3.1.5.pre4
Browse files Browse the repository at this point in the history
Forwardport 3.1.x to 3.2.x
  • Loading branch information
yakky committed Jan 26, 2016
2 parents a1ca379 + 5f77abb commit a069f75
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 101 deletions.
2 changes: 0 additions & 2 deletions cms/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,3 @@ class CMSConfig(AppConfig):

def ready(self):
setup()
from cms.plugin_pool import plugin_pool
plugin_pool.set_plugin_meta()
101 changes: 57 additions & 44 deletions cms/plugin_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,61 +37,74 @@ def clear(self):
self.plugins = {}
self.patched = False

def validate_templates(self, plugin=None):
"""
Plugins templates are validated at this stage
"""
if plugin:
plugins = [plugin]
else:
plugins = self.plugins.values()
for plugin in plugins:
if (plugin.render_plugin and not type(plugin.render_plugin) == property
or hasattr(plugin.model, 'render_template')
or hasattr(plugin, 'get_render_template')):
if (plugin.render_template is None and
not hasattr(plugin.model, 'render_template') and
not hasattr(plugin, 'get_render_template')):
raise ImproperlyConfigured(
"CMS Plugins must define a render template, "
"a get_render_template method or "
"set render_plugin=False: %s" % plugin
)
# If plugin class defines get_render_template we cannot
# statically check for valid template file as it depends
# on plugin configuration and context.
# We cannot prevent developer to shoot in the users' feet
elif not hasattr(plugin, 'get_render_template'):
from django.template import loader

template = ((hasattr(plugin.model, 'render_template') and
plugin.model.render_template) or
plugin.render_template)
if isinstance(template, six.string_types) and template:
try:
loader.get_template(template)
except TemplateDoesNotExist as e:
# Note that the template loader will throw
# TemplateDoesNotExist if the plugin's render_template
# does in fact exist, but it includes a template that
# doesn't.
if six.text_type(e) == template:
raise ImproperlyConfigured(
"CMS Plugins must define a render template (%s) that exists: %s"
% (plugin, template)
)
else:
pass
except TemplateSyntaxError:
pass
else:
if plugin.allow_children:
raise ImproperlyConfigured(
"CMS Plugins can not define render_plugin=False and allow_children=True: %s"
% plugin
)

def register_plugin(self, plugin):
"""
Registers the given plugin(s).
Static sanity checks is also performed.
If a plugin is already registered, this will raise PluginAlreadyRegistered.
"""
if not issubclass(plugin, CMSPluginBase):
raise ImproperlyConfigured(
"CMS Plugins must be subclasses of CMSPluginBase, %r is not."
% plugin
)
if (plugin.render_plugin and not type(plugin.render_plugin) == property
or hasattr(plugin.model, 'render_template')
or hasattr(plugin, 'get_render_template')):
if (plugin.render_template is None and
not hasattr(plugin.model, 'render_template') and
not hasattr(plugin, 'get_render_template')):
raise ImproperlyConfigured(
"CMS Plugins must define a render template, "
"a get_render_template method or "
"set render_plugin=False: %s" % plugin
)
# If plugin class defines get_render_template we cannot
# statically check for valid template file as it depends
# on plugin configuration and context.
# We cannot prevent developer to shoot in the users' feet
elif not hasattr(plugin, 'get_render_template'):
from django.template import loader

template = ((hasattr(plugin.model, 'render_template') and
plugin.model.render_template) or
plugin.render_template)
if isinstance(template, six.string_types) and template:
try:
loader.get_template(template)
except TemplateDoesNotExist as e:
# Note that the template loader will throw
# TemplateDoesNotExist if the plugin's render_template
# does in fact exist, but it includes a template that
# doesn't.
if six.text_type(e) == template:
raise ImproperlyConfigured(
"CMS Plugins must define a render template (%s) that exists: %s"
% (plugin, template)
)
else:
pass
except TemplateSyntaxError:
pass
else:
if plugin.allow_children:
raise ImproperlyConfigured(
"CMS Plugins can not define render_plugin=False and allow_children=True: %s"
% plugin
)
plugin_name = plugin.__name__
if plugin_name in self.plugins:
raise PluginAlreadyRegistered(
Expand Down
38 changes: 38 additions & 0 deletions cms/tests/test_no_i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
from django.contrib.auth import get_user_model
from django.core.urlresolvers import clear_url_caches
from django.template import Template
from django.test import RequestFactory
from django.test.utils import override_settings

from djangocms_text_ckeditor.models import Text

from cms.api import create_page
from cms.middleware.toolbar import ToolbarMiddleware
from cms.models import Page, CMSPlugin
from cms.test_utils.testcases import (CMSTestCase,
URL_CMS_PAGE_ADD, URL_CMS_PLUGIN_EDIT,
URL_CMS_PLUGIN_ADD,
URL_CMS_PAGE_CHANGE_TEMPLATE)
from cms.toolbar.toolbar import CMSToolbar
from cms.utils import get_cms_setting


@override_settings(
Expand Down Expand Up @@ -49,8 +54,30 @@ def setUp(self):
super(TestNoI18N, self).setUp()

def tearDown(self):
super(TestNoI18N, self).tearDown()
clear_url_caches()

def get_page_request(self, page, user, path=None, edit=False, lang_code='en', disable=False):
path = path or page and page.get_absolute_url()
if edit:
path += '?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')
request = RequestFactory().get(path)
request.session = {}
request.user = user
request.LANGUAGE_CODE = lang_code
if edit:
request.GET = {'edit': None}
else:
request.GET = {'edit_off': None}
if disable:
request.GET[get_cms_setting('CMS_TOOLBAR_URL__DISABLE')] = None
request.current_page = page
mid = ToolbarMiddleware()
mid.process_request(request)
if hasattr(request, 'toolbar'):
request.toolbar.populate()
return request

def test_language_chooser(self):
# test simple language chooser with default args
create_page("home", template="col_two.html", language="en-us", published=True)
Expand Down Expand Up @@ -151,3 +178,14 @@ def test_plugin_add_edit(self):
self.assertEqual(response.status_code, 200)
txt = Text.objects.all()[0]
self.assertEqual("Hello World", txt.body)

def test_toolbar_no_locale(self):
page = create_page('test', 'nav_playground.html', 'en-us', published=True)
sub = create_page('sub', 'nav_playground.html', 'en-us', published=True, parent=page)
# loads the urlconf before reverse below
sub.get_absolute_url('en-us')
request = self.get_page_request(sub, self.get_superuser(), edit=True)
del request.LANGUAGE_CODE
toolbar = CMSToolbar(request)
toolbar.set_object(sub)
self.assertEqual(toolbar.get_object_public_url(), '/sub/')
66 changes: 33 additions & 33 deletions cms/tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,10 +605,10 @@ def test_deep_copy_plugins(self):
page_en.publish('en')

def test_plugin_validation(self):
self.assertRaises(ImproperlyConfigured, plugin_pool.register_plugin, NonExisitngRenderTemplate)
self.assertRaises(ImproperlyConfigured, plugin_pool.register_plugin, NoRender)
self.assertRaises(ImproperlyConfigured, plugin_pool.register_plugin, NoRenderButChildren)
plugin_pool.register_plugin(DynTemplate)
self.assertRaises(ImproperlyConfigured, plugin_pool.validate_templates, NonExisitngRenderTemplate)
self.assertRaises(ImproperlyConfigured, plugin_pool.validate_templates, NoRender)
self.assertRaises(ImproperlyConfigured, plugin_pool.validate_templates, NoRenderButChildren)
plugin_pool.validate_templates(DynTemplate)

def test_remove_plugin_before_published(self):
"""
Expand Down Expand Up @@ -758,8 +758,8 @@ def test_inheritplugin_media(self):
"""

inheritfrompage = api.create_page('page to inherit from',
'nav_playground.html',
'en')
'nav_playground.html',
'en')

body = inheritfrompage.placeholders.get(slot="body")

Expand All @@ -776,9 +776,9 @@ def test_inheritplugin_media(self):
inheritfrompage.publish('en')

page = api.create_page('inherit from page',
'nav_playground.html',
'en',
published=True)
'nav_playground.html',
'en',
published=True)

inherited_body = page.placeholders.get(slot="body")

Expand All @@ -800,8 +800,8 @@ def test_inheritplugin_media(self):

def test_inherit_plugin_with_empty_plugin(self):
inheritfrompage = api.create_page('page to inherit from',
'nav_playground.html',
'en', published=True)
'nav_playground.html',
'en', published=True)

body = inheritfrompage.placeholders.get(slot="body")
empty_plugin = CMSPlugin(
Expand All @@ -815,7 +815,7 @@ def test_inherit_plugin_with_empty_plugin(self):
inherited_body = other_page.placeholders.get(slot="body")

api.add_plugin(inherited_body, InheritPagePlaceholderPlugin, 'en', position='last-child',
from_page=inheritfrompage, from_language='en')
from_page=inheritfrompage, from_language='en')

api.add_plugin(inherited_body, "TextPlugin", "en", body="foobar")
# this should not fail, even if there in an empty plugin
Expand All @@ -831,9 +831,9 @@ def test_render_textplugin(self):
for i in range(0, 10):
text_plugin = Text.objects.get(pk=text_plugin.pk)
link_plugins.append(api.add_plugin(ph, "LinkPlugin", "en",
target=text_plugin,
name="A Link %d" % i,
url="http://django-cms.org"))
target=text_plugin,
name="A Link %d" % i,
url="http://django-cms.org"))
text_plugin.text.body += '<img src="/static/cms/img/icons/plugins/link.png" alt="Link - %s" id="plugin_obj_%d" title="Link - %s" />' % (
link_plugins[-1].name,
link_plugins[-1].pk,
Expand Down Expand Up @@ -1052,7 +1052,7 @@ def test_moving_plugin_to_different_placeholder(self):

def test_get_plugins_for_page(self):
page_en = api.create_page("PluginOrderPage", "col_two.html", "en",
slug="page1", published=True, in_navigation=True)
slug="page1", published=True, in_navigation=True)
ph_en = page_en.placeholders.get(slot="col_left")
text_plugin_1 = api.add_plugin(ph_en, "TextPlugin", "en", body="I'm inside an existing placeholder.")
# This placeholder is not in the template.
Expand Down Expand Up @@ -1213,13 +1213,13 @@ def test_plugin_parent_classes(self):
toolbar plugin struct for those given parent Plugins
"""
ParentClassesPlugin = type('ParentClassesPlugin', (CMSPluginBase,),
dict(parent_classes=['GenericParentPlugin'], render_plugin=False))
dict(parent_classes=['GenericParentPlugin'], render_plugin=False))
GenericParentPlugin = type('GenericParentPlugin', (CMSPluginBase,), {'render_plugin':False})
KidnapperPlugin = type('KidnapperPlugin', (CMSPluginBase,), {'render_plugin':False})

expected_struct = {'module': u'Generic',
'name': u'Parent Classes Plugin',
'value': 'ParentClassesPlugin'}
'name': u'Parent Classes Plugin',
'value': 'ParentClassesPlugin'}

for plugin in [ParentClassesPlugin, GenericParentPlugin, KidnapperPlugin]:
plugin_pool.register_plugin(plugin)
Expand All @@ -1229,23 +1229,23 @@ def test_plugin_parent_classes(self):

from cms.utils.placeholder import get_toolbar_plugin_struct
toolbar_struct = get_toolbar_plugin_struct([ParentClassesPlugin],
placeholder.slot,
page,
parent=GenericParentPlugin)
placeholder.slot,
page,
parent=GenericParentPlugin)
self.assertTrue(expected_struct in toolbar_struct)

toolbar_struct = get_toolbar_plugin_struct([ParentClassesPlugin],
placeholder.slot,
page,
parent=KidnapperPlugin)
placeholder.slot,
page,
parent=KidnapperPlugin)
self.assertFalse(expected_struct in toolbar_struct)

toolbar_struct = get_toolbar_plugin_struct([ParentClassesPlugin, GenericParentPlugin],
placeholder.slot,
page)
placeholder.slot,
page)
expected_struct = {'module': u'Generic',
'name': u'Generic Parent Plugin',
'value': 'GenericParentPlugin'}
'name': u'Generic Parent Plugin',
'value': 'GenericParentPlugin'}
self.assertTrue(expected_struct in toolbar_struct)
for plugin in [ParentClassesPlugin, GenericParentPlugin, KidnapperPlugin]:
plugin_pool.unregister_plugin(plugin)
Expand All @@ -1254,7 +1254,7 @@ def test_plugin_child_classes_from_settings(self):
page = api.create_page("page", "nav_playground.html", "en", published=True)
placeholder = page.placeholders.get(slot='body')
ChildClassesPlugin = type('ChildClassesPlugin', (CMSPluginBase,),
dict(child_classes=['TextPlugin'], render_template='allow_children_plugin.html'))
dict(child_classes=['TextPlugin'], render_template='allow_children_plugin.html'))
plugin_pool.register_plugin(ChildClassesPlugin)
plugin = api.add_plugin(placeholder, ChildClassesPlugin, settings.LANGUAGES[0][0])
plugin = plugin.get_plugin_class_instance()
Expand All @@ -1270,14 +1270,14 @@ def test_plugin_child_classes_from_settings(self):
}
with self.settings(CMS_PLACEHOLDER_CONF=CMS_PLACEHOLDER_CONF):
self.assertEqual(['LinkPlugin', 'PicturePlugin'],
plugin.get_child_classes(placeholder.slot, page))
plugin.get_child_classes(placeholder.slot, page))
plugin_pool.unregister_plugin(ChildClassesPlugin)

def test_plugin_parent_classes_from_settings(self):
page = api.create_page("page", "nav_playground.html", "en", published=True)
placeholder = page.placeholders.get(slot='body')
ParentClassesPlugin = type('ParentClassesPlugin', (CMSPluginBase,),
dict(parent_classes=['TextPlugin'], render_plugin=False))
dict(parent_classes=['TextPlugin'], render_plugin=False))
plugin_pool.register_plugin(ParentClassesPlugin)
plugin = api.add_plugin(placeholder, ParentClassesPlugin, settings.LANGUAGES[0][0])
plugin = plugin.get_plugin_class_instance()
Expand All @@ -1293,7 +1293,7 @@ def test_plugin_parent_classes_from_settings(self):
}
with self.settings(CMS_PLACEHOLDER_CONF=CMS_PLACEHOLDER_CONF):
self.assertEqual(['TestPlugin'],
plugin.get_parent_classes(placeholder.slot, page))
plugin.get_parent_classes(placeholder.slot, page))
plugin_pool.unregister_plugin(ParentClassesPlugin)

def test_plugin_translatable_content_getter_setter(self):
Expand Down
4 changes: 2 additions & 2 deletions cms/toolbar/toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def get_object_pk(self):

def get_object_public_url(self):
if self.obj:
with force_language(self.request.LANGUAGE_CODE):
with force_language(self.language):
try:
return self.obj.get_public_url()
except:
Expand All @@ -241,7 +241,7 @@ def get_object_public_url(self):

def get_object_draft_url(self):
if self.obj:
with force_language(self.request.LANGUAGE_CODE):
with force_language(self.language):
try:
return self.obj.get_draft_url()
except:
Expand Down
5 changes: 4 additions & 1 deletion cms/utils/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def setup():
"""
Gather all checks and validations
"""
from cms.plugin_pool import plugin_pool
if DJANGO_1_6:
# While setup is called both in all the Django versions only 1.6-
# requires paching the AppCache. 1.7 provides a cleaner way to handle
Expand All @@ -53,10 +54,12 @@ def setup():

def get_models_patched(self, **kwargs):
ret_value = old_get_models(self, **kwargs)
from cms.plugin_pool import plugin_pool
plugin_pool.set_plugin_meta()
return ret_value

loading.AppCache.get_models = get_models_patched
else:
plugin_pool.set_plugin_meta()
validate_dependencies()
validate_settings()
plugin_pool.validate_templates()
Loading

0 comments on commit a069f75

Please sign in to comment.