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
-~----------~----~----~----~------~----~------~--~---

Reply via email to