Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help with custom Jinja2 Extension

Tags:

python

jinja2

I've struggled to get this Jinja2 custom extension to work -- the docs weren't kidding when they said writing one was not for "civilians" -- and finally managed to arrive at this working code:

class WrapperExtension(Extension):

    tags = set(['wrap'])

    def parse(self, parser):
        lineno = parser.stream.next().lineno
        args = [parser.parse_expression()]
        args.append(nodes.Const(args[0].name))
        return nodes.CallBlock(
            self.call_method('_render', args),
            [], [], []).set_lineno(lineno)

    def _render(self, value, name, *args, **kwargs):
        if some_condition():
            return '<wrapper id="%s">%s</wrapper>' % (name, value)
        return value

As I said, this is now working. What I'm unsure about is why I need to return nodes.CallBlock in parse(), rather than self.call_method() (which returns a nodes.Call object). If anyone has any insight -- or can point me to a tutorial on writing extensions -- please do let me know.

like image 967
dcrosta Avatar asked May 12 '11 01:05

dcrosta


1 Answers

The reason is that parse() is expected to return a statement node, such as CallBlock or Assign. call_method() returns an expression node, which you must wrap in CallBlock to have a statement.

like image 125
Benjamin Peterson Avatar answered Sep 29 '22 13:09

Benjamin Peterson