翻译

编辑本页

警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.4,现已不再维护。

本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

翻译

术语“国际化”(通常缩写为i18n)指的是将字符串和其他特定于语言环境的部分从应用程序抽象到一个层,在这个层中,它们可以根据用户的语言环境(即语言和国家)进行翻译和转换。对于文本,这意味着用一个能够将文本(或“消息”)翻译成用户语言的函数来包装每一个:

1 2 3 4 5 6 7 8
//文本将始终打印出英文转储(“Hello World”);();//文本可以翻译成最终用户的语言或//默认为英文转储(翻译->反式(“Hello World”));();

请注意

这个词语言环境大致指用户的语言和国家。它可以是应用程序用来管理翻译和其他格式差异(例如货币格式)的任何字符串。的ISO 639 - 1语言代码,一个下划线(_),然后ISO 3166-1 alpha-2国家代码(如。fr_FR法语/法国)。

翻译过程有几个步骤:

  1. 启用和配置欧宝娱乐app下载地址Symfony的翻译服务;
  2. 抽象字符串(例如:的调用来封装它们翻译(“翻译”);
  3. 创建翻译资源/文件对于翻译应用程序中每条消息的受支持的语言环境;
  4. 确定,设置和管理用户的语言环境对于请求和可选的在用户的整个会话上

配置

类处理翻译翻译服务,该服务使用用户的语言环境来查找和返回翻译后的消息。使用前,请启用翻译在您的配置中:

  • YAML
  • XML
  • PHP
1 2 3
# app / config / config.yml框架:翻译:回退:(en)

看到翻译有关回退关键字以及当Symfony欧宝娱乐app下载地址找不到翻译时会做什么。

翻译中使用的语言环境是存储在请求中的语言环境。这通常是通过_locale属性(请参阅如何使用用户的语言环境).

基本的翻译

文本的翻译是通过翻译服务(翻译).翻译一个文本块(称为文本块)消息),使用反式()方法。假设,例如,你正在翻译一个来自控制器内部的简单消息:

