使用Django实现基于翻译键的国际化

91zkwejq  于 2023-03-04  发布在  Go
关注(0)|答案(4)|浏览(141)

Django默认的i18 n系统使用代码语言(例如,英语)作为翻译键;翻译成其他语言必须从基本语言编写。例如,在Django模板中,您可以编写{% trans "Hello" %},然后在法语或西班牙语翻译文件中将“Hello”翻译成“Bonjour”或“Hola”。
这有一个重大缺陷:在英语中拼写相同的单词在其他语言中不能有不同的翻译。例如,如果我在代码的两个地方使用{% trans "Fire" %},其中一个表示燃烧的东西,另一个表示大炮,我需要在法语中分别使用“Feu”和“Tirer”;但Django的i18 n迫使我为“Fire”选择一个单一的翻译。
转换键模式解决了这个问题:我在代码中使用了诸如{% trans "campsite.fire" %}{% trans "cannon.fire" %}这样的翻译键,在英语翻译文件中我将它们分别翻译为“Fire”,在法语文件中分别翻译为“Feu”和“Tirer”。
Django的i18 n系统支持这种用法吗?我如何将变量注入到这样的翻译中?

kqhtkvqz

kqhtkvqz1#

我目前(但很笨拙)的工作方式是:

  • 使用诸如{% trans "cannon.fire" %}的转换密钥
  • 如果需要使用变量,请使用转换键 *,后跟变量 *:

{% blocktrans %}email.password_reset.click_link {{link}}{% endblocktrans %}
然后,在我的翻译中,我可以使用链接变量%(link)s
感觉像是无意中的使用,和doc很不一样,可能有更官方的方法来做到这一点。

ohtdti5x

ohtdti5x2#

是的,这是可能的.键可以是任何匹配的字符串,或短语.
template.html

{% trans "cannon.fire" %} 
{% trans "campsite.fire" %}

po文件:

msgid "cannon.fire"
msgstr "Tirer"

msgid "campsite.fire"
msgstr "Feu"

对于翻译中的变量,有一个blocktranslate标签允许在翻译中使用变量。

{% blocktranslate %} hello my name is {{ name }} {% endblocktranslate %}

也可以在渲染上下文中转换变量:

{% translate myvar %}
0yg35tkg

0yg35tkg3#

Django支持contextual markers正是为了这个目的:

<p>{% translate "Fire" context "Literal fire" %}</p>
<p>{% translate "Fire" context "Shooting something" %}</p>

会变成

msgctxt "Literal fire"
msgid "Fire"
msgstr ""

msgctxt "Shooting something"
msgid "Fire"
msgstr ""

文件:www.example.comhttps://docs.djangoproject.com/en/4.1/topics/i18n/translation/#contextual-markers

4ngedf3f

4ngedf3f4#

我最近对Django Framework中同样的概念感到恼火,我看了react和python中i18n库的例子,以及其他过去的经验,有很多原因会让人倾向于使用keys而不是plain text进行翻译。
下面是一个在文本中包含变量的工作解决方案,但可能有点烦人。
Django 这边:

from django.utils.translation import gettext_lazy as _

TEXT = str(_("some.key")).format(count=10)

在po文件中:

msgid "some.key"
msgstr "Number of balls: {count}"

用法:

>>> print(TEXT)
# Number of balls: 10
    • 我还没有在Django模板中测试过**所以我不能确定它在那里是如何工作的,你可能可以为它编写插件。但是对于rest框架的使用来说,这应该足够了。

相关问题