1 from jinja2 import nodes
2 from jinja2.ext import Extension
5 class FragmentCacheExtension(Extension):
6 # a set of names that trigger the extension.
9 def __init__(self, environment):
10 super(FragmentCacheExtension, self).__init__(environment)
12 # add the defaults to the environment
14 fragment_cache_prefix='',
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
25 # now we parse a single expression that is used as cache key.
26 args = [parser.parse_expression()]
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())
33 args.append(nodes.Const(None))
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)
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)
44 def _cache_support(self, name, timeout, caller):
45 """Helper callback."""
46 key = self.environment.fragment_cache_prefix + name
48 # try to load the block from the cache
49 # if there is no fragment in the cache, render it and store
51 rv = self.environment.fragment_cache.get(key)
55 self.environment.fragment_cache.add(key, rv, timeout)