3

I would like to implement a custom extension with that allow dynamical loading of an external datasource. For example:

{# A jinja template #}
{% datasource '../foo.yml' %}

{{ foo }}
{{ bar }}

So I wrote this:

#!/usr/bin/env python
from jinja2 import Template, nodes
from jinja2.ext import Extension

class Test(Extension):
    tags = set(['datasource'])

    def parse(self, parser):
        lineno = next(parser.stream).lineno
        args = [parser.parse_expression()]
        call = self.call_method('_render', args)
        return nodes.Output([call], lineno=lineno)

    def _render(self, name):
        print name
        print "Hello from render"
        return None

x = """
{# A jinja template #}
{% datasource '../foo.yml' %}

{{ foo }}
{{ bar }}
"""

t = Template(x, extensions=[Test])
t.render()

It works well if I use:

{% datasource '../foo.yml' %}

However if I miss the argument '../foo.yml', I get a long traceback that is hard to understand:

TemplateSyntaxError: unexpected 'end of statement block'

If I add a second argument, I also get an error:

{% datasource 'foo', 'bar' %}

TemplateSyntaxError: expected token 'end of statement block', got ','

How should I implement that?

Bonus question: is lineno=lineno necessary?

Ulf Gjerdingen
  • 1,414
  • 3
  • 16
  • 20
nowox
  • 25,978
  • 39
  • 143
  • 293

0 Answers0