Django模板中如何翻译变量内容

47
我正在使用 {% trans %} 模板标签。Django 文档中说:

{% trans %} 模板标签可以翻译常量字符串(用单引号或双引号括起来)或变量内容:

{% trans "This is the title." %} {% trans myvar %}

https://docs.djangoproject.com/en/4.0/topics/i18n/translation/#translate-template-tag

我发现做 {% trans myvar %} 是不可能的,因为在运行 makemessages 命令后,myvar 在 django.po 文件中根本没有显示出来。

我是用错了吗?有人能帮我解决这个问题吗?


1
你在编辑器中检查模糊关键词了吗?当我使用Rosetta应用程序作为翻译工具时,许多关键词都被保留为模糊状态。 - brsbilgic
它可以翻译变量内容,如其中一个答案所述,但您需要将该内容翻译到django.po文件中并进行编译。 - Bula
9个回答

47

在这种情况下,您可以使用{{link1:blocktrans}}模板标签:

{% blocktrans %} This is the title: {{ myvar }} {% endblocktrans %}

1
但是当我使用这个blocktrans来翻译数据库的值时,它就不起作用了,你能告诉我解决方案吗? - Mohini
2
我可能错了。但是你可能必须这样写,对吗?:{% bolcktrans myvar=myvar %} - Lalaphoon

33

{% trans myvar %}很好用。所以请检查您的PO文件,确保myvar的值在PO消息ID中。

<title>{% trans myvar %}</title>
例如,如果 myvar 包含"Some Publisher",您可以在PO文件中编写以下内容:
msgid "Some Publisher"
msgstr "কিছু প্রকাশক"

另外请确保您已运行:

python manage.py compilemessages

13

Django无法猜测变量中的内容,因此您需要自己进行翻译,方法是添加英文(msgid)和本地化(msgstr)字符串。


1
我已经在django.po中添加了msgid和msgstr,并运行了compilemessages。但是更改语言环境后,变量似乎没有被翻译。我是否漏掉了什么? - thoslin
我也遇到了这个问题,但是Django的compilemessages命令注释掉了我添加的msgid和msgstr。我认为这个答案非常误导人。 - Patrik Beck
1
它对我来说非常有效,只需避免再次运行makemessages,因为那些字符串将无法找到并被注释。 - m0y
5
或者创建另一个虚拟模板文件,包含您变量的所有不同可能值,使用 {% trans "content" %}。这样,makemessages 将自动将它们添加到您的 django.po 文件中。这并不是最优雅的解决方案,但它是可行的。 - m0y
3
在这种情况下,应该使用 noop 吗?根据文档,noop 会在 po 文件中创建一个翻译字符串,但该字符串在网站中不会直接使用。这样一来,您就无需避免运行 makemessages 命令。 - Eduard Luca
显示剩余4条评论

6

我的经验是,变量翻译在模板中不能单独使用。然而,当变量的内容已知时(我指的是它们不是自由文本,而是您在数据库中设置的一组选择),我找到了一个合适的解决方案。

您需要在视图或过滤器标记中强制进行翻译

总之:

  1. 在您的模板中使用blocktrans
  2. 强制变量进行翻译
    • 您可以在上下文中设置已标记为翻译的变量
    • 或使用过滤器进行翻译
  3. 生成.po文件中的翻译

故事是这样的:

views.py

def my_view(request):
    return render(request, 'i18n_test.html', {'salutation':"Hola"})

templates/i18n_test.html

...
{% blocktrans %}{{ salutation }}{% endblocktrans %}
...

当我渲染模板时,无论当前语言是什么,它总是显示Hola

为了强制翻译,在视图中我们需要使用ugettext。

def my_view(request):
    return render(request, 'i18n_test.html', {'salutation':ugettext("Hola")})

然而,并非总是能够访问视图。因此,我更喜欢使用像这样的过滤器。

templatetags/i18n_extras.py

@register.filter(name='translate')
def translate(text):
  try:    
    return ugettext(text)

而模板变成了

...
{% blocktrans s=salutation|translate %}{{ s }}{% endblocktrans %}
...

根据当前语言,它会生成Hola, Hello, Ciao, Salut等内容。

缺点是(正如docs所指出的那样),makemessages不会自动包含这些翻译,因此我们需要手动包括它们。在django.po文件中:

locales/en/django.po

...
msgid "Hola"
msgstr "Hello"
...

1
制作自己的标签
from django.utils.translation import ugettext as _

@register.simple_tag
def trans2(tr, *args, **kwargs):
    # print(':', kwargs)
    trans = _(tr)
    trans_str = trans.format(**kwargs)
    return trans_str

在模板中:
{% trans2 columns_once.res_data.message with value=columns_once.res_data.recommend%}

在django.po文件中。
#: default_content.py:136
msgid "_audit_recommend_speed"
msgstr "Рекомендованная скорость до {value} сек"

1
您可以像这样在Python代码中翻译变量,例如 settings.SITE_NAME:
from django.conf import settings
from django.utils.translation import ugettext_lazy as _

def processor004(request):
 my_dict = {
    'site_id004': settings.SITE_ID,
    'site_name004': _(settings.SITE_NAME),
    'installed_apps004': settings.INSTALLED_APPS,
    'embedded_widget004': settings.EMBEDDED_WIDGET,
    'base_template004': settings.BASE_TEMPLATE,
}

return my_dict

1
作为一种解决方法,您可以在一个模板中收集 {% trans %}(Django 3.0 及以下版本)或 {% translate %}(Django 3.1 及以上版本)标签,在 {% comment %}{% endcomment %} 之间。这将节省您重复键入相同 msgid 的努力,如果您有多个语言 po 文件的话。
{% comment %}
{% trans "Tea" %}
{% trans "Clothes" %}
{% endcomment %.}

确保在放置上述代码后运行 django-admin makemessages --all

似乎不起作用,尽管注释块中的每个可翻译字符串都被忽略了。 - Jeffrey04

0
对我来说,这是在我的Django项目目录之外有TEMPLATES.DIRS时发生的。将模板获取到项目目录中解决了问题。

0

这是一个复杂而优雅的解决方案,如果您需要翻译模型字段的值,它可能会有所帮助:http://django-modeltranslation.readthedocs.org

"Modeltranslation

modeltranslation应用程序用于将现有Django模型的动态内容翻译成任意数量的语言,而无需更改原始模型类。"


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