Fixes checksum calculation in offline mode with templatetags inside compress blocks.
To calculate the hash for a compress block, get_offline_hexdigest() calls smart_str on each template node, which resulted in the Python repr of the templates node which is not a text node. This caused problems when using the {% static %} tag inside a compress block, since the {% static %} repr looks something like this: >>> template.Template('{% load static %}{% static "foo" %}').nodelist [<django.template.defaulttags.LoadNode at 0x10e747510>, <django.template.base.SimpleNode at 0x10e747490>] The repr changes on every compilation (since the memory location changes), which caused the checksum to change every time, and thus made the offline mode unusable. This patch renders the blocks completely, and calculates the checksums on the entire rendered block.
This commit is contained in:
@@ -49,8 +49,8 @@ def get_mtime_cachekey(filename):
|
|||||||
return get_cachekey("mtime.%s" % get_hexdigest(filename))
|
return get_cachekey("mtime.%s" % get_hexdigest(filename))
|
||||||
|
|
||||||
|
|
||||||
def get_offline_hexdigest(source):
|
def get_offline_hexdigest(render_template_string):
|
||||||
return get_hexdigest([smart_str(getattr(s, 's', s)) for s in source])
|
return get_hexdigest(render_template_string)
|
||||||
|
|
||||||
|
|
||||||
def get_offline_cachekey(source):
|
def get_offline_cachekey(source):
|
||||||
|
@@ -197,7 +197,7 @@ class Command(NoArgsCommand):
|
|||||||
context.render_context = extra_context.render_context
|
context.render_context = extra_context.render_context
|
||||||
except (IOError, TemplateSyntaxError, TemplateDoesNotExist):
|
except (IOError, TemplateSyntaxError, TemplateDoesNotExist):
|
||||||
# That first node we are trying to render might cause more errors
|
# That first node we are trying to render might cause more errors
|
||||||
# that we didn't catch when simply creating a Template instance
|
# that we didn't catch when simply creating a Template instance
|
||||||
# above, so we need to catch that (and ignore it, just like above)
|
# above, so we need to catch that (and ignore it, just like above)
|
||||||
# as well.
|
# as well.
|
||||||
if verbosity > 0:
|
if verbosity > 0:
|
||||||
@@ -209,7 +209,7 @@ class Command(NoArgsCommand):
|
|||||||
context['block'] = context.render_context[BLOCK_CONTEXT_KEY].pop(node._block_name)
|
context['block'] = context.render_context[BLOCK_CONTEXT_KEY].pop(node._block_name)
|
||||||
if context['block']:
|
if context['block']:
|
||||||
context['block'].context = context
|
context['block'].context = context
|
||||||
key = get_offline_hexdigest(node.nodelist)
|
key = get_offline_hexdigest(node.nodelist.render(context))
|
||||||
try:
|
try:
|
||||||
result = node.render(context, forced=True)
|
result = node.render(context, forced=True)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
@@ -41,14 +41,14 @@ class CompressorNode(template.Node):
|
|||||||
if request is not None:
|
if request is not None:
|
||||||
return settings.COMPRESS_DEBUG_TOGGLE in request.GET
|
return settings.COMPRESS_DEBUG_TOGGLE in request.GET
|
||||||
|
|
||||||
def render_offline(self, forced):
|
def render_offline(self, context, forced):
|
||||||
"""
|
"""
|
||||||
If enabled and in offline mode, and not forced or in debug mode
|
If enabled and in offline mode, and not forced or in debug mode
|
||||||
check the offline cache and return the result if given
|
check the offline cache and return the result if given
|
||||||
"""
|
"""
|
||||||
if (settings.COMPRESS_ENABLED and
|
if (settings.COMPRESS_ENABLED and
|
||||||
settings.COMPRESS_OFFLINE) and not forced:
|
settings.COMPRESS_OFFLINE) and not forced:
|
||||||
key = get_offline_hexdigest(self.nodelist)
|
key = get_offline_hexdigest(self.nodelist.render(context))
|
||||||
offline_manifest = get_offline_manifest()
|
offline_manifest = get_offline_manifest()
|
||||||
if key in offline_manifest:
|
if key in offline_manifest:
|
||||||
return offline_manifest[key]
|
return offline_manifest[key]
|
||||||
@@ -68,12 +68,13 @@ class CompressorNode(template.Node):
|
|||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
def render(self, context, forced=False):
|
def render(self, context, forced=False):
|
||||||
|
|
||||||
# Check if in debug mode
|
# Check if in debug mode
|
||||||
if self.debug_mode(context):
|
if self.debug_mode(context):
|
||||||
return self.nodelist.render(context)
|
return self.nodelist.render(context)
|
||||||
|
|
||||||
# See if it has been rendered offline
|
# See if it has been rendered offline
|
||||||
cached_offline = self.render_offline(forced)
|
cached_offline = self.render_offline(context, forced)
|
||||||
if cached_offline:
|
if cached_offline:
|
||||||
return cached_offline
|
return cached_offline
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
{% compress js%}
|
{% compress js%}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
alert("test");
|
alert("{% firstof "test" %}");
|
||||||
</script>
|
</script>
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user