1 from django.template import Library, Node, TemplateSyntaxError |
1 from django.template import Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist |
2 from django.template import resolve_variable |
2 from django.template import resolve_variable |
3 from django.core.cache import cache |
3 from django.core.cache import cache |
4 from django.utils.encoding import force_unicode |
4 from django.utils.encoding import force_unicode |
|
5 from django.utils.http import urlquote |
5 |
6 |
6 register = Library() |
7 register = Library() |
7 |
8 |
8 class CacheNode(Node): |
9 class CacheNode(Node): |
9 def __init__(self, nodelist, expire_time, fragment_name, vary_on): |
10 def __init__(self, nodelist, expire_time_var, fragment_name, vary_on): |
10 self.nodelist = nodelist |
11 self.nodelist = nodelist |
11 self.expire_time = expire_time |
12 self.expire_time_var = Variable(expire_time_var) |
12 self.fragment_name = fragment_name |
13 self.fragment_name = fragment_name |
13 self.vary_on = vary_on |
14 self.vary_on = vary_on |
14 |
15 |
15 def render(self, context): |
16 def render(self, context): |
|
17 try: |
|
18 expire_time = self.expire_time_var.resolve(context) |
|
19 except VariableDoesNotExist: |
|
20 raise TemplateSyntaxError('"cache" tag got an unknkown variable: %r' % self.expire_time_var.var) |
|
21 try: |
|
22 expire_time = int(expire_time) |
|
23 except (ValueError, TypeError): |
|
24 raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time) |
16 # Build a unicode key for this fragment and all vary-on's. |
25 # Build a unicode key for this fragment and all vary-on's. |
17 cache_key = u':'.join([self.fragment_name] + \ |
26 cache_key = u':'.join([self.fragment_name] + [urlquote(resolve_variable(var, context)) for var in self.vary_on]) |
18 [force_unicode(resolve_variable(var, context)) for var in self.vary_on]) |
|
19 value = cache.get(cache_key) |
27 value = cache.get(cache_key) |
20 if value is None: |
28 if value is None: |
21 value = self.nodelist.render(context) |
29 value = self.nodelist.render(context) |
22 cache.set(cache_key, value, self.expire_time) |
30 cache.set(cache_key, value, expire_time) |
23 return value |
31 return value |
24 |
32 |
25 def do_cache(parser, token): |
33 def do_cache(parser, token): |
26 """ |
34 """ |
27 This will cache the contents of a template fragment for a given amount |
35 This will cache the contents of a template fragment for a given amount |
46 nodelist = parser.parse(('endcache',)) |
54 nodelist = parser.parse(('endcache',)) |
47 parser.delete_first_token() |
55 parser.delete_first_token() |
48 tokens = token.contents.split() |
56 tokens = token.contents.split() |
49 if len(tokens) < 3: |
57 if len(tokens) < 3: |
50 raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0]) |
58 raise TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0]) |
51 try: |
59 return CacheNode(nodelist, tokens[1], tokens[2], tokens[3:]) |
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:]) |
|
56 |
60 |
57 register.tag('cache', do_cache) |
61 register.tag('cache', do_cache) |