Author: mtredinnick
Date: 2007-10-21 10:48:40 -0500 (Sun, 21 Oct 2007)
New Revision: 6580
Added:
django/trunk/django/templatetags/cache.py
Modified:
django/trunk/docs/cache.txt
django/trunk/tests/regressiontests/templates/tests.py
Log:
Fixed #1065 -- Added a "cache" template tag. Thanks, Ian Maurer and,
particularly, Nick Lane.
Added: django/trunk/django/templatetags/cache.py
===================================================================
--- django/trunk/django/templatetags/cache.py (rev 0)
+++ django/trunk/django/templatetags/cache.py 2007-10-21 15:48:40 UTC (rev
6580)
@@ -0,0 +1,57 @@
+from django.template import Library, Node, TemplateSyntaxError
+from django.template import resolve_variable
+from django.core.cache import cache
+from django.utils.encoding import force_unicode
+
+register = Library()
+
+class CacheNode(Node):
+ def __init__(self, nodelist, expire_time, fragment_name, vary_on):
+ self.nodelist = nodelist
+ self.expire_time = expire_time
+ self.fragment_name = fragment_name
+ self.vary_on = vary_on
+
+ def render(self, context):
+ # Build a unicode key for this fragment and all vary-on's.
+ cache_key = u':'.join([self.fragment_name] + \
+ [force_unicode(resolve_variable(var, context)) for var in
self.vary_on])
+ value = cache.get(cache_key)
+ if value is None:
+ value = self.nodelist.render(context)
+ cache.set(cache_key, value, self.expire_time)
+ return value
+
+def do_cache(parser, token):
+ """
+ This will cache the contents of a template fragment for a given amount
+ of time.
+
+ Usage::
+
+ {% load cache %}
+ {% cache [expire_time] [fragment_name] %}
+ .. some expensive processing ..
+ {% endcache %}
+
+ This tag also supports varying by a list of arguments::
+
+ {% load cache %}
+ {% cache [expire_time] [fragment_name] [var1] [var2] .. %}
+ .. some expensive processing ..
+ {% endcache %}
+
+ Each unique set of arguments will result in a unique cache entry.
+ """
+ nodelist = parser.parse(('endcache',))
+ parser.delete_first_token()
+ tokens = token.contents.split()
+ if len(tokens) < 3:
+ raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." %
tokens[0])
+ try:
+ expire_time = int(tokens[1])
+ except ValueError:
+ raise TemplateSyntaxError(u"First argument to '%r' must be an integer
(got '%s')." % (tokens[0], tokens[1]))
+ return CacheNode(nodelist, expire_time, tokens[2], tokens[3:])
+
+register.tag('cache', do_cache)
Modified: django/trunk/docs/cache.txt
===================================================================
--- django/trunk/docs/cache.txt 2007-10-21 14:57:05 UTC (rev 6579)
+++ django/trunk/docs/cache.txt 2007-10-21 15:48:40 UTC (rev 6580)
@@ -288,6 +288,36 @@
above example, the result of the ``slashdot_this()`` view will be cached for 15
minutes.
+Template fragment caching
+=========================
+
+If you're after even more control, you can also cache template fragments using
+the ``cache`` template tag. To give your template access to this tag, put ``{%
+load cache %}`` near the top of your template.
+
+The ``{% cache %}`` template tag caches the contents of the block for a given
+amount of time. It takes at least two arguments: the cache timeout, in
+seconds, and the name to give the cache fragment. For example::
+
+ {% load cache %}
+ {% cache 500 sidebar %}
+ .. sidebar ..
+ {% endcache %}
+
+Sometimes you might want to cache multiple copies of a fragment depending on
+some dynamic data that appears inside the fragment. For example you may want a
+separate cached copy of the sidebar used in the previous example for every user
+of your site. This can be easily achieved by passing additional arguments to
+the ``{% cache %}`` template tag to uniquely identify the cache fragment::
+
+ {% load cache %}
+ {% cache 500 sidebar request.user.username %}
+ .. sidebar for logged in user ..
+ {% endcache %}
+
+If you need more than one argument to identify the fragment that's fine, simply
+pass as many arguments to ``{% cache %}`` as you need!
+
The low-level cache API
=======================
Modified: django/trunk/tests/regressiontests/templates/tests.py
===================================================================
--- django/trunk/tests/regressiontests/templates/tests.py 2007-10-21
14:57:05 UTC (rev 6579)
+++ django/trunk/tests/regressiontests/templates/tests.py 2007-10-21
15:48:40 UTC (rev 6580)
@@ -805,6 +805,20 @@
'url-fail01' : ('{% url %}', {}, template.TemplateSyntaxError),
'url-fail02' : ('{% url no_such_view %}', {}, ''),
'url-fail03' : ('{% url regressiontests.templates.views.client
no_such_param="value" %}', {}, ''),
+
+ ### CACHE TAG
######################################################
+ 'cache01' : ('{% load cache %}{% cache -1 test %}cache01{%
endcache %}', {}, 'cache01'),
+ 'cache02' : ('{% load cache %}{% cache -1 test %}cache02{%
endcache %}', {}, 'cache02'),
+ 'cache03' : ('{% load cache %}{% cache 2 test %}cache03{% endcache
%}', {}, 'cache03'),
+ 'cache04' : ('{% load cache %}{% cache 2 test %}cache04{% endcache
%}', {}, 'cache03'),
+ 'cache05' : ('{% load cache %}{% cache 2 test foo %}cache05{%
endcache %}', {'foo': 1}, 'cache05'),
+ 'cache06' : ('{% load cache %}{% cache 2 test foo %}cache06{%
endcache %}', {'foo': 2}, 'cache06'),
+ 'cache07' : ('{% load cache %}{% cache 2 test foo %}cache06{%
endcache %}', {'foo': 1}, 'cache05'),
+
+ # Raise exception if we dont have at least 2 args, first one
integer.
+ 'cache08' : ('{% load cache %}{% cache %}{% endcache %}', {},
template.TemplateSyntaxError),
+ 'cache09' : ('{% load cache %}{% cache 1 %}{% endcache %}', {},
template.TemplateSyntaxError),
+ 'cache10' : ('{% load cache %}{% cache foo bar %}{% endcache %}',
{}, template.TemplateSyntaxError),
}
# Register our custom template loader.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---