Search code examples
pythonfunctiontemplatingmako

Python functions in Mako templates (not in module-level blocks)


I'm using Pyramid and Mako for templating.

It is possible to define a (semi-anonymous) function within a Mako block <% and %>.

I know it can be done with a module-level block <%! and %>, but this means my function doesn't have any access to the local scope when templating, meaning I have to pass every bit of variable in that I need.

Example:

...template...
<%
variable_in_local_scope = 'blah blah blah'
def my_function():
    header_name = variable_in_local_scope.upper()
    return header_name
%>
${foo()}

This will throw a NameError saying header_name is not defined. The only way around this has been to code it like

<%!
def my_function(input_variable):
    return input_variable.upper()
%>
${my_function(variable_in_local_scope)}

This works, but when there are more than a few variables for the function, it gets quite unweildy. I must also re-import any 'helper' functions available to my template in the module-level-block.

Is there any way around this, or am I doing something completely stupid?


Solution

  • Add a dictionary in your context using:

    template.render(local_vars={})
    

    and then use it in your functions.

    Note: Mako is too fast, because the engine will create a python module for each *.mak(template file) before render it, you may try this:

    from mako.template import Template
    mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
    print mytemplate.render()
    

    and check content of *.py files in '/tmp/mako_modules'