Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #6201 -- Improved the {% cache %} template tag to allow the tim…

…eout to be a template variable. Inspired by the patch by zz and edrik

git-svn-id: http://code.djangoproject.com/svn/django/trunk@7754 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 74f0408fa2e8e41969a381150f6d78d0cdf3f363 1 parent 5ee4a09
Adrian Holovaty authored June 26, 2008
25  django/templatetags/cache.py
... ...
@@ -1,4 +1,4 @@
1  
-from django.template import Library, Node, TemplateSyntaxError
  1
+from django.template import Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist
2 2
 from django.template import resolve_variable
3 3
 from django.core.cache import cache
4 4
 from django.utils.encoding import force_unicode
@@ -6,20 +6,27 @@
6 6
 register = Library()
7 7
 
8 8
 class CacheNode(Node):
9  
-    def __init__(self, nodelist, expire_time, fragment_name, vary_on):
  9
+    def __init__(self, nodelist, expire_time_var, fragment_name, vary_on):
10 10
         self.nodelist = nodelist
11  
-        self.expire_time = expire_time
  11
+        self.expire_time_var = Variable(expire_time_var)
12 12
         self.fragment_name = fragment_name
13 13
         self.vary_on = vary_on
14 14
 
15 15
     def render(self, context):
  16
+        try:
  17
+            expire_time = self.expire_time_var.resolve(context)
  18
+        except VariableDoesNotExist:
  19
+            raise TemplateSyntaxError('"cache" tag got an unknkown variable: %r' % self.expire_time_var.var)
  20
+        try:
  21
+            expire_time = int(expire_time)
  22
+        except (ValueError, TypeError):
  23
+            raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
16 24
         # Build a unicode key for this fragment and all vary-on's.
17  
-        cache_key = u':'.join([self.fragment_name] + \
18  
-            [force_unicode(resolve_variable(var, context)) for var in self.vary_on])
  25
+        cache_key = u':'.join([self.fragment_name] + [force_unicode(resolve_variable(var, context)) for var in self.vary_on])
19 26
         value = cache.get(cache_key)
20 27
         if value is None:
21 28
             value = self.nodelist.render(context)
22  
-            cache.set(cache_key, value, self.expire_time)
  29
+            cache.set(cache_key, value, expire_time)
23 30
         return value
24 31
 
25 32
 def do_cache(parser, token):
@@ -48,10 +55,6 @@ def do_cache(parser, token):
48 55
     tokens = token.contents.split()
49 56
     if len(tokens) < 3:
50 57
         raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0])
51  
-    try:
52  
-        expire_time = int(tokens[1])
53  
-    except ValueError:
54  
-        raise TemplateSyntaxError(u"First argument to '%r' must be an integer (got '%s')." % (tokens[0], tokens[1]))
55  
-    return CacheNode(nodelist, expire_time, tokens[2], tokens[3:])
  58
+    return CacheNode(nodelist, tokens[1], tokens[2], tokens[3:])
56 59
 
57 60
 register.tag('cache', do_cache)
11  docs/cache.txt
@@ -336,6 +336,17 @@ template tag to uniquely identify the cache fragment::
336 336
 It's perfectly fine to specify more than one argument to identify the fragment.
337 337
 Simply pass as many arguments to ``{% cache %}`` as you need.
338 338
 
  339
+The cache timeout can be a template variable, as long as the template variable
  340
+resolves to an integer value. For example, if the template variable
  341
+``my_timeout`` is set to the value ``600``, then the following two examples are
  342
+equivalent::
  343
+
  344
+    {% cache 600 sidebar %} ... {% endcache %}
  345
+    {% cache my_timeout sidebar %} ... {% endcache %}
  346
+
  347
+This feature is useful in avoiding repetition in templates. You can set the
  348
+timeout in a variable, in one place, and just reuse that value.
  349
+
339 350
 The low-level cache API
340 351
 =======================
341 352
 
52  tests/regressiontests/templates/tests.py
@@ -863,40 +863,46 @@ def get_template_tests(self):
863 863
 
864 864
             ### NOW TAG ########################################################
865 865
             # Simple case
866  
-            'now01' : ('{% now "j n Y"%}', {}, str(datetime.now().day) + ' ' + str(datetime.now().month) + ' ' + str(datetime.now().year)),
  866
+            'now01': ('{% now "j n Y"%}', {}, str(datetime.now().day) + ' ' + str(datetime.now().month) + ' ' + str(datetime.now().year)),
867 867
 
868 868
             # Check parsing of escaped and special characters
869  
-            'now02' : ('{% now "j "n" Y"%}', {}, template.TemplateSyntaxError),
870  
-        #    'now03' : ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)),
871  
-        #    'now04' : ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year))
  869
+            'now02': ('{% now "j "n" Y"%}', {}, template.TemplateSyntaxError),
  870
+        #    'now03': ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)),
  871
+        #    'now04': ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year))
872 872
 
873 873
             ### URL TAG ########################################################
874 874
             # Successes
875  
-            'url01' : ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'),
876  
-            'url02' : ('{% url regressiontests.templates.views.client_action client.id, action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
877  
-            'url03' : ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'),
878  
-            'url04' : ('{% url named.client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'),
879  
-            'url05' : (u'{% url метка_оператора v %}', {'v': u'Ω'},
880  
-                    '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
  875
+            'url01': ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'),
  876
+            'url02': ('{% url regressiontests.templates.views.client_action client.id, action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),
  877
+            'url03': ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'),
  878
+            'url04': ('{% url named.client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'),
  879
+            'url05': (u'{% url метка_оператора v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
881 880
 
882 881
             # Failures
883  
-            'url-fail01' : ('{% url %}', {}, template.TemplateSyntaxError),
884  
-            'url-fail02' : ('{% url no_such_view %}', {}, ''),
885  
-            'url-fail03' : ('{% url regressiontests.templates.views.client no_such_param="value" %}', {}, ''),
  882
+            'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
  883
+            'url-fail02': ('{% url no_such_view %}', {}, ''),
  884
+            'url-fail03': ('{% url regressiontests.templates.views.client no_such_param="value" %}', {}, ''),
886 885
 
887 886
             ### CACHE TAG ######################################################
888  
-            'cache01' : ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'),
889  
-            'cache02' : ('{% load cache %}{% cache -1 test %}cache02{% endcache %}', {}, 'cache02'),
890  
-            'cache03' : ('{% load cache %}{% cache 2 test %}cache03{% endcache %}', {}, 'cache03'),
891  
-            'cache04' : ('{% load cache %}{% cache 2 test %}cache04{% endcache %}', {}, 'cache03'),
892  
-            'cache05' : ('{% load cache %}{% cache 2 test foo %}cache05{% endcache %}', {'foo': 1}, 'cache05'),
893  
-            'cache06' : ('{% load cache %}{% cache 2 test foo %}cache06{% endcache %}', {'foo': 2}, 'cache06'),
894  
-            'cache07' : ('{% load cache %}{% cache 2 test foo %}cache06{% endcache %}', {'foo': 1}, 'cache05'),
  887
+            'cache01': ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'),
  888
+            'cache02': ('{% load cache %}{% cache -1 test %}cache02{% endcache %}', {}, 'cache02'),
  889
+            'cache03': ('{% load cache %}{% cache 2 test %}cache03{% endcache %}', {}, 'cache03'),
  890
+            'cache04': ('{% load cache %}{% cache 2 test %}cache04{% endcache %}', {}, 'cache03'),
  891
+            'cache05': ('{% load cache %}{% cache 2 test foo %}cache05{% endcache %}', {'foo': 1}, 'cache05'),
  892
+            'cache06': ('{% load cache %}{% cache 2 test foo %}cache06{% endcache %}', {'foo': 2}, 'cache06'),
  893
+            'cache07': ('{% load cache %}{% cache 2 test foo %}cache07{% endcache %}', {'foo': 1}, 'cache05'),
  894
+
  895
+            # Allow first argument to be a variable.
  896
+            'cache08': ('{% load cache %}{% cache time test foo %}cache08{% endcache %}', {'foo': 2, 'time': 2}, 'cache06'), 
  897
+            'cache09': ('{% load cache %}{% cache time test foo %}cache09{% endcache %}', {'foo': 3, 'time': -1}, 'cache09'), 
  898
+            'cache10': ('{% load cache %}{% cache time test foo %}cache10{% endcache %}', {'foo': 3, 'time': -1}, 'cache10'), 
895 899
 
896 900
             # Raise exception if we don't have at least 2 args, first one integer.
897  
-            'cache08' : ('{% load cache %}{% cache %}{% endcache %}', {}, template.TemplateSyntaxError),
898  
-            'cache09' : ('{% load cache %}{% cache 1 %}{% endcache %}', {}, template.TemplateSyntaxError),
899  
-            'cache10' : ('{% load cache %}{% cache foo bar %}{% endcache %}', {}, template.TemplateSyntaxError),
  901
+            'cache11': ('{% load cache %}{% cache %}{% endcache %}', {}, template.TemplateSyntaxError),
  902
+            'cache12': ('{% load cache %}{% cache 1 %}{% endcache %}', {}, template.TemplateSyntaxError),
  903
+            'cache13': ('{% load cache %}{% cache foo bar %}{% endcache %}', {}, template.TemplateSyntaxError),
  904
+            'cache14': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': 'fail'}, template.TemplateSyntaxError), 
  905
+            'cache15': ('{% load cache %}{% cache foo bar %}{% endcache %}', {'foo': []}, template.TemplateSyntaxError), 
900 906
 
901 907
             ### AUTOESCAPE TAG ##############################################
902 908
             'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"),

0 notes on commit 74f0408

Please sign in to comment.
Something went wrong with that request. Please try again.