Pushed version number in setup.py for 2.3.1 release.
[jinja2.git] / docs / cache_extension.py
1 from jinja2 import nodes
2 from jinja2.ext import Extension
3
4
5 class FragmentCacheExtension(Extension):
6     # a set of names that trigger the extension.
7     tags = set(['cache'])
8
9     def __init__(self, environment):
10         super(FragmentCacheExtension, self).__init__(environment)
11
12         # add the defaults to the environment
13         environment.extend(
14             fragment_cache_prefix='',
15             fragment_cache=None
16         )
17
18     def parse(self, parser):
19         # the first token is the token that started the tag.  In our case
20         # we only listen to ``'cache'`` so this will be a name token with
21         # `cache` as value.  We get the line number so that we can give
22         # that line number to the nodes we create by hand.
23         lineno = parser.stream.next().lineno
24
25         # now we parse a single expression that is used as cache key.
26         args = [parser.parse_expression()]
27
28         # if there is a comma, the user provided a timeout.  If not use
29         # None as second parameter.
30         if parser.stream.skip_if('comma'):
31             args.append(parser.parse_expression())
32         else:
33             args.append(nodes.Const(None))
34
35         # now we parse the body of the cache block up to `endcache` and
36         # drop the needle (which would always be `endcache` in that case)
37         body = parser.parse_statements(['name:endcache'], drop_needle=True)
38
39         # now return a `CallBlock` node that calls our _cache_support
40         # helper method on this extension.
41         return nodes.CallBlock(self.call_method('_cache_support', args),
42                                [], [], body).set_lineno(lineno)
43
44     def _cache_support(self, name, timeout, caller):
45         """Helper callback."""
46         key = self.environment.fragment_cache_prefix + name
47
48         # try to load the block from the cache
49         # if there is no fragment in the cache, render it and store
50         # it in the cache.
51         rv = self.environment.fragment_cache.get(key)
52         if rv is not None:
53             return rv
54         rv = caller()
55         self.environment.fragment_cache.add(key, rv, timeout)
56         return rv