Skip to content
Snippets Groups Projects
Commit b64d6f4f authored by Mike Bayer's avatar Mike Bayer
Browse files

- cache_key argument can now render arguments passed

  directly to the %page or %def, i.e.
  <%def name="foo(x)" cached="True" cache_key="${x}"/>
  [ticket:78]
parent 3a31591d
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,10 @@
- rewrote the "whitespace adjuster" function to work with
more elaborate combinations of quotes and comments
[ticket:75]
- cache_key argument can now render arguments passed
directly to the %page or %def, i.e.
<%def name="foo(x)" cached="True" cache_key="${x}"/>
[ticket:78]
0.1.10
- fixed propagation of 'caller' such that nested %def calls
......
......@@ -176,8 +176,8 @@ class _GenerateRenderMethod(object):
self.printer.writeline(None)
self.printer.write("\n\n")
if cached:
self.write_cache_decorator(node, name, buffered, self.identifiers, toplevel=True)
self.write_cache_decorator(node, name, args, buffered, self.identifiers, toplevel=True)
def write_module_code(self, module_code):
"""write module-level template code, i.e. that which is enclosed in <%! %> tags
in the template."""
......@@ -340,8 +340,8 @@ class _GenerateRenderMethod(object):
self.write_def_finish(node, buffered, filtered, cached)
self.printer.writeline(None)
if cached:
self.write_cache_decorator(node, node.name, False, identifiers, inline=True, toplevel=False)
self.write_cache_decorator(node, node.name, namedecls, False, identifiers, inline=True, toplevel=False)
def write_def_finish(self, node, buffered, filtered, cached, callstack=True):
"""write the end section of a rendering function, either outermost or inline.
......@@ -377,7 +377,7 @@ class _GenerateRenderMethod(object):
"return ''"
)
def write_cache_decorator(self, node_or_pagetag, name, buffered, identifiers, inline=False, toplevel=False):
def write_cache_decorator(self, node_or_pagetag, name, args, buffered, identifiers, inline=False, toplevel=False):
"""write a post-function decorator to replace a rendering callable with a cached version of itself."""
self.printer.writeline("__M_%s = %s" % (name, name))
cachekey = node_or_pagetag.parsed_attributes.get('cache_key', repr(name))
......@@ -398,22 +398,22 @@ class _GenerateRenderMethod(object):
else:
cacheargs[arg[1]] = val
if inline:
ctx_arg = ""
else:
ctx_arg = "context, "
self.printer.writeline("def %s(%s*args, **kwargs):" % (name, ctx_arg))
self.printer.writeline("def %s(%s):" % (name, ','.join(args)))
self.write_variable_declares(identifiers, toplevel=toplevel, limit=node_or_pagetag.undeclared_identifiers())
# form "arg1, arg2, arg3=arg3, arg4=arg4", etc.
pass_args = [ '=' in a and "%s=%s" % ((a.split('=')[0],)*2) or a for a in args]
self.write_variable_declares(identifiers, toplevel=toplevel, limit=node_or_pagetag.undeclared_identifiers())
if buffered:
s = "context.get('local').get_cached(%s, %screatefunc=lambda:__M_%s(%s*args, **kwargs))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ctx_arg)
s = "context.get('local').get_cached(%s, %screatefunc=lambda:__M_%s(%s))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args))
# apply buffer_filters
s = self.create_filter_callable(self.compiler.buffer_filters, s, False)
self.printer.writelines("return " + s,None)
else:
self.printer.writelines(
"context.write(context.get('local').get_cached(%s, %screatefunc=lambda:__M_%s(%s*args, **kwargs)))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ctx_arg),
"context.write(context.get('local').get_cached(%s, %screatefunc=lambda:__M_%s(%s)))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args)),
"return ''",
None
)
......
......@@ -92,7 +92,43 @@ class CacheTest(unittest.TestCase):
"callcount: [1]"
]
assert m.kwargs == {}
def test_dynamic_key_with_funcargs(self):
t = Template("""
<%def name="foo(num=5)" cached="True" cache_key="foo_${str(num)}">
hi
</%def>
${foo()}
""")
m = self._install_mock_cache(t)
t.render()
t.render()
assert result_lines(t.render()) == ['hi']
assert m.key == "foo_5"
t = Template("""
<%def name="foo(*args, **kwargs)" cached="True" cache_key="foo_${kwargs['bar']}">
hi
</%def>
${foo(1, 2, bar='lala')}
""")
m = self._install_mock_cache(t)
t.render()
assert result_lines(t.render()) == ['hi']
assert m.key == "foo_lala"
t = Template('''
<%page args="bar='hi'" cache_key="foo_${bar}" cached="True"/>
hi
''')
m = self._install_mock_cache(t)
t.render()
assert result_lines(t.render()) == ['hi']
assert m.key == "foo_hi"
def test_dynamic_key_with_imports(self):
lookup = TemplateLookup()
lookup.put_string("foo.html", """
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment