diff --git a/cms/plugin_rendering.py b/cms/plugin_rendering.py index 4213b1cc312..2a7e34ea7aa 100644 --- a/cms/plugin_rendering.py +++ b/cms/plugin_rendering.py @@ -10,6 +10,7 @@ from django.template.defaultfilters import title from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ +from django.utils.safestring import mark_safe # these are always called before all other plugin context processors DEFAULT_PLUGIN_CONTEXT_PROCESSORS = ( @@ -81,6 +82,11 @@ def render_plugins(plugins, context, placeholder, processors=None): context.pop() return out + +def render_dragables(plugins): + return render_to_string("cms/toolbar/placeholder_dragables.html", {'plugins':plugins}) + + def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder"): """ Renders plugins for a placeholder on the given page using shallow copies of the @@ -108,7 +114,7 @@ def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder" if not key in context: context[key] = value - content = [] + # Prepend frontedit toolbar output if applicable edit = False @@ -122,15 +128,20 @@ def render_placeholder(placeholder, context_to_copy, name_fallback="Placeholder" processors = (toolbar_plugin_processor,) else: processors = None - + content = [] content.extend(render_plugins(plugins, context, placeholder, processors)) - content = "".join(content) + toolbar_content = '' + dragables_content = '' if edit: - content = render_placeholder_toolbar(placeholder, context, content, name_fallback) + toolbar_content = mark_safe(render_placeholder_toolbar(placeholder, context, name_fallback)) + dragables_content = mark_safe(render_dragables(plugins)) + content = mark_safe("".join(content)) + + result = render_to_string("cms/toolbar/placeholder.html", {'plugins':content, "toolbar":toolbar_content, "dragables":dragables_content, 'edit':edit}) context.pop() - return content + return result -def render_placeholder_toolbar(placeholder, context, content, name_fallback=None): +def render_placeholder_toolbar(placeholder, context, name_fallback=None): from cms.plugin_pool import plugin_pool request = context['request'] page = placeholder.page if placeholder else None @@ -158,6 +169,6 @@ def render_placeholder_toolbar(placeholder, context, content, name_fallback=None context['placeholder_label'] = name context['placeholder'] = placeholder context['page'] = page - toolbar = render_to_string("cms/toolbar/placeholder.html", context) + toolbar = render_to_string("cms/toolbar/placeholder_toolbar.html", context) context.pop() - return "".join([toolbar, content]) + return toolbar diff --git a/cms/static/cms/js/plugins/cms.placeholders.js b/cms/static/cms/js/plugins/cms.placeholders.js index fefca4e23e3..4d0e946f5dc 100644 --- a/cms/static/cms/js/plugins/cms.placeholders.js +++ b/cms/static/cms/js/plugins/cms.placeholders.js @@ -152,10 +152,12 @@ $(document).ready(function () { 'stop': function (event, ui) { // TODO this needs refactoring, first should be ALL placeholders than all dragitems within a list // TODO otherwise this wont work + //var dragitem = ui.item; //plugin.insertBefore(dragitem); + // TODO we need some ajax checking before actually replacing // TODO we might also need some loading indication @@ -460,4 +462,4 @@ $(document).ready(function () { 'move_plugin': '' } } - */ \ No newline at end of file + */ diff --git a/cms/templates/cms/toolbar/items/plugin_drag.html b/cms/templates/cms/toolbar/items/plugin_drag.html new file mode 100644 index 00000000000..155a0e749f9 --- /dev/null +++ b/cms/templates/cms/toolbar/items/plugin_drag.html @@ -0,0 +1,22 @@ + +
+
+
+ {% trans "Settings" %} + Copy + Delete + {% for class, name in child_plugin_classes %} + {% if forloop.first %}{% trans "Add Plugin" %}{% endif %} + + {{ name }} + {% endfor %} +
+
{{ instance.plugin_type }} {{ instance.placeholder.slot }}
+ {% if plugin.get_plugin_class.allow_children and plugin.plugin_children_instances %} + {% for child in plugin.plugin_children_instances %} + {# workaround because include tag does not allow recursive includes #} + {% with template_name="cms/toolbar/items/plugin_drag.html" %}{% include template_name %}{% endwith %} + + {% endfor %} + {% endif %} +
diff --git a/cms/templates/cms/toolbar/placeholder.html b/cms/templates/cms/toolbar/placeholder.html index f2fb7b0607d..d5539f419a6 100644 --- a/cms/templates/cms/toolbar/placeholder.html +++ b/cms/templates/cms/toolbar/placeholder.html @@ -1,33 +1,9 @@ -{% load i18n sekizai_tags %} -{% addtoblock "js" %} - -{% endaddtoblock %} -
-
{{ placeholder_label }}
-
- {% trans "Add Plugin" %} - -
+{% if edit %} +{{ toolbar }} +
+ {{ plugins }} + {{ dragables }}
-
Drop a plugin here
\ No newline at end of file +{% else %} +{{ plugins }} +{% endif %} diff --git a/cms/templates/cms/toolbar/placeholder_dragables.html b/cms/templates/cms/toolbar/placeholder_dragables.html new file mode 100644 index 00000000000..0bb89db6829 --- /dev/null +++ b/cms/templates/cms/toolbar/placeholder_dragables.html @@ -0,0 +1,3 @@ +{% for plugin in plugins %} + {% include "cms/toolbar/items/plugin_drag.html" with plugin=plugin %} +{% endfor %} diff --git a/cms/templates/cms/toolbar/placeholder_toolbar.html b/cms/templates/cms/toolbar/placeholder_toolbar.html new file mode 100644 index 00000000000..bd5778f016f --- /dev/null +++ b/cms/templates/cms/toolbar/placeholder_toolbar.html @@ -0,0 +1,33 @@ +{% load i18n sekizai_tags %} +{% addtoblock "js" %} + +{% endaddtoblock %} +
+
{{ placeholder_label }}
+
+ {% trans "Add Plugin" %} +
    + {% regroup installed_plugins by module as module_list %} + {% for module in module_list %} +
  • {% if module.grouper %}{{ module.grouper|capfirst }}{% else %}{% trans "Available plugins" %}{% endif %}
  • + {% for p in module.list %} +
  • {{ p.name }}
  • + {% endfor %} + {% endfor %} +
+
+
+
Drop a plugin here
diff --git a/cms/templates/cms/toolbar/placeholder_wrapper.html b/cms/templates/cms/toolbar/placeholder_wrapper.html index e47b4988069..80e6198eedf 100644 --- a/cms/templates/cms/toolbar/placeholder_wrapper.html +++ b/cms/templates/cms/toolbar/placeholder_wrapper.html @@ -26,24 +26,4 @@ {% endaddtoblock %} -{% if not instance.parent %}
{{ rendered_content }}
{% endif %} -
-
-
- {% trans "Settings" %} - Copy - Delete - {% for class, name in child_plugin_classes %} - {% if forloop.first %}{% trans "Add Plugin" %}{% endif %} - - {{ name }} - {% endfor %} -
-
{{ instance.plugin_type }} {{ instance.placeholder.slot }}
- {% if instance.get_plugin_class.allow_children and instance.plugion_children %} - {% for plugin in instance.plugin_children %} - {% render_plugin plugin %} - {% endfor %} - {% endif %} -
- +
{{ rendered_content }}
diff --git a/cms/tests/rendering.py b/cms/tests/rendering.py index 25d690d01fb..f4c29b41a22 100644 --- a/cms/tests/rendering.py +++ b/cms/tests/rendering.py @@ -4,7 +4,7 @@ from cms.api import create_page, add_plugin from cms.models.placeholdermodel import Placeholder from cms.models.pluginmodel import CMSPlugin -from cms.plugin_rendering import (render_plugins, PluginContext, +from cms.plugin_rendering import (render_plugins, PluginContext, render_placeholder_toolbar) from cms.test_utils.testcases import SettingsOverrideTestCase from cms.test_utils.util.context_managers import SettingsOverride, ChangeModel @@ -24,12 +24,12 @@ def test_plugin_processor(instance, placeholder, rendered_content, original_cont original_context_var) def test_plugin_context_processor(instance, placeholder): - content = 'test_plugin_context_processor_ok|'+instance.body+'|'+placeholder.slot + content = 'test_plugin_context_processor_ok|' + instance.body + '|' + placeholder.slot return {'test_plugin_context_processor': content} class RenderingTestCase(SettingsOverrideTestCase): - + settings_overrides = { 'CMS_TEMPLATES': [(TEMPLATE_NAME, TEMPLATE_NAME), ('extra_context.html', 'extra_context.html')], 'CMS_MODERATOR': False, @@ -37,11 +37,11 @@ class RenderingTestCase(SettingsOverrideTestCase): def setUp(self): super(RenderingTestCase, self).setUp() - self.test_user = User(username="test", is_staff = True, is_active = True, is_superuser = True) + self.test_user = User(username="test", is_staff=True, is_active=True, is_superuser=True) self.test_user.set_password("test") self.test_user.save() with self.login_user_context(self.test_user): - + self.test_data = { 'title': u'RenderingTestCase-title', 'slug': u'renderingtestcase-slug', @@ -98,7 +98,7 @@ def insert_test_content(self): # # Insert some test Text plugins add_plugin(self.test_placeholders3['sub'], 'TextPlugin', 'en', body=self.test_data3['text_sub']) - + # Insert another page that is not the home p4 = create_page(self.test_data4['title'], 'extra_context.html', 'en', parent=p) # Placeholders have been inserted on post_save signal: @@ -106,14 +106,14 @@ def insert_test_content(self): for placeholder in p4.placeholders.all(): self.test_placeholders4[placeholder.slot] = placeholder # Insert some test plugins - add_plugin(self.test_placeholders4['extra_context'], 'ExtraContextPlugin', 'en') + add_plugin(self.test_placeholders4['extra_context'], 'ExtraContextPlugin', 'en') # Reload test pages self.test_page = self.reload(p) self.test_page2 = self.reload(p2) self.test_page3 = self.reload(p3) self.test_page4 = self.reload(p4) - + def get_context(self, page, context_vars={}): request = self.get_request(page) return RequestContext(request, context_vars) @@ -141,39 +141,39 @@ def test_details_view(self): from cms.views import details response = details(self.get_request(self.test_page), '') r = self.strip_rendered(response.content) - self.assertEqual(r, u'|'+self.test_data['text_main']+u'|'+self.test_data['text_sub']+u'|') - + self.assertEqual(r, u'|' + self.test_data['text_main'] + u'|' + self.test_data['text_sub'] + u'|') + def test_processors(self): """ Tests that default plugin context processors are working, that plugin processors and plugin context processors can be defined in settings and are working and that extra plugin context processors can be passed to PluginContext. """ with SettingsOverride( - CMS_PLUGIN_PROCESSORS = ('cms.tests.rendering.test_plugin_processor',), - CMS_PLUGIN_CONTEXT_PROCESSORS = ('cms.tests.rendering.test_plugin_context_processor',), + CMS_PLUGIN_PROCESSORS=('cms.tests.rendering.test_plugin_processor',), + CMS_PLUGIN_CONTEXT_PROCESSORS=('cms.tests.rendering.test_plugin_context_processor',), ): def test_passed_plugin_context_processor(instance, placeholder): return {'test_passed_plugin_context_processor': 'test_passed_plugin_context_processor_ok'} - t = u'{% load cms_tags %}'+ \ + t = u'{% load cms_tags %}' + \ u'{{ plugin.counter }}|{{ plugin.instance.body }}|{{ test_passed_plugin_context_processor }}|{{ test_plugin_context_processor }}' instance, plugin = CMSPlugin.objects.all()[0].get_plugin_instance() instance.render_template = Template(t) context = PluginContext({'original_context_var': 'original_context_var_ok'}, instance, self.test_placeholders['main'], processors=(test_passed_plugin_context_processor,)) plugin_rendering._standard_processors = {} c = render_plugins((instance,), context, self.test_placeholders['main']) - r = "".join(c) - self.assertEqual(r, u'1|'+self.test_data['text_main']+'|test_passed_plugin_context_processor_ok|test_plugin_context_processor_ok|'+self.test_data['text_main']+'|main|test_plugin_processor_ok|'+self.test_data['text_main']+'|main|original_context_var_ok') + r = "".join(c) + self.assertEqual(r, u'1|' + self.test_data['text_main'] + '|test_passed_plugin_context_processor_ok|test_plugin_context_processor_ok|' + self.test_data['text_main'] + '|main|test_plugin_processor_ok|' + self.test_data['text_main'] + '|main|original_context_var_ok') plugin_rendering._standard_processors = {} - + def test_placeholder(self): """ Tests the {% placeholder %} templatetag. """ - t = u'{% load cms_tags %}'+ \ + t = u'{% load cms_tags %}' + \ u'|{% placeholder "main" %}|{% placeholder "empty" %}' r = self.render(t, self.test_page) - self.assertEqual(r, u'|'+self.test_data['text_main']+'|') - + self.assertEqual(r, u'|' + self.test_data['text_main'] + '|') + def test_placeholder_extra_context(self): t = u'{% load cms_tags %}{% placeholder "extra_context" %}' @@ -187,7 +187,7 @@ def test_placeholderor(self): """ Tests the {% placeholder %} templatetag. """ - t = u'{% load cms_tags %}'+ \ + t = u'{% load cms_tags %}' + \ u'|{% placeholder "empty" or %}No content{% endplaceholder %}' r = self.render(t, self.test_page) self.assertEqual(r, u'|No content') @@ -196,22 +196,22 @@ def test_show_placeholder(self): """ Tests the {% show_placeholder %} templatetag, using lookup by pk/dict/reverse_id and passing a Page object. """ - t = u'{% load cms_tags %}'+ \ - u'|{% show_placeholder "main" '+str(self.test_page.pk)+' %}'+ \ - u'|{% show_placeholder "main" test_dict %}'+ \ - u'|{% show_placeholder "sub" "'+str(self.test_page.reverse_id)+'" %}'+ \ + t = u'{% load cms_tags %}' + \ + u'|{% show_placeholder "main" ' + str(self.test_page.pk) + ' %}' + \ + u'|{% show_placeholder "main" test_dict %}' + \ + u'|{% show_placeholder "sub" "' + str(self.test_page.reverse_id) + '" %}' + \ u'|{% show_placeholder "sub" test_page %}' r = self.render(t, self.test_page, {'test_page': self.test_page, 'test_dict': {'pk': self.test_page.pk}}) - self.assertEqual(r, (u'|'+self.test_data['text_main'])*2+(u'|'+self.test_data['text_sub'])*2) - + self.assertEqual(r, (u'|' + self.test_data['text_main']) * 2 + (u'|' + self.test_data['text_sub']) * 2) + def test_show_placeholder_extra_context(self): - t = u'{% load cms_tags %}{% show_placeholder "extra_context" '+str(self.test_page4.pk)+' %}' + t = u'{% load cms_tags %}{% show_placeholder "extra_context" ' + str(self.test_page4.pk) + ' %}' r = self.render(t, self.test_page4) self.assertEqual(r, self.test_data4['no_extra']) with SettingsOverride(CMS_PLACEHOLDER_CONF=self.test_data4['placeholderconf']): r = self.render(t, self.test_page4) self.assertEqual(r, self.test_data4['extra']) - + def test_show_uncached_placeholder_by_pk(self): """ Tests the {% show_uncached_placeholder %} templatetag, using lookup by pk. @@ -234,27 +234,27 @@ def test_show_uncached_placeholder_by_page(self): template = u'{% load cms_tags %}{% show_uncached_placeholder "sub" test_page %}' output = self.render(template, self.test_page, {'test_page': self.test_page}) self.assertEqual(output, self.test_data['text_sub']) - + def test_page_url_by_pk(self): template = u'{%% load cms_tags %%}{%% page_url %s %%}' % self.test_page2.pk output = self.render(template, self.test_page) self.assertEqual(output, self.test_page2.get_absolute_url()) - + def test_page_url_by_dictionary(self): template = u'{% load cms_tags %}{% page_url test_dict %}' - output = self.render(template, self.test_page, {'test_dict': {'pk': self.test_page2.pk}}) + output = self.render(template, self.test_page, {'test_dict': {'pk': self.test_page2.pk}}) self.assertEqual(output, self.test_page2.get_absolute_url()) - + def test_page_url_by_reverse_id(self): template = u'{%% load cms_tags %%}{%% page_url "%s" %%}' % self.test_page2.reverse_id output = self.render(template, self.test_page) self.assertEqual(output, self.test_page2.get_absolute_url()) - + def test_page_url_by_reverse_id_not_on_a_page(self): template = u'{%% load cms_tags %%}{%% page_url "%s" %%}' % self.test_page2.reverse_id output = self.render(template, None) self.assertEqual(output, self.test_page2.get_absolute_url()) - + def test_page_url_by_page(self): template = u'{% load cms_tags %}{% page_url test_page %}' output = self.render(template, self.test_page, {'test_page': self.test_page2}) @@ -264,30 +264,30 @@ def test_page_attribute(self): """ Tests the {% page_attribute %} templatetag, using current page, lookup by pk/dict/reverse_id and passing a Page object. """ - t = u'{% load cms_tags %}'+ \ - u'|{% page_attribute title %}'+ \ - u'{% page_attribute title as title %}'+ \ - u'|{{ title }}'+ \ - u'|{% page_attribute title '+str(self.test_page2.pk)+' %}'+ \ - u'{% page_attribute title '+str(self.test_page2.pk)+' as title %}'+ \ - u'|{{ title }}'+ \ - u'|{% page_attribute title test_dict %}'+ \ - u'{% page_attribute title test_dict as title %}'+ \ - u'|{{ title }}'+ \ - u'|{% page_attribute slug "'+str(self.test_page2.reverse_id)+'" %}'+ \ - u'{% page_attribute slug "'+str(self.test_page2.reverse_id)+'" as slug %}'+ \ - u'|{{ slug }}'+ \ - u'|{% page_attribute slug test_page %}'+ \ - u'{% page_attribute slug test_page as slug %}'+ \ + t = u'{% load cms_tags %}' + \ + u'|{% page_attribute title %}' + \ + u'{% page_attribute title as title %}' + \ + u'|{{ title }}' + \ + u'|{% page_attribute title ' + str(self.test_page2.pk) + ' %}' + \ + u'{% page_attribute title ' + str(self.test_page2.pk) + ' as title %}' + \ + u'|{{ title }}' + \ + u'|{% page_attribute title test_dict %}' + \ + u'{% page_attribute title test_dict as title %}' + \ + u'|{{ title }}' + \ + u'|{% page_attribute slug "' + str(self.test_page2.reverse_id) + '" %}' + \ + u'{% page_attribute slug "' + str(self.test_page2.reverse_id) + '" as slug %}' + \ + u'|{{ slug }}' + \ + u'|{% page_attribute slug test_page %}' + \ + u'{% page_attribute slug test_page as slug %}' + \ u'|{{ slug }}' r = self.render(t, self.test_page, {'test_page': self.test_page2, 'test_dict': {'pk': self.test_page2.pk}}) - self.assertEqual(r, (u'|'+self.test_data['title'])*2+(u'|'+self.test_data2['title'])*4+(u'|'+self.test_data2['slug'])*4) + self.assertEqual(r, (u'|' + self.test_data['title']) * 2 + (u'|' + self.test_data2['title']) * 4 + (u'|' + self.test_data2['slug']) * 4) def test_inherit_placeholder(self): - t = u'{% load cms_tags %}'+ \ + t = u'{% load cms_tags %}' + \ u'|{% placeholder "main" inherit %}|{% placeholder "sub" %}' r = self.render(t, self.test_page3) - self.assertEqual(r, u'|'+self.test_data['text_main']+'|'+self.test_data3['text_sub']) + self.assertEqual(r, u'|' + self.test_data['text_main'] + '|' + self.test_data3['text_sub']) def test_extra_context_isolation(self): with ChangeModel(self.test_page, template='extra_context.html'): @@ -312,14 +312,14 @@ def test_render_placeholder_toolbar(self): "cms_placeholder-bar-%s" % placeholder.pk, "cms_placeholder_slot::test", ] - output = render_placeholder_toolbar(placeholder, context, '', 'test') + output = render_placeholder_toolbar(placeholder, context, 'test') for cls in classes: self.assertTrue(cls in output, '%r is not in %r' % (cls, output)) def test_placeholder_name_toolbar(self): placeholder_conf_name = 'test_placeholder' placeholder_conf_tag = '
%s
' % placeholder_conf_name - with SettingsOverride(CMS_PLACEHOLDER_CONF = { + with SettingsOverride(CMS_PLACEHOLDER_CONF={ 'test': {'name':placeholder_conf_name} }): placeholder = Placeholder()