第十三章——I18n, L10n
如果你开发了一个国际申请,你知道处理文本翻译的方方面面,当地标准和本地化内容可以是一个噩梦。幸运的是,symfony本ob娱乐下载机自动化方面的国际化。
长的一个单词,开发人员常常把国际化作为i18n (count中的字母词知道为什么)。被称为l10n本地化。它们覆盖的两个不同方面多语言的web应用程序。
国际化应用程序包含几个版本的相同的内容在不同的语言或格式。例如,一个邮箱界面在几种语言可以提供相同的服务;只有接口更改。
本地化应用程序包含不同的信息按照国家的浏览。思考新闻门户网站的内容:当浏览来自美国,它显示的最新头条的美欧宝平台是合法的吗国,但当浏览来自法国,法国新闻头条新闻关注。所以l10n翻译应用程序不仅提供内容,但内容可以不同从一个到另一个本地化版本。
总之,处理i18n l10n意味着应用程序可以照顾下列:
- 文本翻译(接口、资产和内容)
- 标准和格式(日期、数量、数字等)
- 本地化内容(许多版本的一个给定的对象根据一个国家)
本章涵盖了symfony的方式处理这些元素,以及如何使用ob娱乐下载它来开发国际化和本地化的应用程序。
用户的文化
所有内置的i18n特性在symfony是基于用户会话被称为文化的一个ob娱乐下载参数。文化的结合国家和用户的语言,它决定如何显示文本和文化相关的信息。因为它是序列化的用户会话,页面之间的文化是持久的。
设置默认的文化
默认情况下,新用户的文化default_culture
。您可以更改此设置settings.yml
配置文件,见清单的佳绩。
清单的佳绩,设置默认的文化,前端/ config / settings.yml
所有:.settings: default_culture: fr_FR
请注意
在开发期间,你可能会惊讶,一个文化的变化settings.yml
文件不改变当前文化在浏览器中。这是因为会话已经有一个文化从之前的页面。如果你想看新的默认的应用程序文化,你需要清楚域饼干或重启浏览器。
保持语言和国家的文化是必要的,因为你可能有不同的法语翻译为用户从法国,比利时,加拿大,和一个不同的用户从西班牙和墨西哥西班牙语的内容。语言是两个小写字符编码,根据ISO 639 - 1标准(例如,在
英语)。这个国家是两个大写字符编码,根据ISO 3166 - 1标准(例如,GB
英国)。
改变用户的文化
文化可以改变用户在浏览会话——例如,当用户决定从英文版本切换到法国版本的应用程序,或者当用户登录到应用程序,并使用语言存储在他的偏好。这就是为什么sfUser
类提供了用户文化的getter和setter方法。清单13 - 2展示了如何使用这些方法在一个行动。
清单13 - 2 -设置和检索的文化行动
/ /文化setter这个美元- >getUser()- >setCulture(“en_US”);/ /文化getter美元的文化=这个美元- >getUser()- >getCulture();= > en_US
侧边栏
文化在URL中
当使用symfony的ob娱乐下载本地化和国际化功能,对单个URL的页面往往有不同的版本——这一切都取决于用户会话。这可以防止你缓存或在搜索引擎索引页面。
一个解决方案是使文化出现在每一个URL,这样翻译页面可以被视为不同的URL到外面的世界。为了做到这一点,添加:sf_culture
令牌在应用程序的每一条规则routing.yml
:
页面:url: /: sf_culture /:页面参数:……要求:{sf_culture:(?:身材为fr | |)}文章:url: /: sf_culture /: /:月/:/天:蛞蝓参数:…要求:{sf_culture:(?:身材为fr | |)}
为了避免手动设置sf_culture
在每一个请求参数link_to ()
syob娱乐下载mfony自动添加用户文化缺省路由参数。它还入站工作因为symfony会自动改变用户文化如果ob娱乐下载sf_culture
参数是在URL中找到。
自动确定文化
在许多应用程序中,用户文化定义在第一个请求中,基于浏览器的偏好。用户可以定义一个列表接受语言的浏览器,这与每个请求发送到服务器,数据接收语言
HTTP报头。你可以在symfony通过检索它ob娱乐下载sfWebRequest
对象。例如,获得用户的首选语言列表中一个动作,类型:
美元的语言=美元的请求- >getLanguages();
HTTP报头是一个字符串,但是symfony自动解析它并将它转换为ob娱乐下载一个数组。所以用户访问的首选语言语言[0]美元
在前面的例子。
可以有用自动设置用户的首选浏览器语言文化网站所有页面的主页或过滤器。但是你的网站可能只支持一组有限的语言,它是更好的使用getPreferredCulture ()
方法。它返回最好的语言通过比较用户首选语言和所支持的语言:
美元的语言=美元的请求- >getPreferredCulture(数组(“en”,“fr”));/ /中可用的网站是英语和法语
如果没有匹配,方法返回第一个支持语言(在
在前面的例子)。
谨慎
的接收语言
HTTP头不是很可靠的信息,因为用户很少知道如何修改它在他们的浏览器。在大多数情况下,浏览器的首选语言的语言界面,和浏览器并不适用所有的语言。如果你决定设置文化自动根据浏览器首选语言,确保为用户提供了一种方法来选择另一种语言。
标准和格式
一个web应用程序的内部不关心文化特质。数据库,例如,使用国际标准存储日期,数量,等等。但是,当数据被发送到或从用户检索,需要进行转换。用户不会理解时间戳,他们会更愿意宣布他们的母语为法语,而不是法语。所以你需要援助的自动转换,基于用户的文化。
输出数据在用户的文化
一旦定义了文化,助手取决于它会自动有适当的输出。例如,format_number ()
助手自动显示一个数字的格式熟悉的用户,根据其文化,如清单13所示。
清单13 -为用户显示一个数字的文化
< ? phpuse_helper(“数量”)? >< ? phpsf_user美元- >setCulture(“en_US”)? >< ? php回声format_number(12000.10)? >= >12000 .10< ? phpsf_user美元- >setCulture(“fr_FR”)? >< ? php回声format_number(12000.10)? >= >的12 000年10
你不需要显式地将文化传递给帮手。他们会寻找它自己在当前会话对象。常规清单列出了帮手,考虑用户文化输出。
常规清单——文化相关的帮手
< ? phpuse_helper(“日期”)? >< ? php回声format_date(时间())? >= >“9/14/10”< ? php回声format_datetime(时间())? >= >“2010年9月14日下午6:11:07 c”< ? phpuse_helper(“数量”)? >< ? php回声format_number(12000.10)? >= >12000 .10< ? php回声format_currency(1350年,“美元”)? >= >“1350美元”< ? phpuse_helper(“国际化”)? >< ? php回声format_country(“我们”)? >= >“美国”< ? phpformat_language(“en”)? >= >“英语”< ? phpuse_helper(“形式”)? >< ? php回声input_date_tag(“birth_date”,mktime(0,0,0,9,14,2010年))? >输入type = = >“文本”name =“birth_date”id =“birth_date”值=“9/14/10”大小=“十一”/ >< ? php回声select_country_tag(“国家”,“我们”)? >= = > <选择名称“国家”id =“国家”> <选项值=“对焦”阿富汗> < /选项>…<选项值=“GB”英国< / >选项> <选项值=“我们”选择=“选择”美国< / >选项> <选项值=“嗯”美国小离岛> < /选项> < =选项值“UY”乌拉圭< / >选项>…< /选择>
助手可以接受额外的日期格式参数强制显示文化无关,但你不应该使用它如果您的应用程序国际化。
使数据从一个局部的输入
如果需要显示数据在用户的文化、检索数据,你应该尽可能把用户应用程序的输入已经国际化的数据。这种方法可以节省从试图找出如何将数据在不同格式和不确定的地方。例如,他们可能会进入一个货币价值与逗号分隔符在一个输入框?
你可以通过隐藏用户输入帧格式(例如在实际的数据select_country_tag ()
)或分离的不同组件复杂数据分成几个简单的输入。
然而,日期,这通常是不可能的。用户习惯于以自己的文化格式输入日期,你需要将这些数据转换成内部(国际)格式。这就是sfI18N
类应用。清单13比5演示了如何使用这个类。
清单13比5 -得到约会在一个动作从本地化的格式
美元的日期=美元的请求- >getParameter(“birth_date”);user_culture美元=这个美元- >getUser()- >getCulture();/ /时间戳美元的时间戳=这个美元- >getContext()- >getI18N()- >getTimestampForCulture(美元的日期,user_culture美元);/ /得到一个结构化的日期列表(美元d,m美元,$ y)=这个美元- >getContext()- >getI18N()- >getDateForCulture(美元的日期,user_culture美元);
数据库中的文本信息
本地化应用程序提供不同的内容根据用户的文化。例如,网上商店可以提供全球产品在相同的价格,但在一个定制的描述每一个国家。这意味着数据库必须能够存储不同版本的一个给定的数据,为此,你需要设计模式在一个特定的方式,用文化每次操作局部模型对象。
创建本地化模式
为每个表,其中包含一些本地化的数据,你就应该把这个表两部分:没有任何i18n列一个表,另一个只有i18n列。这两个表是一对多的关系。这个设置允许您添加更多的语言当你需要在不改变模型。让我们考虑一个例子使用产品
表。
首先,创建表schema.yml
文件,如清单13所示。
清单13 -样本模式i18n数据与推动,配置/ schema.yml
my_connection: my_product: _attributes: {isI18N phpName:产品:真的,i18nTable: my_product_i18n},{类型:整数,要求:真的,primaryKey:真的,自动增量:真正}价格:{类型:浮动}my_product_i18n: _attributes: {phpName: ProductI18n},{类型:整数,要求:真的,primaryKey:真的,foreignTable: my_product, foreignReference: id}文化:{isCulture:真的,类型:varchar、大小:7,要求:真的,primaryKey:真正}名称:{类型:varchar、尺寸:50}
注意到isI18N
和i18nTable
在第一个表属性,特殊文化
列第二。所有这些都是symfony-ob娱乐下载specific推动改进。
清单13 -样本模式i18n数据与教义,配置/理论/ schema.yml
产品:找:I18n:字段:[名字]列:价格:{类型:浮动}名称:{类型:字符串(50)}
symfob娱乐下载ony的自动化可以写快得多。如果表包含国际化数据具有相同的名称作为主要的表_i18n
作为后缀,它们与一个列命名id
在两个表中,可以省略了id
和文化
列_i18n
表以及特定的i18n属性主要表;ob娱乐下载symfony会推断出他们。这意味着symfony会看到ob娱乐下载清单13-8中的模式如清单13一样的人。
为i18n清单13-8 -样本模式数据,短的版本,配置/ schema.yml
my_connection: my_product: _attributes: {phpName:产品}id:价格:浮动my_product_i18n: _attributes: {phpName: ProductI18n}名称:varchar (50)
使用生成的I18n对象
一旦建立了相应的对象模型(不要忘记调用推动:构建——模型
每次修改后的任务schema.yml
),你可以用你的产品
类与i18n支持好像只有一个表,如清单13-9所示。
清单13-9 -处理i18n对象
美元的产品= ProductPeer::retrieveByPk(1);美元的产品- >setName(“杜以前的产品”);/ /默认情况下,文化是当前用户的文化美元的产品- >保存();回声美元的产品- >getName();= >“杜以前的产品”美元的产品- >setName(“产品名称”,“en”);/ /改变的值“en”文化美元的产品- >保存();回声美元的产品- >getName(“en”);= >“产品名称”
至于查询与对等的对象,你可以限制结果对象有一个翻译为当前文化使用doSelectWithI18n
方法,而不是通常的doSelect
如清单13 - 10所示。此外,它将创建相关i18n对象的同时,定期的,导致数量减少的查询完整的内容(参见第18章为更多的信息关于这个方法的积极影响性能)。
清单13 - 10 -检索对象i18n标准
$ c=新标准();$ c- >添加(ProductPeer::价格,One hundred.标准::LESS_THAN);美元的产品= ProductPeer::doSelectWithI18n($ c,美元的文化);/ /美元文化参数是可选的/ /当前用户使用文化如果没有文化
基本上,你不应该和i18n对象直接接触,而是通过文化模型(或让它想它)每次查询一般的对象。
界面翻译
i18n应用程序的用户界面需要适应。模板必须能够显示标签,在几种语言信息,导航,但同样的演讲。ob娱乐下载Symfony建议你建立你的模板使用默认语言,和你提供的翻译短语在字典文件模板中使用。这样,你不需要改变你的模板每次修改、添加或删除一个翻译。
配置翻译
模板没有翻译在默认情况下,这意味着你需要激活模板翻译功能settings.yml
文件之前,一切,见清单骁将。
清单骁将-激活界面翻译,前端/ config / settings.yml
:.settings: i18n:真的
使用翻译助手
假设您希望创建一个网站在英语和法语,英语是默认的语言。之前考虑翻译网站之后,你可能写的模板类似清单13-12示例所示。
清单13-12——一个单一语种的模板
欢迎来到我们的网站。今天的日期是< ?php echo format_date(日期())?
在symob娱乐下载fony的短语翻译模板,他们必须确定为文本翻译。这是的目的__ ()
辅助(两个下划线),I18N辅助集团的一员。所以你所有的模板需要附上的短语翻译这样的函数调用。清单骁将,例如,可以修改像清单13-13(正如您将看到的“处理复杂的翻译需要“在本章后面部分,有一个更好的方法调用翻译助手在这个例子)。
清单13-13 - Multiple-Language-Ready模板
< ? phpuse_helper(“国际化”)? >< ? php回声__(欢迎来到我们的网站。)? >< ? php回声__(“今天的日期)? >< ? php回声format_date(日期())? >
提示
如果您的应用程序使用I18N助手组的每一页,这可能是一个好主意的standard_helpers
设置在settings.yml
文件,以便您避免重复use_helper (I18N)
为每个模板。
使用字典文件
每一次__ ()
函数被调用时,symfony查找词典翻译ob娱乐下载它的参数的当前用户的文化。如果找到一个相应的短语,翻译是在响应中返回并显示。所以用户界面翻译依赖于字典文件。
字典文件都写在XML本地化文件交换格式(XLIFF),根据命名模式消息。(语言代码). xml
,并存储在应用程序i18n /
目录中。
XLIFF是一个基于XML的标准格式。如众所周知,您可以使用第三方翻译工具参考所有文本在你的网站和翻译。翻译公司知道如何处理这些文件和翻译整个网站仅仅通过添加一个新的XLIFF翻译。
提示
除了XLIFF标准,symfony还支持其他词典翻译后端:gettexob娱乐下载t, MySQL和SQLite。请查阅API文档关于这些后端配置的欧宝官网下载app更多信息。
清单13显示了一个示例的XLIFF语法messages.fr.xml
所需文件清单13-13翻译成法语。
清单13 - 14日- XLIFF字典,前端/ i18n / messages.fr.xml
< ? xml版本=“1.0”编码=“utf - 8”? >< !DOCTYPE xliff公共”——/ / xliff / / DTD xliff / / EN " " http://www.oasis-open.org/committees/xliff/documents/xliff.dtd " >< xliff版本=“1.0”><文件原始=“全球”通过读=“en_US”数据类型=“明文”><身体>< trans-unitid=“1”><源>欢迎来到我们的网站。< /来源><目标>欢迎在我们的web站点。< /目标>< / trans-unit>< trans-unitid=“2”><源>今天的日期是< /来源><目标>La日期d会好< /目标>< / trans-unit>< /身体>< /文件>< / xliff>
的通过读
属性必须包含完整的ISO代码默认文化。每个翻译写的trans-unit
标签与一个独特的id
属性。
使用默认用户文化(设置为en_US
),短语翻译的原始参数__ ()
显示调用。清单13-12的结果类似于清单骁将。然而,如果文化改变fr_FR
或fr_BE
的翻译messages.fr.xml
文件显示,结果如清单13 - 15所示。
清单13 - 15 -翻译模板
欢迎在我们的web站点。拉日期d“今天”回族是< ? php回声format_date(日期())? >
如果需要做额外的翻译,只需添加一个新的messages.XX.xml
翻译文件在同一目录中。
提示
找字典文件,解析它们,找到正确的翻译对于一个给定的字符串需要一些时间,symfony使用内部缓存加速的过程。ob娱乐下载默认情况下,这个缓存使用的文件系统。您可以配置i18N缓存是如何工作的(例如,在多个服务器之间共享缓存)factories.yml
(见19章)。
管理字典
如果你的messages.XX.xml
文件太长是可读的,你总是可以把翻译分成几个字典文件,命名的主题。例如,您可以将messages.fr.xml
文件到这三个文件的应用程序i18n /
目录:
navigation.fr.xml
terms_of_service.fr.xml
search.fr.xml
注意,一旦翻译并不是默认的messages.XX.xml
文件,你必须声明这字典是每次调用使用__ ()
助手,使用它的第三个参数。例如,输出一个字符串翻译的navigation.fr.xml
字典,写这个:
< ? php回声__(欢迎来到我们的网站的,零,“导航”)? >
组织翻译字典的另一种方法是将它们分割模块。而不是写一个messages.XX.xml
文件为整个应用程序中,您可以编写一个模块/ [module_name] / i18n /
目录中。它让模块更独立于应用程序,这是必要的,如果你想重用他们,比如在插件(见第17章)。
手动更新i18n字典是很容易出错,symfony提供了任务自动化流程。ob娱乐下载的i18n:提取
任务解析一个symfony应ob娱乐下载用提取的所有字符串需要翻译。需要一个应用程序和一个文化作为它的参数:
php syob娱乐下载mfony i18n:美元提取前端en
默认情况下,任务不修改你的字典,它只是输出新老i18n字符串的数量。新字符串附加到你的字典,你可以通过——自动保存
选择:
美元php ob娱乐下载symfony i18n:提取——自动保存前端
你也可以通过自动删除旧的字符串——auto-delete
选择:
php syob娱乐下载mfony i18n:美元提取——自动保存auto-delete前端
请注意
当前任务有一些已知的限制。它只能使用默认值消息
词典和基于文件的后端(XLIFF
或gettext
),它只保存和删除字符串在主应用程序/前端/ i18n / messages.XX.xml
文件。
处理其他元素需要翻译
以下是其他元素,可能需要翻译:
图像、文本文档或任何其他类型的资产也可以根据用户不同的文化。最好的例子是一段文字与一个特殊的排版,实际上是一个形象。对于这些,您可以创建子目录命名的用户
文化
:< ? php回声image_tag(sf_user美元- >getCulture()。' / myText.gif ')? >
从验证文件会自动输出错误消息
__ ()
,所以你只需要添加他们的翻译字典翻译。- 默认symfony页面(ob娱乐下载页面没有找到,内部服务器错误,限制访问,等等)都是英文的,必须重写的i18n的应用程序。您应该创建自己的
默认的
模块在您的应用程序和使用__ ()
在它的模板。指第十九章如何定制这些页面。
处理复杂的翻译需求
只翻译,如果是有道理的__ ()
参数是一个完整的句子。然而,当你有时有格式化或变量混合的话,你可能会把句子切成几块,因此调用辅助毫无意义的短语。幸运的是,__ ()
助手提供了一个基于令牌替换功能,这将帮助你拥有一个有意义的翻译字典,更容易处理。与HTML格式,你可以把它在辅助调用。清单13 - 16显示了一个示例。
清单13 - 16 -翻译句子包含的代码
/ /基本的例子欢迎所有的< b > < / b >新用户。< br / >< ? php回声count_logged()? >人记录。/ /启用文本翻译的不错方式< ? php回声__(“欢迎”)? >< b > < ? php回声__(“新”)? > < / b >< ? php回声__(“用户”)? >。< br / >< ? php回声__(“有”)? >< ? php回声count_logged()? >< ? php回声__(“个人登录”)? >/ /启用文本翻译的好方法< ? php回声__(“欢迎< b > < / b >新用户”)? >< br / >< ? php回声__(“有1% %的人记录”,数组(“% 1%”= > count_logged()))? >
在这个例子中,令牌% 1%
,但它可以是任何东西,因为使用的替代功能翻译助手strtr ()
。
翻译的一个常见的问题是使用复数形式。根据结果的数量,文本变化但不以同样的方式根据语言。例如,清单13 - 16中的最后一句话是不正确的count_logged ()
返回0或1。你可以做一个测试在这个函数的返回值,并据此选择使用哪一个句子,但是这也代表了很多代码。此外,不同的语言有不同的语法规则,和复数词尾变化规则可以相当复杂。这个问题很常见,symfony提供了一个助手来处理它,ob娱乐下载format_number_choice ()
。清单13 - 17展示了如何使用这个帮手。
清单- -翻译句子根据参数的值
< ? php回声format_number_choice(“[0]没有人登录|[1]有1人登录|(1 +正]% 1%人登录,数组(“% 1%”= > count_logged()),count_logged())? >
第一个参数是文本的多种可能性。第二个参数是替代模式(与__ ()
助手),是可选的。第三个参数是测试的数量来确定哪些文本。
消息/字符串的选择由管道(|
)字符后跟一个可接受的值数组,使用下面的语法:
[1,2]
:接受1和2之间的值,包容(1、2)
:接受1和2之间的值,不含1和2{1,2,3,4}
:只接受值中定义的设置(负无穷,0)
:接受值大于或等于负无穷,严格小于0{n: n % 10 > 1 & & n % 10 < 5} pliki
:匹配数字2、3、4,22日,23日,24日(有用的语言,像波兰或俄语)
任何非空的方括号和括号分隔符的组合是可以接受的。
消息需要显式出现在的XLIFF文件翻译正常工作。十三至十八清单显示了一个示例。
十三至十八清单——XLIFF的字典format_number_choice ()
论点
…< trans-unit id = " 3 " > <源>[0]没有人登录|[1]有1人登录|(1 +正]% 1%人登录< /源> <目标>[0]人n是connecte |[1]一个人est connectee |(1 +正]有% 1%人在准则< /目标> < / trans-unit >…
侧边栏
几句关于数据集
处理国际化内容模板往往导致数据集的问题。如果你使用本地化的字符集,您将需要改变它在用户每次改变文化。此外,模板写在一个给定的字符集不正常显示另一个字符集的字符。
这就是为什么,一旦你处理多个文化,都必须保存在你的模板utf - 8,布局必须声明这个字符集的内容。你不会有任何不愉快的惊喜,如果你总是使用utf - 8,你会把自己从一个大头痛。
ob娱乐下载Symfony的应用程序依赖于一个中心设置字符集,settings.yml
文件。改变这个参数会改变内容类型
头的反应。
:.settings:字符集:utf - 8
调用模板外的翻译助手
并不是所有的文本显示在一个页面来自模板。这就是为什么你经常需要调用__ ()
辅助应用程序的其他部分:行动,过滤器,模型类,等等。清单23显示了如何调用一个行动的辅助检索当前的实例I18N
通过上下文singleton对象。
清单13 - 19 -调用__ ()
在一个行动
这个美元- >getContext()- >getI18N()- > __(美元的文本,args美元,“消息”);
总结
在web应用程序中处理国际化和本地化是无痛的如果你知道如何处理用户的文化。助手会自动考虑它输出正确格式化的数据,从数据库和本地化内容被视为如果它是一个简单的表的一部分。至于界面翻译,__ ()
助手和XLIFF字典确保你会有最大的多功能性与最小的工作。
这项工作是GFDL许可执照。