Cormac Mulhall
Cormac Mulhall

Reputation: 1217

Jinja macros accessing different blocks

I'm trying to get a Jinja2 macro to output into different part of the calling template. The reason I' want to do this is because there is inline Javascript as part of the macro, but I want all Javascript at the end of the template. I basically want to do something like this

{% import 'tooltip.html' as tooltip %} 
<html>
  <body>
    {% block contents %}
    {% tooltip('mytool') %}
    {% endblock %}
    <script>
      {% block javascript %}
      {% endblock %}
    </script>
  </body>
</html>

And in the macro file

{% macro tooltip(name) %}
  <div id='{{ name }}'>
    This is my tooltip
  </div>

  {% block javascript %}
  jQuery("#{{ name }}").click(function(){//do something});
  {% endblock %}
{% endmacro %}

So the end result would be something like

<html>
  <body>
    <div id='mytool'>
      This is my tooltip
    </div>
    <script>
      jQuery("#mytool").click(function(){//do something});
    </script>
  </body>
</html>

I want all my javascript at the end of my template, but macros seem to just return then and there.

Is there something I'm missing or is this beyond standard Jinja2 and would require writing an extension?

Thanks

Upvotes: 4

Views: 2370

Answers (2)

nightpool
nightpool

Reputation: 611

Could you split it into 2 functions? Like, one that outputs the markup and one that outputs the javascript? That would be the simplest way to do it that I see. It kind of all depends on your use case, but I think that would also be the "right way".

Upvotes: 1

Will McCutchen
Will McCutchen

Reputation: 13117

I'm not sure if it's possible to do what you're asking in Jinja. But I do think a different approach might work and provide a simpler solution:

Instead of generating markup like

<div id='mytool'>
  This is my tooltip
</div>

and a corresponding jQuery call with each tooltip's ID hardcoded like

<script>
  jQuery("#mytool").click(function(){});
</script>

for every tooltip on a page, give every tooltip a class attribute and make the jQuery functionality work on all elements with that class. That way, every page can have the same generic bit of jQuery and work regardless of what tooltips appear on that specific page.

Something more like:

<div id="mytool" class="tooltip">
  This is my tooltip
</div>

plus a more generic jQuery call:

<script>
  // This will add the onclick handler to any element
  // with a class of "tooltip"
  jQuery(".tooltip").click(function(){});
</script>

This jQuery code can be included once, at the bottom of your "base" template, so that it's available on every page and you don't have to figure out how to write to two separate blocks from a Jinja macro.

Upvotes: 4

Related Questions