首页 > 解决方案 > 使用长 `with` 子句替代 blocktrans 标记

问题描述

语境

我正在尝试使用 django 模板引擎使用上下文中的变量来呈现页面的可翻译部分。具体来说,这是我的用例

{% blocktrans trimmed with type=training.type title=training.title city=training.city %}
Training {{ type }} "{{ title }}" at {{ city }}
{% endblocktrans %}

这很好用,但是,我的问题是blocktrans长度在可接受的范围内增长得非常快(至少对我而言)。

作为替代方案,我可以做

    {% with training.title as title %}
    {% with training.type as type %}
    {% with training.city as city %}
    {% blocktrans trimmed %}
    Training {{ type }} "{{ title }}" at {{ city }}
    {% endblocktrans %}
    {% endwith %}
    {% endwith %}
    {% endwith %}

或者使用一个单独的 with 子句。

但这并不能真正简化该代码的可读性,尤其是在有更多变量要暴露给翻译字符串的情况下。

我想到的解决方案

我最初的想法是将 blocktrans 标签扩展到几行:

{% blocktrans trimmed with 
    type=training.type
    title=training.title
    city=training.city %}
Training {{ type }} "{{ title }}" at {{ city }}
{% endblocktrans %} 

对我来说不幸的是,django 不支持模板中的多行标签。

(有关原因,请参阅 django邮件列表上相当冗长的讨论)。

问题

由于我在上述讨论中没有找到解决方案,因此我正在寻找一种方法来获得与我的第一个代码相同的结果,而不会因为过长的行/大块的with标签而妨碍我的模板可读性。

我考虑过将该代码放在其他地方,就像@property模型中的方法training所基于的那样。但在我看来,该逻辑属于模板,(它不太可能在其他任何地方使用)。

在 django 中是否有另一种惯用的方法来实现这一点?

标签: djangodjango-templatesinternationalizationreadabilitydjango-context

解决方案


一种方法是创建一个自定义模板标签来设置模板内的变量

from django import template

register = template.Library()

@register.simple_tag
def setvar(val):
    return val

并在模板中

{% load setvar %}
{% setvar training.title as title %}
{% setvar training.type as type %}
{% setvar training.city as city %}
{% blocktrans trimmed %}
    Training {{ type }} "{{ title }}" at {{ city }}
{% endblocktrans %}

这也支持过滤器,例如

{% setvar training.title|title as title %}

推荐阅读