如何在Jinja2中使用相对路径包含模板

19

我正在尝试在模板中包含同一文件夹中的另一个模板。为此,我只需使用{% import 'header.jinja2' %}。问题是我一直收到TemplateNotFound错误。

我的模板文件夹如下所示:

+ myProject
|
+--+ templates
   |
   +--+ arby
   |  |-- header.jinja2
   |  |-- footer.jinja2
   |  +-- base.jinja2
   |
   +--+ bico
      |-- header.jinja2
      |-- footer.jinja2
      +-- base.jinja2

我想在渲染arby的'base.jinja2'时包含'arby/header.jinja2',在渲染bico的'base.jinja2'时包含'bico/header.jinja2'。问题在于,我不想在{% include 'arby/base.jinja2' %}中写入'arby/'或'bico/'前缀。这种做法可行吗?

谢谢。


你从哪个文件运行了 import 命令? - Blender
从 'arby/base.jinja2' 中,我想使用 {%import 'header.jinja2'%} 来包含 'arby/header.jinja2'。 - Marco Bruggmann
3个回答

15

jinja2.Environment.join_path() 文档中有一些提示,可以通过子类化 Environment 并重写 join_path() 方法来支持相对于当前(即 join_path 的 parent 参数)模板的 import 路径。

以下是这样一个类的示例:

class RelEnvironment(jinja2.Environment):
    """Override join_path() to enable relative template paths."""
    def join_path(self, template, parent):
        return os.path.join(os.path.dirname(parent), template)

3
请注意 - 由于 Jinja 的 411 和 412 问题,此方法在 Windows 上无法使用 - os.path.dirname 和 os.path.join 将使用 '\\' 分隔符,而 FilesystemLoader 会拒绝。请确保结果使用 '/' 分隔符进行分隔,而不是使用 os.path.sep。 - Tomasz Gandor
@TomaszGandor,你说得对。我因为这个问题已经挣扎了几个小时了。这一定要写在文档里。 - suhailvs

1
这个答案来得有些晚,但是如果有人遇到这个问题,你可以在base.jinja2中像这样做。
{%import 'arby/header.jinja2' as header%}

jinja应该知道模板的路径,因此在模板的子文件夹中指定文件应该很容易,只需按照文件夹/文件.扩展名的格式即可。
注意:来自flask的角度。

这完全忽略了问题的前提,哈哈 - undefined
依然是同样的问题,我需要指定模板目录的方式是相对于原始脚本位置,而不是脚本运行的位置。 - undefined

0
答案是使用os.path。
import os

path = os.path.dirname(os.path.realpath(__file__)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接