如何在 Jinja2 中对字符串执行多次替换?

How to perform multiple replacements on string in Jinja2?

我有 Pelican website with bootstrap3 主题。该主题使用 Font Awesome 将 link 的图标放置到社交媒体帐户中。 Font Awesome class 名称是通过将 link 文本小写并用破折号替换所有空格来确定的。

问题是,有时我的 link 文本没有映射到 Font Awesome class 名称。例如,信封图标是由 envelope class 提供的,但我真的希望 Email 作为网站上的 link 文本。

我可以在 Font Awesome 样式表中更改 class 名称,但是我将无法使用 Bootstrap CDN,每次我将 Font Awesome 更新为新版本。

我决定改为修改 Pelican 模板,并在写入 class 名称之前进行必要的转换。到目前为止,我的代码如下所示:

{% set name_sanitized = name|lower|replace('+','-plus')|replace(' ','-')|replace('stackexchange', 'stack-exchange')|replace('rss-feed', 'rss')|replace('email', 'envelope') %}

我可以使用 dict 替换此 replace 调用链吗?像这样:

{% set replacements = dict('+' = '-plus', ' ' = '-', 
                          'stackexchange' = 'stack-exchange', 'rss-feed' = 'rss',
                          'email' = 'envelope') %}
{% set name_sanitized = name|lower|??? %}

如果不是,是否有任何其他方法可以使这部分在长期内更具可读性和可维护性?

这看起来像是 custom Jinja2 filter 的工作。

def dict_replace(text, replacements):
    for key, val in replacements.iteritems():
        text = text.replace(key, val)
    return text

将过滤器添加到您的 Pelican config file:

JINJA_FILTERS = {'dict_replace': dict_replace}

然后在您的模板中使用过滤器:

{% set name_sanitized = name|lower|dict_replace(replacements) %}

或者,您可以直接在 Jinja2 中实现它,但这很尴尬。

{% set _name_sanitized = {'': name|lower} %}
{% for key, val in replacements.items() %}
    {% if _name_sanitized.update('', _name_sanitized['']|replace(key, val) %}{% endif %}
{% endfor %}
{% set name_sanitized = _name_sanitized[''] %}

_name_sanitized 变量是必需的,因为循环在 Jinja2 中有自己的范围,所以你不能只用 set.

更新变量