1 2 3 4 5 6 7 8
/ /……公共函数indexAction()翻译->get (“翻译”->反式(“欧宝娱乐app下载地址Symfony很棒”);/ /……

当执行这段代码时,Symfony将尝试基于欧宝娱乐app下载地址语言环境用户的。为此,您需要告诉Symfony如何通过“翻译资源”翻译消息,“翻译资源欧宝娱乐app下载地址”通常是一个包含给定语言环境的翻译集合的文件。这个翻译“字典”可以用几种不同的格式创建:

  • YAML
  • XML
  • PHP
1 2
# messages.fr.yml欧宝娱乐app下载地址Symfony很棒:欧宝娱乐app下载地址

有关这些文件应位于何处的信息,请参见翻译

现在,如果用户所在地区的语言是法语(例如;fr_FRfr_BE),讯息会被翻译成我Symfon欧宝娱乐app下载地址y.你也可以在你的模板

使用真实消息或关键字消息

这个例子说明了在创建要翻译的消息时的两种不同的哲学:

1 2 3
翻译->反式(“欧宝娱乐app下载地址Symfony很棒”);翻译->反式(“欧宝娱乐app下载地址symfony.great”);

在第一种方法中,消息用默认地区的语言编写(在本例中为英语)。然后在创建翻译时将该消息用作“id”。

在第二种方法中,消息实际上是传达消息思想的“关键字”。然后将关键字消息用作任何翻译的“id”。在这种情况下,必须对默认区域进行翻译(即翻译欧宝娱乐app下载地址symfony.great欧宝娱乐app下载地址Symfony很棒).

第二种方法很方便,因为如果您决定消息在默认语言环境中实际上应该读作“Symfony is really great”,则不需要在每个翻译文件中更改消息键。欧宝娱乐app下载地址

选择使用哪种方法完全取决于您,但“关键字”格式通常推荐用于多语言应用程序,而对于包含翻译资源的共享包,我们推荐使用真实消息,因此您的应用程序可以选择禁用翻译层,并且您将看到可读的消息。

此外,php而且yaml文件格式支持嵌套id,以避免重复使用关键字而不是实际文本的id:

  • YAML
  • PHP
12 3 4 5 6 7 8 9 10 11 12
欧宝娱乐app下载地址symfony:是:# id是sym欧宝娱乐app下载地址fony.is.great大:欧宝娱乐app下载地址伟大的# id是sym欧宝娱乐app下载地址fony.is.amazing惊人的:欧宝娱乐app下载地址令人惊异的有:# id是sym欧宝娱乐app下载地址fy .has.bundles包:欧宝娱乐app下载地址用户:# id是user.login登录:登录

翻译过程

为了真正翻译信息,Symfony使用了一个简单的过程:欧宝娱乐app下载地址

  1. 语言环境当前用户的,哪个存储在请求上;
  2. 从定义的翻译资源中加载翻译消息的目录(即大集合)语言环境(如。fr_FR).来自回退场所如果它们还不存在,也会加载并添加到目录中。最终的结果是一个巨大的翻译“字典”。
  3. 如果消息位于目录中,则返回翻译。如果不是,翻译器将返回原始消息。

当使用反式()方法,Symfo欧宝娱乐app下载地址ny在适当的消息目录中查找确切的字符串并返回它(如果它存在)。

提示

当翻译不在默认域中的字符串时(消息),则必须将域指定为的第三个参数反式()

1
翻译->反式(“欧宝娱乐app下载地址Symfony很棒”[],“管理”);

消息占位符

有时候,包含变量的消息需要被转换:

1 2 3 4 5 6
公共函数indexAction的名字翻译->get (“翻译”->反式(“你好”的名字“!”);/ /……

然而,为这个字符串创建一个翻译是不可能的,因为翻译器将试图查找确切的消息,包括可变部分(例如。“你好瑞恩!”“法比你好!”).而不是为每个可能的迭代编写翻译美元的名字变量,你可以用“占位符”替换变量:

1 2 3 4 5 6 7 8
/ /……公共函数indexAction的名字翻译->get (“翻译”->反式(“你好% %”);/ /……

欧宝娱乐app下载地址Symfony现在将寻找原始消息的翻译(你好% %),然后将占位符替换为它们的值。创建一个翻译就像之前一样:

  • YAML
  • XML
  • PHP
1
“你好% % !”你好%的名字%

请注意

在使用PHP重新构造完整消息时,占位符可以采用任何形式strtr函数.但是,%…%推荐使用Twig的表单,以避免在使用Twig时出现问题。

正如你所看到的,创建一个翻译是一个两步的过程:

  1. 方法对需要翻译的消息进行抽象处理翻译
  2. 为您选择支持的每种语言环境中的消息创建翻译。

第二步是通过创建定义任意数量不同地区的翻译的消息目录来完成的。

多元化的案例

另一个复杂的问题是,当你的翻译可能是复数,也可能不是复数,这取决于一些变量:

1 2
有一个苹果。有5个苹果。

当翻译由于多元化而具有不同的形式时,您可以将所有形式作为由管道(|):

1
“有一个苹果|有%count%苹果”

要翻译这些消息,请使用transChoice ()方法或transchoice标签/过滤器模板.要翻译多元化的消息,请使用transChoice ()方法:

12 3 4 5 6 7 8 9 10 11 12 13
// %count%占位符被分配给第二个参数…->get (“翻译”->transChoice (“有一个苹果|有%count%苹果”10);/ /……但是如果需要,您可以定义更多占位符->get (“翻译”->transChoice (“快点%name%!”还剩一个苹果。|有%count%苹果left.'10//这里不需要包含%count%;欧宝娱乐app下载地址Symfony为你做到了%的名字%的= >用户->getName ()));

第二个参数(10在本例中)是数量对象的转换,并用于确定要使用哪种翻译以及填充%数%占位符。

3.2

在Symfon欧宝娱乐app下载地址y 3.2之前,占位符用于选择复数(%数%类的第三个可选参数中必须包含transChoice ()方法:

1 2 3 4 5
翻译->transChoice (“有一个苹果|有%count%苹果”10, (“%数%”= >10]);

从Symfony 3.2开始欧宝娱乐app下载地址,当唯一的占位符是%数%,你不需要通过第三个参数。

根据给定的数字,翻译人员选择正确的复数形式。在英语中,当只有一个宾语时,大多数单词都是单数形式,而所有其他数字都是复数形式(0,2,3…)。所以,如果1,翻译器将使用第一个字符串(有一个苹果)作为翻译。否则它会使用有%count%苹果

以下是法语翻译:

1
“Il y a %count% pomme|Il y a %count% pommes”

即使字符串看起来很相似(它由两个由管道隔开的子字符串组成),法语的规则是不同的:当使用第一种形式(没有复数形式)时01.因此,翻译器将自动使用第一个字符串(Il y %count% pomme)当01

每个地区都有自己的一套规则,有些地区有多达六种不同的复数形式,并有复杂的规则,哪些数字对应哪些复数形式。对于英语和法语,规则非常简单,但是对于俄语,您可能需要一个提示来知道哪个规则匹配哪个字符串。为了帮助翻译人员,你可以选择“标记”每个字符串:

1 2 3
“one:有一个苹果|some:有%count%苹果”none_or_one: Il y %count% pomme|some: Il y %count% pommes”

这些标签实际上只是给翻译人员的提示,并不影响用来决定使用哪种复数形式的逻辑。标签可以是任何以冒号结尾的描述性字符串().原始消息中的标记也不需要与翻译后的相同。

提示

因为标签是可选的,所以翻译器不会使用它们(翻译器只会根据它在字符串中的位置获得一个字符串)。

显式区间复数

将消息复数化最简单的方法是让Translator使用内部逻辑根据给定的数字选择要使用的字符串。有时,您需要更多的控制,或者想要对特定情况进行不同的翻译(例如0,或者当计数为负数时,例如)。对于这种情况,你可以使用显式的数学间隔:

1
{0}没有苹果|{1}有一个苹果|]1,19]有%count%苹果|[20,Inf[有许多苹果'

时间间隔遵循ISO 31-11符号。上面的字符串指定了四个不同的间隔:完全正确0,完全1三分之一的,20.甚至更高。

您还可以混合显式数学规则和标准规则。在这种情况下,如果计数没有匹配到特定的间隔,则在删除显式规则后,标准规则生效:

1
{0}没有苹果|[20,Inf[有很多苹果|有一个苹果|a_few:有%count%苹果'

例如,对于1苹果,标准规则有一个苹果将被使用。为三分之一的苹果,第二个标准规则有%count%苹果将被选中。

一个时间间隔可以表示一个有限的数字集:

1
{1, 2, 3, 4}

或两个数之间的数:

1 2
[1, +Inf[]-1,2[

左边的分隔符可以是(包容)或(独家)。正确的分隔符可以是(独家)或(包容)。除了数字,你还可以用而且+正为了无限。

模板中的翻译

大多数时候,翻译发生在模板中。欧宝娱乐app下载地址Symfony为Twig和PHP模板提供了本地支持。

树枝模板

欧宝娱乐app下载地址Symfony提供了专门的Twig标记(反式而且transchoice),协助翻译静态文本块

1 2 3 4 5
{%反式%}你好% %{%endtrans%}{%transchoice数%}{0}没有苹果|{1}有一个苹果|]1,Inf[有%count%苹果{%endtranschoice%}

transchoice标记自动获取%数%变量,并将其传递给翻译器。方法后面使用占位符时,此机制才有效% var %模式。

谨慎

% var %在Twig模板中使用标签翻译时,需要使用占位符符号。

提示

如果需要使用百分比字符(),通过加倍来转义它:{% trans %}百分比:%%% %%{% endtrans %}

你也可以传递一些额外的变量并指定消息域:

1 2 3 4 5 6 7
{%反式用{'%name%': 'Fabien'}变成'fr' %}你好% %{%endtrans%}{%transchoice使用{'%name%': 'Fabien'} %}进行计数{0} %name%,没有苹果|{1}%name%,有一个苹果|]1,Inf[%name%,有%count%苹果{%endtranschoice%}{%反式with {'%name%': 'Fabien'} from 'custom_domain' %}你好% %{%endtrans%}

反式而且transchoice过滤器可以用来翻译变量文本复杂表达式:

1 2 3 4 5 6 7
{{message|trans}}{{message| transschoice (5)}}{{message|trans({'%name%': 'Fabien'}, 'app')}}{{{消息| transchoice(5日‘%名称%’:‘法’},“应用程序”)}}

提示

使用翻译标记或过滤器具有相同的效果,但有一个细微的区别:自动输出转义仅应用于使用过滤器的翻译。换句话说,如果你需要确保你翻译的信息是正确的输出转义后,必须应用转换过滤器后的过滤器:

1 2 3 4 5 6 7 8 9 10
{#标签之间翻译的文本永远不会转义#}{%反式%}<h3>喷火h3>{%endtrans%}{%消息= '

foo

' %}
默认情况下,通过过滤器转换的字符串和变量将转义#}{{消息反式| |}}{{'酒吧< h3 > < / h3 > |反式|}}

提示

你可以用一个标签为整个Twig模板设置翻译域:

1
{%trans_default_domain“应用程序”%}

请注意,这只影响当前模板,而不影响任何“包含”模板(以避免副作用)。

PHP模板

在PHP模板中,可以通过翻译助手:

1 2 3 4 5 6 7
<?视图“翻译”->反式(“欧宝娱乐app下载地址Symfony很棒”? ><?视图“翻译”->transChoice ({0}没有苹果|{1}有一个苹果|]1,Inf[有%count%苹果'10, (“%数%”= >10])? >

强制译者的语言环境

在翻译消息时,翻译人员将使用指定的区域设置或回退现场(如果需要的话)。你也可以手动指定要用于翻译的语言环境:

12 3 4 5 6 7 8 9 10 11 12 13 14
翻译->反式(“欧宝娱乐app下载地址Symfony很棒”[],“消息”“fr_FR”);翻译->transChoice ({0}没有苹果|{1}有一个苹果|]1,Inf[有%count%苹果'10[],“消息”“fr_FR”);

翻译内容自动提取与目录自动更新

翻译应用程序时最耗时的任务是提取要翻译的所有模板内容,并保持所有翻译文件的同步。欧宝娱乐app下载地址Symfony包含一个名为翻译:更新这可以帮助你完成以下任务:

1 2 3 4 5
#更新法语翻译文件,在app/Resources/ templates中找到缺失的字符串PHP bin/控制台转换:update——dump-messages——force fr#更新英文翻译文件,使用AppBundle中丢失的字符串php bin/控制台翻译:update——dump-messages——force en AppBundle

请注意

如果希望在不实际更新翻译文件的情况下查看缺失的翻译字符串,请删除——力选项。

提示

如果您需要从其他来源(如控制器、表单和flash消息)提取翻译字符串,请考虑使用更高级的第三方TranslationBundle

翻译资源/文件名称和位置

欧宝娱乐app下载地址Symfony在以下默认位置查找消息文件(即翻译):

  • 翻译/目录(在项目的根目录);
  • 应用程序/资源/翻译目录;
  • 应用程序/资源/ <包名称> /翻译目录;
  • 资源/翻译/目录中的任何包。

这里列出的位置优先级最高。也就是说,您可以覆盖前2个目录中的任何一个包的翻译消息。

覆盖机制在键级别上工作:只有被覆盖的键需要列在优先级更高的消息文件中。当在消息文件中没有找到键时,转换器将自动退回到优先级较低的消息文件。

翻译文件的文件名也很重要:每个消息文件必须按照以下路径命名:domain.locale.loader

  • :域是将消息组织到组中的一种方法。除非应用程序的各个部分显式地彼此分离,否则建议只使用默认值消息域(如。messages.en.yaml).
  • 语言环境:翻译的语言环境(例如:en_GB等);
  • 加载程序Symfon欧宝娱乐app下载地址y应该如何加载和解析文件(例如:xlfphpyml等等)。

加载器可以是任何已注册加载器的名称。默认情况下,Symfon欧宝娱乐app下载地址y提供了许多加载器:

  • .yaml: YAML文件
  • .xlf: XLIFF文件;
  • . php:返回PHP数组;
  • . csv: CSV文件;
  • . json: JSON文件;
  • . ini: INI文件;
  • .datr: ICU资源包;
  • mo:机器对象格式;
  • .po:可移植对象格式;
  • .qt: QT Translations XML文件;

选择使用哪个加载器完全取决于您,这是一个品味问题。建议在简单项目中使用YAML,如果使用专门的程序或团队生成翻译,则使用XLIFF。

谨慎

每次创建消息目录(或安装包含翻译目录的包),请确保清除缓存,以便Symfony可以发现新的翻译资源:欧宝娱乐app下载地址

1
PHP bin/控制台缓存:清除

请注意

属性可以添加其他目录路径配置中的选项:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / config.yml框架:翻译:道路:-' % kernel.project_dir % /翻译'

请注意

类的自定义类实现,也可以将翻译存储在数据库或任何其他存储中LoaderInterface接口。看到内置的Symfon欧宝娱乐app下载地址y服务标签标签以获取更多信息。

备用翻译区域设置

假设用户的语言环境是fr_FR你在转换键欧宝娱乐app下载地址Symfony很棒.为了找到法语翻译,Symfony实际上检查了几个地区的翻译资源:欧宝娱乐app下载地址

  1. 首先,Symf欧宝娱乐app下载地址ony在fr_FR翻译资源(例如:messages.fr_FR.xlf);
  2. 如果没有找到,Symfony将在欧宝娱乐app下载地址fr翻译资源(例如:messages.fr.xlf);
  3. 如果仍然没有找到翻译,Symfony将使用欧宝娱乐app下载地址回退参数,默认为(见配置).

请注意

当Symf欧宝娱乐app下载地址ony在给定的语言环境中没有找到翻译时,它将把缺少的翻译添加到日志文件中。详细信息请参见框架配置参考(FrameworkBundle)

处理用户的语言环境

翻译是基于用户的语言环境进行的。读如何使用用户的语言环境了解更多如何处理它。

翻译数据库内容

数据库内容的翻译应由Doctrine通过可翻译扩展或者是可翻译行为(PHP 5.4 +)。有关更多信息,请参阅这些库的文档。欧宝体育电话

调试翻译

当您处理不同语言的许多翻译消息时,可能很难跟踪哪些翻译丢失了,哪些翻译不再使用。读如何查找缺失或未使用的翻译信息找出如何识别这些信息。

总结

使用Symfony欧宝娱乐app下载地址 Translation组件,创建国际化应用程序不再是一个痛苦的过程,可以归结为几个基本步骤:

  • 抽象应用程序中的消息,方法是将每个消息包装在反式()transChoice ()方法;
  • 通过创建翻译消息文件将每条消息翻译成多个地区。欧宝娱乐app下载地址Symfony发现并处理每个文件,因为它的名称遵循特定的约定;
  • 管理用户的语言环境,该语言环境存储在请求中,但也可以在用户的会话中设置。
此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。