Get expressions from template

88 views
Skip to first unread message

slide

unread,
Sep 12, 2012, 5:20:46 AM9/12/12
to mako-d...@googlegroups.com
I am using Mako inside of an application to provide templated generation of XML files. I would like to retrieve the expression values from a given template to allow users to override the value before it is rendered.

For instance if I had the following

<Test>
    <foo name="Something" value="${SOMEVAR}"/>
    <foo name="SomethingElse" value="${OTHERVAR}"/>
</Test>

I would like to retrieve SOMEVAR and OTHERVAR. I noticed they are replaced by something like this in the templte

SOMEVAR = context.get('SOMEVAR', UNDEFINED)

so it seems like there might be a way to hook into the parsing stage?

Thanks,

slide

Michael Bayer

unread,
Sep 12, 2012, 10:13:49 PM9/12/12
to mako-d...@googlegroups.com
its a little odd to tell exactly who/when knows what in this scenario. It seems like there is some concept of templates coming from somewhere with variables declared in them, and some other code needs to call upon these templates, and needs to "know" what variables will be called.

That is, i need something to happen in response to a variable being present in a template.

Usually, when I have to do this kind of thing it's with Python string templates, but same idea, I use an object with __getattr__ or __getitem__ on it.

That is, template:

variable one: ${namespace.FOO}
variable two: ${namespace.BAR}

usage:

class MyNamespace(object):
def __getattr__(self, key):
print "namespace attribute %s called" % key
return "HELLO!"

template.render(namespace=MyNamespace())

This is kind of an entirely different approach to what you're looking for, but is very simple and performant.

Otherwise, you truly need to know the names before anything is rendered, yes you'd have to dig into Lexer, lex the template, get the parsetree back, walk through it and look for undeclared_identifiers() stuck on nodes. Take a look at lexer.py and parsetree.py to see how that works, a quick lex looks like:

from mako.lexer import Lexer
parsetree = Lexer("some template").parse()

def find_undeclared(node):
stack = [node]
while stack:
node = stack.pop(0)
stack.extend(node.get_children())
if hasattr(node, "undeclared_identifiers"):
for ident in node.undeclared_identifiers():
yield ident


slide

unread,
Sep 12, 2012, 11:31:55 PM9/12/12
to mako-d...@googlegroups.com
That doesn't sound too bad, I appreciate the pointers and will give it the old college try as they say. 

slide 

slide

unread,
Sep 14, 2012, 2:54:18 AM9/14/12
to mako-d...@googlegroups.com
FYI, your solution worked perfectly. I was able to get the info I needed from the template with the code above. Thanks again for the help, its very much appreciated!

slide 
Reply all
Reply to author
Forward
0 new messages