Added support for {{ block.super }}. Dropped support for Django 1.1.X. Fixed #88.

This commit is contained in:
Mathieu Pillard
2011-07-18 18:02:09 +02:00
committed by Jannis Leidel
parent 55ba6a2014
commit fdc05a64de
6 changed files with 87 additions and 40 deletions

View File

@@ -1,5 +1,6 @@
import os
import sys
from types import MethodType
from fnmatch import fnmatch
from optparse import make_option
@@ -12,6 +13,8 @@ from django.core.management.base import NoArgsCommand, CommandError
from django.template import Context, Template, TemplateDoesNotExist, TemplateSyntaxError
from django.utils.datastructures import SortedDict
from django.utils.importlib import import_module
from django.template.loader import get_template
from django.template.loader_tags import ExtendsNode, BlockNode, BLOCK_CONTEXT_KEY
try:
from django.template.loaders.cached import Loader as CachedLoader
@@ -25,6 +28,14 @@ from compressor.templatetags.compress import CompressorNode
from compressor.utils import walk, any
def patched_get_parent(self, context):
# Patch template returned by get_parent to make sure their _render method is
# just returning the context instead of actually rendering stuff.
compiled_template = self._old_get_parent(context)
compiled_template._render = MethodType(lambda self, c: c, compiled_template)
return compiled_template
class Command(NoArgsCommand):
help = "Compress content outside of the request/response cycle"
option_list = NoArgsCommand.option_list + (
@@ -149,7 +160,8 @@ class Command(NoArgsCommand):
"template %s\n" % template_name)
nodes = list(self.walk_nodes(template))
if nodes:
compressor_nodes.setdefault(template_name, []).extend(nodes)
template.template_name = template_name
compressor_nodes.setdefault(template, []).extend(nodes)
if not compressor_nodes:
raise OfflineGenerationError(
@@ -157,14 +169,30 @@ class Command(NoArgsCommand):
if verbosity > 0:
log.write("Found 'compress' tags in:\n\t" +
"\n\t".join(compressor_nodes.keys()) + "\n")
"\n\t".join((t.template_name for t in compressor_nodes.keys())) + "\n")
log.write("Compressing... ")
count = 0
results = []
context = Context(settings.COMPRESS_OFFLINE_CONTEXT)
for nodes in compressor_nodes.values():
for template, nodes in compressor_nodes.iteritems():
context = Context(settings.COMPRESS_OFFLINE_CONTEXT)
extra_context = {}
firstnode = template.nodelist[0]
if isinstance(firstnode, ExtendsNode):
# If this template has a ExtendsNode, we apply our patch to
# generate the necessary context, and then use it for all the
# nodes in it, just in case (we don't know which nodes were
# in a block)
firstnode._old_get_parent = firstnode.get_parent
firstnode.get_parent = MethodType(patched_get_parent, firstnode)
extra_context = firstnode.render(context)
context.render_context = extra_context.render_context
for node in nodes:
context.push()
if extra_context and node._block_name:
context['block'] = context.render_context[BLOCK_CONTEXT_KEY].pop(node._block_name)
if context['block']:
context['block'].context = context
key = get_offline_cachekey(node.nodelist)
try:
result = node.render(context, forced=True)
@@ -172,19 +200,22 @@ class Command(NoArgsCommand):
raise CommandError("An error occured during rending: "
"%s" % e)
cache.set(key, result, settings.COMPRESS_OFFLINE_TIMEOUT)
context.pop()
results.append(result)
count += 1
log.write("done\nCompressed %d block(s) from %d template(s).\n" %
(count, len(compressor_nodes)))
return count, results
def walk_nodes(self, node):
def walk_nodes(self, node, block_name=None):
for node in getattr(node, "nodelist", []):
if (isinstance(node, CompressorNode) or
node.__class__.__name__ == "CompressorNode"): # for 1.1.X
if isinstance(node, BlockNode):
block_name = node.name
if isinstance(node, CompressorNode):
node._block_name = block_name
yield node
else:
for node in self.walk_nodes(node):
for node in self.walk_nodes(node, block_name=block_name):
yield node
def handle_extensions(self, extensions=('html',)):

