Use new context hook to pass name argument from tag to compressor to signal.

This commit is contained in:
Jonathan Lukens 2011-08-26 22:42:23 -04:00
parent dc316b2322
commit 8afbd9d7cf
6 changed files with 45 additions and 23 deletions

View File

@ -40,7 +40,6 @@ class Compressor(object):
self.extra_context = {} self.extra_context = {}
self.all_mimetypes = dict(settings.COMPRESS_PRECOMPILERS) self.all_mimetypes = dict(settings.COMPRESS_PRECOMPILERS)
self.finders = staticfiles.finders self.finders = staticfiles.finders
self.block_name = block_name
def split_contents(self): def split_contents(self):
""" """
@ -262,6 +261,6 @@ class Compressor(object):
final_context.update(context) final_context.update(context)
final_context.update(self.context) final_context.update(self.context)
final_context.update(self.extra_context) final_context.update(self.extra_context)
post_compress.send(sender='django-compressor', name=self.block_name, type=self.type, mode=mode, context=final_context) post_compress.send(sender='django-compressor', type=self.type, mode=mode, context=final_context)
return render_to_string("compressor/%s_%s.html" % return render_to_string("compressor/%s_%s.html" %
(self.type, mode), final_context) (self.type, mode), final_context)

View File

@ -1,4 +1,4 @@
import django.dispatch import django.dispatch
post_compress = django.dispatch.Signal(providing_args=['name', 'type', 'mode', 'context']) post_compress = django.dispatch.Signal(providing_args=['type', 'mode', 'context'])

View File

