Repository: django-cms/django-cms

Issue:
show_editable_model template tag filters only applied in edit mode
As per the docs for the show_editable_model template tag:

"filters (optional): a string containing chained filters to apply to the output content; works the same way as filter templatetag;"

but in use, something like:

{% show_editable_model object "field" None None "upper" %}

will only apply the 'upper' template filter when the page loads in edit mode - when the page is loaded outside of edit mode, the filter is not applied.

I think it has to do with the 2 different templates used to render content generated with the show_editable_model template tag.

When in edit mode, the template 'cms/toolbar/plugin.html' is rendered, which prints the content using the {{ rendered_content }} context variable,

but when not in edit mode, the template 'cms/toolbar/content.html' is rendered, which prints the content using a different context variable: {{ content }}

Inside the tag, the filtered data is only assigned to the 'rendered_content' context variable.



Discussion:

Resolving patch:
diff --git a/cms/templatetags/cms_tags.py b/cms/templatetags/cms_tags.py
--- a/cms/templatetags/cms_tags.py
+++ b/cms/templatetags/cms_tags.py
@@ -590,6 +590,10 @@ def render_tag(self, context, name, nodelist):
 
 
 class CMSEditableObject(InclusionTag):
+    """
+    Templatetag that links a content extracted from a generic django model
+    to the model admin changeform.
+    """
     template = 'cms/toolbar/content.html'
     edit_template = 'cms/toolbar/plugin.html'
     name = 'show_editable_model'
@@ -667,11 +671,9 @@ def get_context(self, context, instance, attribute, edit_fields, language,
                 context['content'] = context['content'](language)
             else:
                 context['content'] = context['content'](context['request'])
-        context['rendered_content'] = mark_safe(context['content'])
         if filters:
-            expression = self.parser.compile_filter("rendered_content|%s" % (filters))
-            out = expression.resolve(context)
-            context['rendered_content'] = mark_safe(out)
+            expression = self.parser.compile_filter("content|%s" % (filters))
+            context['content'] = expression.resolve(context)
         # If the toolbar is not enabled the following part is just skipped: it
         # would cause a perfomance hit for no reason
         if self._is_editable(context.get('request', None)):
@@ -702,5 +704,10 @@ def get_context(self, context, instance, attribute, edit_fields, language,
                     url_base = reverse(view_url, args=(instance.pk, language))
                     querystring['edit_fields'] = ",".join(context['edit_fields'])
             context['edit_url'] = "%s?%s" % (url_base, urlencode(querystring))
+	# content is for non-edit template content.html
+	# rendered_content is for edit template plugin.html
+	# in this templatetag both hold the same content
+        context['content'] = mark_safe(context['content'])
+        context['rendered_content'] = context['content']
         return context
-register.tag(CMSEditableObject)
\ No newline at end of file
+register.tag(CMSEditableObject)


Test patch:
diff --git a/cms/tests/toolbar.py b/cms/tests/toolbar.py
--- a/cms/tests/toolbar.py
+++ b/cms/tests/toolbar.py
@@ -242,7 +242,6 @@ def test_placeholder_name(self):
             self.assertContains(response, 'PPPP')
 
 
-
 class EditModelTemplateTagTest(ToolbarTestBase):
     urls = 'cms.test_utils.project.placeholderapp_urls'
     edit_fields_rx = "(\?|&amp;)edit_fields=%s"
@@ -316,7 +315,24 @@ def test_filters(self):
 '''
         request = self.get_page_request(page, user, edit=True)
         response = detail_view(request, ex1.pk, template_string=template_text)
-        self.assertContains(response, '<h1><div class="cms_plugin cms_plugin-%s-%s-%s">%s</div>' % ('placeholderapp', 'char_1', ex1.pk, truncatewords(ex1.char_1, 2)))
+        self.assertContains(response, '<h1><div class="cms_plugin cms_plugin-%s-%s-%s">%s</div></h1>' % ('placeholderapp', 'char_1', ex1.pk, truncatewords(ex1.char_1, 2)))
+
+    def test_filters_notoolbar(self):
+        user = self.get_staff()
+        page = create_page('Test', 'col_two.html', 'en', published=True)
+        ex1 = Example1(char_1="char_1, <p>hello</p>, <p>hello</p>, <p>hello</p>, <p>hello</p>", char_2="char_2", char_3="char_3",
+                       char_4="char_4")
+        ex1.save()
+        template_text = '''{% extends "base.html" %}
+{% load cms_tags %}
+
+{% block content %}
+<h1>{% show_editable_model instance "char_1" "" "" truncatewords:2  %}</h1>
+{% endblock content %}
+'''
+        request = self.get_page_request(page, user, edit=False)
+        response = detail_view(request, ex1.pk, template_string=template_text)
+        self.assertContains(response, '<h1>%s</h1>' % truncatewords(ex1.char_1, 2))
 
     def test_invalid_attribute(self):
         user = self.get_staff()