Skip to content

Loading…

Don't leave `compressed` in the render context #354

Closed
wants to merge 2 commits into from

2 participants

@gavinwahl

The compress template tag should push/pop the context when rendering so as to not overwrite a template variable called compressed.

@gavinwahl

I noticed this breaks the Jinja2 extension tests, because it uses dictionaries for the context, which have a different pop() method. I'm not sure how to proceed here.

@diox

Sorry, I'm closing this because Jinja2 compatibility is forcing our hand here. I don't want to add more complexity for such a small issue, so I don't think adding a workaround specifically for jinja2 would be a good idea.

@diox diox closed this
@gavinwahl

It should be documented that you're not allowed to use a template context variable called compressed when using django-compressor. Where's a good place to put this in the docs?

@diox

I guess somewhere in the usage section. Alternatively, it looks like we don't do a very good job at explaining the compressor templates & context so we could have a full section for it if you really want to go the extra mile and write that too :-p

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 14 additions and 4 deletions.
  1. +5 −2 compressor/templatetags/compress.py
  2. +9 −2 compressor/tests/test_templatetags.py
View
7 compressor/templatetags/compress.py
@@ -94,7 +94,7 @@ def render_compressed(self, context, kind, mode, forced=False):
not settings.COMPRESS_PRECOMPILERS) and not forced):
return self.get_original_content(context)
- context['compressed'] = {'name': getattr(self, 'name', None)}
+ context.update({'compressed': {'name': getattr(self, 'name', None)}})
compressor = self.get_compressor(context, kind)
# Prepare the actual compressor and check cache
@@ -107,13 +107,16 @@ def render_compressed(self, context, kind, mode, forced=False):
rendered_output = self.render_output(compressor, mode, forced=forced)
if cache_key:
cache_set(cache_key, rendered_output)
+ context.pop()
return rendered_output.decode('utf-8')
except Exception:
if settings.DEBUG or forced:
raise
# Or don't do anything in production
- return self.get_original_content(context)
+ output = self.get_original_content(context)
+ context.pop()
+ return output
def render_output(self, compressor, mode, forced=False):
return compressor.output(mode, forced=forced)
View
11 compressor/tests/test_templatetags.py
@@ -2,6 +2,7 @@
import os
import sys
+import copy
from mock import Mock
@@ -121,14 +122,20 @@ def test_named_compress_tag(self):
{% endcompress %}
"""
+ context_copy = []
+
def listener(sender, **kwargs):
- pass
+ context_copy.append(copy.deepcopy(kwargs['context']))
+
callback = Mock(wraps=listener)
post_compress.connect(callback)
render(template)
args, kwargs = callback.call_args
context = kwargs['context']
- self.assertEqual('foo', context['compressed']['name'])
+ # compressed must be in the context while the tag is being rendered
+ self.assertEqual('foo', context_copy[0]['compressed']['name'])
+ # but it must not remain when the tag is done
+ self.assertRaises(KeyError, lambda: context['compressed'])
class PrecompilerTemplatetagTestCase(TestCase):
Something went wrong with that request. Please try again.