View File

@@ -0,0 +1,16 @@
{% block content %}{% endblock %}
{% block js%}
<script type="text/javascript">
alert("test 3");
</script>
{% endblock %}
{% block css %}
<style type="text/css">
body {
background: {{ color|default:"purple" }};
}
</style>
{% endblock %}

View File

@@ -1,5 +1,7 @@
{% extends "base.html" %}
{% load compress %}
{% spaceless %}
{% block content %}{% spaceless %}
{% compress css%}
<style type="text/css">
body {
@@ -19,4 +21,22 @@
alert("test 2");
</script>
{% endcompress %}
{% endspaceless %}
{% endspaceless %}{% endblock %}
{% block js %}{% spaceless %}
{% compress js %}
{{ block.super }}
<script type="text/javascript">
alert("test 4");
</script>
{% endcompress %}
{% endspaceless %}{% endblock %}
{% block css %}{% spaceless %}
{% compress css %}
{{ block.super }}
<style type="text/css">
body { color: orange ; }
</style>
{% endcompress %}
{% endspaceless %}{% endblock %}

View File

@@ -466,11 +466,13 @@ class OfflineGenerationTestCase(TestCase):
def test_offline(self):
count, result = CompressCommand().compress()
self.assertEqual(3, count)
self.assertEqual(5, count)
self.assertEqual([
css_tag('/media/CACHE/css/cd579b7deb7d.css')+'\n',
u'<script type="text/javascript" src="/media/CACHE/js/0a2bb9a287c0.js" charset="utf-8"></script>',
u'<script type="text/javascript" src="/media/CACHE/js/fb1736ad48b7.js" charset="utf-8"></script>',
u'<script type="text/javascript" src="/media/CACHE/js/770a7311729e.js" charset="utf-8"></script>',
u'<link rel="stylesheet" href="/media/CACHE/css/67ed6aff7f7b.css" type="text/css" />\n',
], result)
# Template rendering should use the cache. FIXME: how to make sure of it ? Should we test the cache
# key<->values ourselves?
@@ -483,11 +485,13 @@ class OfflineGenerationTestCase(TestCase):
'color': 'blue',
}
count, result = CompressCommand().compress()
self.assertEqual(3, count)
self.assertEqual(5, count)
self.assertEqual([
css_tag('/media/CACHE/css/ee62fbfd116a.css')+'\n',
u'<script type="text/javascript" src="/media/CACHE/js/0a2bb9a287c0.js" charset="utf-8"></script>',
u'<script type="text/javascript" src="/media/CACHE/js/fb1736ad48b7.js" charset="utf-8"></script>',
u'<script type="text/javascript" src="/media/CACHE/js/770a7311729e.js" charset="utf-8"></script>',
u'<link rel="stylesheet" href="/media/CACHE/css/73e015f740c6.css" type="text/css" />\n',
], result)
# Template rendering should use the cache. FIXME: how to make sure of it ? Should we test the cache
# key<->values ourselves?

View File

@@ -16,6 +16,10 @@ HEAD
To revert to the previous way simply set the ``COMPRESS_CACHE_KEY_FUNCTION``
to ``'django_compressor.cache.socket_cachekey'``.
- Added support for ``{{ block.super }}`` to ``compress`` management command.
- Dropped Django 1.1.X support.
- Added Compass filter (beta).
- Fixed compiler filters on Windows.

28
tox.ini
View File

@@ -13,34 +13,6 @@ commands =
make clean
make html
[testenv:py25-1.1.X]
basepython = python2.5
deps =
unittest2
BeautifulSoup
html5lib
coverage
django==1.1.4
[testenv:py26-1.1.X]
basepython = python2.6
deps =
unittest2
BeautifulSoup
html5lib
coverage
django==1.1.4
[testenv:py27-1.1.X]
basepython = python2.7
deps =
unittest2
BeautifulSoup
html5lib
coverage
django==1.1.4
[testenv:py25-1.2.X]
basepython = python2.5
deps =