views:

117

answers:

1

I'm using Jinja2, and I'm trying to create a couple tags that work together, such that if I have a template that looks something like this:

{{ my_summary() }}
... arbitrary HTML ...
{{ my_values('Tom', 'Dick', 'Harry') }}
... arbitrary HTML ...
{{ my_values('Fred', 'Barney') }}

I'd end up with the following:

This page includes information about <b>Tom</b>, <b>Dick</b>, <b>Harry</b>, <b>Fred</b>, and <b>Barney</b>.
... arbitrary HTML ...
<h1>Tom, Dick, and Harry</h1>
... arbitrary HTML ...
<h1>Fred and Barney</h1>

In other words, the my_summary() at the start of the page includes information provided later on in the page. It should be smart enough to take into account expressions which occur in include and import statements, as well.

What's the best way to do this?

+3  A: 

Disclaimer: I do not know Jinja.

My guess is that you cannot (easily) accomplish this.

I would suggest the following alternative:

  • Pass the Tom, Dick, etc. values as variables to the template from the outside.
  • Let your custom tags take the values as arguments.
  • I do not know what "the outside" would be in your case. If the template is used in a web app framework, "the outside" is probably a controller method.
  • For instance:

Template:

{{ my_summary(list1 + list2) }}
... arbitrary HTML ...
{{ my_values(list1) }}
... arbitrary HTML ...
{{ my_values(list2) }}

Controller:

def a_controller_method(request):
    return render_template('templatefilename', {
        'list1': ['Dick', 'Tom', 'Harry'],
        'list2': ['Fred', 'Barney']})
  • If passing the values from the outside is not feasible, I suggest you define them at the top of your template, like this:
{% set list1 = ['Dick', ...] %}
{% set list2 = ['Fred', ...] %}
{{ my_summary(list1 + list2) }}
... arbitrary HTML ...
{{ my_values(list1) }}
... arbitrary HTML ...
{{ my_values(list2) }}
codeape
If I knew all values at the start of the page, I wouldn't have this issue. The goal is to define a parent template (with my_summary()) that can have children that define my_values(). The parent wouldn't need to know, at the start of the render process, whether it does or not.
Chris B.