Jinja宏访问不同块

4 投票
2 回答
2323 浏览
提问于 2025-04-16 07:27

我想让一个Jinja2的宏在调用它的模板的不同部分输出内容。这样做的原因是因为宏里面有一些内联的JavaScript代码,但我希望所有的JavaScript都放在模板的最后。我基本上想做的事情是这样的:

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

然后在宏文件里:

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

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

最终的结果应该是这样的:

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

我希望我的所有JavaScript都放在模板的最后,但宏似乎只能在调用的地方直接返回内容。

我是不是漏掉了什么,还是说这超出了标准的Jinja2,需要写一个扩展呢?

谢谢!

2 个回答

1

你能把它分成两个函数吗?比如,一个函数负责输出HTML标记,另一个函数负责输出JavaScript代码?我觉得这样做是最简单的方式。这其实也要看你的具体需求,但我认为这样做也是“正确的方式”。

4

我不太确定在Jinja中是否能做到你所要求的。不过我觉得换个方法可能会更有效,也能提供一个更简单的解决方案:

与其生成像这样的标记:

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

以及每个提示框的ID都写死在jQuery调用中的代码:

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

不如给每个提示框加一个 class 属性,然后让jQuery的功能作用于所有带有这个 class 的元素。这样,每个页面都可以使用相同的通用jQuery代码,无论该页面上出现什么提示框,都能正常工作。

可以像这样:

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

再加上一个更通用的jQuery调用:

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

这段jQuery代码可以只放在你“基础”模板的底部,这样在每个页面上都能使用,你也不需要去想如何从Jinja宏中写入两个不同的代码块。

撰写回答