jinja2允许宏被扩展,但是提供了一个回退实现

58wvjzkj  于 2021-07-13  发布在  Java
关注(0)|答案(0)|浏览(230)

在我正在进行的一个项目中,我希望能够声明一些常见的宏,这些宏可以方便地通过基于jinja模板的主题进行扩展。
以下是我设置和构建主题的典型示例:

$ tree
.
├── base
│   ├── common_macros.j2
│   └── example.j2
├── example.py
└── theme1
    └── common_macros.j2

example.py 看起来像:

from pathlib import Path
import jinja2

if __name__ == '__main__':
    tmplt_root = Path(__file__).parent

    # Setup the base loader to be able to use both "example.j2" and "base/example.j2",
    # thereby allowing themes to implement "example.j2" by extending "base/example.j2".
    base_template_paths = [str(tmplt_root), str(tmplt_root / 'base')]

    env1 = jinja2.Environment(
        loader=jinja2.FileSystemLoader(base_template_paths),
    )

    env_themed = jinja2.Environment(
        loader=jinja2.FileSystemLoader(['theme1/'] + base_template_paths),
    )

    print('BASE')
    print('----------')
    print(env1.get_template('example.j2').render())

    print('Theme 1')
    print('----------')
    print(env_themed.get_template('example.j2').render())
``` `base/example.j2` :

{% from "common_macros.j2" import macro1 %}

{% block main -%}
{{ macro1() }}
{%- endblock main %}
``` base/common_macros.j2 :

{% macro macro1() -%}
Macro 1 base
{% endmacro %}

通过这种设置,我可以在 theme1/common_macros.j2 (甚至可以调用基本实现!):

{% import "base/common_macros.j2" as base %}

{% macro macro1() -%}
    Theme macro 1!
    {{ base.macro1() }}
{% endmacro %}

到目前为止,一切都很好!

$ python example.py
BASE
----------

Macro 1 base

Theme 1
----------

Theme macro 1!
    Macro 1 base

当我将另一个宏添加到 base/common_macros.j2 (并将其用于 example.j2 )此时会发生以下错误:

$ python example.py
BASE
----------

Macro 1 base

    Macro 2 base

Theme 1
----------
Traceback (most recent call last):
  File "example.py", line 25, in <module>
    print(env_themed.get_template('example.j2').render())
  File "jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "base/example.j2", line 3, in top-level template code
    {% block main -%}
  File "base/example.j2", line 5, in block "main"
    {{ macro2() }}
jinja2.exceptions.UndefinedError: the template 'common_macros.j2' (imported on line 1 in 'example.j2') does not export the requested name 'macro2'

很明显这是由于 theme1/common_macros.j2 重写未实现基中的所有宏。
我的问题是:如果不需要重新定义所有的宏,我该怎么做才能使它工作呢 base/common_macros.j2theme1/common_macros.j2 ?
迄今为止我尝试过但失败的方法:
从导入所有宏 base/common_macros.j2 进入 theme1/common_macros.j2 (相当于 from base import * 在python中-记住,我不想在每个主题中写下所有存在于base中的宏名称,否则升级会变得乏味!)。
不幸的是,这并不存在(jinja模板,如何按照dry原则导入所有宏?)
包含基本宏 {% include "base/common_macros.j2" %} 在主题中(类似于 extends 对于非宏模板)。
不幸的是,只有在 theme1/common_macros.j2 可见(根据https://jinja.palletsprojects.com/en/2.10.x/templates/#import)
我非常高兴听到关于如何使用jinja进行主题化的其他想法,如果它能够解决问题并且不会增加复杂性的话。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题