@ -18,6 +18,7 @@ class CompressorNode(template.Node):
self.nodelist = nodelist self.nodelist = nodelist
self.kind = kind self.kind = kind
self.mode = mode self.mode = mode
self.name = name
def compressor_cls(self, *args, **kwargs): def compressor_cls(self, *args, **kwargs):
compressors = { compressors = {
@ -70,6 +71,7 @@ class CompressorNode(template.Node):
return cached_offline return cached_offline
# 3. Prepare the actual compressor and check cache # 3. Prepare the actual compressor and check cache
context.update({'name': self.name})
compressor = self.compressor_cls(content=self.nodelist.render(context), compressor = self.compressor_cls(content=self.nodelist.render(context),
context=context) context=context)
cache_key, cache_content = self.render_cached(compressor, forced) cache_key, cache_content = self.render_cached(compressor, forced)
@ -127,13 +129,13 @@ def compress(parser, token):
args = token.split_contents() args = token.split_contents()
if not len(args) in (2, 3): if not len(args) in (2, 3, 4):
raise template.TemplateSyntaxError( raise template.TemplateSyntaxError(
"%r tag requires either one or two arguments." % args[0]) "%r tag requires either one, two or three arguments." % args[0])
kind = args[1] kind = args[1]
if len(args) == 3: if len(args) >= 3:
mode = args[2] mode = args[2]
if not mode in OUTPUT_MODES: if not mode in OUTPUT_MODES:
raise template.TemplateSyntaxError( raise template.TemplateSyntaxError(
@ -141,4 +143,8 @@ def compress(parser, token):
(args[0], OUTPUT_FILE, OUTPUT_INLINE)) (args[0], OUTPUT_FILE, OUTPUT_INLINE))
else: else:
mode = OUTPUT_FILE mode = OUTPUT_FILE
return CompressorNode(nodelist, kind, mode) if len(args) == 4:
name = args[3]
else:
name = None
return CompressorNode(nodelist, kind, mode, name)

View File

@ -86,8 +86,8 @@ would be rendered something like::
</script> </script>
The compress template tag also supports a third argument for naming the output The compress template tag also supports a third argument for naming the output
of that particular compress tag. This is then passed as an argument to the of that particular compress tag. This is then added to the context so you can
`post_compress signal <signals>`. access it in the `post_compress signal <signals>`.
.. _memcached: http://memcached.org/ .. _memcached: http://memcached.org/
.. _caching documentation: http://docs.djangoproject.com/en/1.2/topics/cache/#memcached .. _caching documentation: http://docs.djangoproject.com/en/1.2/topics/cache/#memcached
@ -159,10 +159,6 @@ sends the following arguments:
``sender`` ``sender``
Always "django-compressor". Always "django-compressor".
``name``
The value provided in the 3rd positional argument to the template tag, or
``None`` if no 3rd positional argument was provided.
``type`` ``type``
Either "``js``" or "``css``". Either "``js``" or "``css``".
@ -171,11 +167,17 @@ sends the following arguments:
``context`` ``context``
The context dictionary used to render the output of the compress template The context dictionary used to render the output of the compress template
tag. If ``mode`` is "``file``", this will contain a "``url``" key that maps to tag.
the relative URL for the compressed asset. If ``type`` is "``css``", the
context will additionally contain a "``media``" key with a value of ``None`` if If ``mode`` is "``file``", this will contain a "``url``" key that maps to
no media attribute is specified on the link/style tag and equal to that the relative URL for the compressed asset.
attribute if one is specified.
If ``type`` is "``css``", the context will additionally contain a
"``media``" key with a value of ``None`` if no media attribute is specified on
the link/style tag and equal to that attribute if one is specified.
Additionally, ``context['name']`` will be the third positional argument to
the template tag, if provided.
.. note:: .. note::

View File

@ -17,12 +17,12 @@ class PostCompressSignalTestCase(TestCase):
<link rel="stylesheet" href="/media/css/one.css" type="text/css" /> <link rel="stylesheet" href="/media/css/one.css" type="text/css" />
<style type="text/css">p { border:5px solid green;}</style> <style type="text/css">p { border:5px solid green;}</style>
<link rel="stylesheet" href="/media/css/two.css" type="text/css" />""" <link rel="stylesheet" href="/media/css/two.css" type="text/css" />"""
self.css_node = CssCompressor(self.css, block_name='foo') self.css_node = CssCompressor(self.css)
self.js = """\ self.js = """\
<script src="/media/js/one.js" type="text/javascript"></script> <script src="/media/js/one.js" type="text/javascript"></script>
<script type="text/javascript">obj.value = "value";</script>""" <script type="text/javascript">obj.value = "value";</script>"""
self.js_node = JsCompressor(self.js, block_name='foo') self.js_node = JsCompressor(self.js)
def tearDown(self): def tearDown(self):
post_compress.disconnect() post_compress.disconnect()
@ -35,7 +35,6 @@ class PostCompressSignalTestCase(TestCase):
self.js_node.output() self.js_node.output()
args, kwargs = callback.call_args args, kwargs = callback.call_args
self.assertEquals('django-compressor', kwargs['sender']) self.assertEquals('django-compressor', kwargs['sender'])
self.assertEquals('foo', kwargs['name'])
self.assertEquals('js', kwargs['type']) self.assertEquals('js', kwargs['type'])
self.assertEquals('file', kwargs['mode']) self.assertEquals('file', kwargs['mode'])
context = kwargs['context'] context = kwargs['context']
@ -49,7 +48,6 @@ class PostCompressSignalTestCase(TestCase):
self.css_node.output() self.css_node.output()
args, kwargs = callback.call_args args, kwargs = callback.call_args
self.assertEquals('django-compressor', kwargs['sender']) self.assertEquals('django-compressor', kwargs['sender'])
self.assertEquals('foo', kwargs['name'])
self.assertEquals('css', kwargs['type']) self.assertEquals('css', kwargs['type'])
self.assertEquals('file', kwargs['mode']) self.assertEquals('file', kwargs['mode'])
context = kwargs['context'] context = kwargs['context']
@ -60,7 +58,7 @@ class PostCompressSignalTestCase(TestCase):
<link rel="stylesheet" href="/media/css/one.css" media="handheld" type="text/css" /> <link rel="stylesheet" href="/media/css/one.css" media="handheld" type="text/css" />
<style type="text/css" media="print">p { border:5px solid green;}</style> <style type="text/css" media="print">p { border:5px solid green;}</style>
<link rel="stylesheet" href="/media/css/two.css" type="text/css" />""" <link rel="stylesheet" href="/media/css/two.css" type="text/css" />"""
css_node = CssCompressor(css, block_name='foo') css_node = CssCompressor(css)
def listener(sender, **kwargs): def listener(sender, **kwargs):
pass pass
callback = Mock(wraps=listener) callback = Mock(wraps=listener)

View File

@ -4,6 +4,10 @@ from django.conf import settings
from django.template import Template, Context, TemplateSyntaxError from django.template import Template, Context, TemplateSyntaxError
from django.test import TestCase from django.test import TestCase
from mock import Mock
from compressor.signals import post_compress
from .base import css_tag from .base import css_tag
@ -96,3 +100,16 @@ class TemplatetagTestCase(TestCase):
<script type="text/javascript">obj.value = "value";</script>""" <script type="text/javascript">obj.value = "value";</script>"""
self.assertEqual(out, render(template, context)) self.assertEqual(out, render(template, context))
def test_named_compress_tag(self):
template = u"""{% load compress %}{% compress js inline foo %}
<script type="text/javascript">obj.value = "value";</script>
{% endcompress %}
"""
def listener(sender, **kwargs):
pass
callback = Mock(wraps=listener)
post_compress.connect(callback)
render(template)
args, kwargs = callback.call_args
context = kwargs['context']
self.assertEqual('foo', context['name'])