亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

翻譯

“國際化”(internationalization,常被簡寫為i18n),是指將字符串和其他一些具有區(qū)域特征的片段從你的程序中提?。╝bstract)出來并基于用戶所在區(qū)域(比如語言、國家)而將其置于一個能被翻譯和轉(zhuǎn)化的層的過程。對于文本來說(text),這意味著用一個能夠把它(或“信息”)翻譯成用戶所需語言的函數(shù),來剝離文本的每一部分:

// 文本始終以英語輸出echo 'Hello World'; // 文本將以用戶指定語言或默認英語輸出echo $translator->trans('Hello World');

locale的意思,單純來說就是用戶的語言和國家。在程序中它可以是任何一個字符串,用來管理翻譯(translation)和其他格式信息(比如幣種)。推薦使用以ISO 639-1語言代碼,加一個下劃線(_),再跟一個ISO 3166-1 alpha-2國家代碼(比如fr_FR這個locale是指“法國法語”French/France)。

在本章,你將學(xué)習(xí)如何使用Symfony框架中的translation組件。你可以閱讀翻譯組件來了解更多。整體上,翻譯的過程有如下幾步:

  1. 開啟和配置Symfony的翻譯服務(wù);

  2. 將字符串抽象出來(如“xxxx”),這是通過調(diào)用Translator去剝離它們來實現(xiàn)的 ;(參考 翻譯基礎(chǔ))

  3. 針對每個被支持的locale,創(chuàng)建翻譯資源/文件,用于翻譯程序中每一個待譯字串;

  4. 針對request(請求)和可選的 基于用戶整個session過程,來 確定、設(shè)置和管理用戶的locale信息

配置 ?

翻譯的過程是通過translator服務(wù)來處理的,該服務(wù)使用用戶指定的locale來查找并返回翻譯過的信息。使用translator之前,在配置文件中開啟它:

PHP:// app/config/config.php$container->loadFromExtension('framework', array('translator' => array('fallbacks' => array('en')),));
XML:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:framework="http://symfony.com/schema/dic/symfony"           xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/symfony        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">     <framework:config>
        <framework:translator>
            <framework:fallback>en</framework:fallback>
        </framework:translator>
    </framework:config></container>
YAML:# app/config/config.ymlframework:translator: { fallbacks: [en] }

關(guān)于 fallbacks關(guān)鍵字 以及Symfony在找不到翻譯語種時如何處理,請參考 翻譯時的Locales回滾 以了解細節(jié)。

翻譯時要用到的locale信息被存于request對象中。一般在路由中被設(shè)為 _locale 屬性。請參考 The Locale and the URL。

翻譯基礎(chǔ) ?

translator 服務(wù)負責(zé)完成對文本的翻譯。為了翻譯一個文本塊(被稱為“message”,以下稱作“信息”),使用trans()方法。例如,你要在controller中翻譯一個簡單的信息:

// ...use Symfony\Component\HttpFoundation\Response; public function indexAction(){$translated = $this->get('translator')->trans('Symfony is great'); return new Response($translated);}

上述代碼被執(zhí)行后,Symfony就嘗試基于用戶的 locale 來翻譯 “Symfony is great”信息。為了讓這個過程實現(xiàn),你需要告訴Symfony如何通過一個“翻譯源(translation resource)”來執(zhí)行翻譯。一般來說翻譯源是一個文件,包含有成組的翻譯信息,對應(yīng)某一指定的locale。它就像個翻譯時的“字典”,可被創(chuàng)建為多種格式,但推薦使用XLIFF(譯注:就是后綴不同的xml格式):

PHP:// messages.fr.phpreturn array('Symfony is great' => 'J\'aime Symfony',);
YAML:# messages.fr.ymlSymfony is great: J'aime Symfony
XML:<!-- messages.fr.xlf --><?xml version="1.0"?><xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" datatype="plaintext" original="file.ext">
        <body>
        <trans-unit id="symfony_is_great">
            <source>Symfony is great</source>
            <target>J'aime Symfony</target>
        </trans-unit>
        </body>
    </file></xliff>

關(guān)于這類文件的存放位置等信息,參考 翻譯源/文件名與位置

現(xiàn)在,如果用戶的locale是法語(比如 fr_FRfr_BE ),那么前面的信息將被翻譯為 J'aime Symfony。你也可以在 模板(templates) 中完成翻譯。

翻譯的處理過程 ?

為了能翻譯一條信息,Symfony執(zhí)行以下簡明流程:

  • 先確定request對象中所存儲的當(dāng)前用戶的 locale 信息;

  • 某一目錄(一大組message)的已經(jīng)翻譯好的信息,將從由 locale(比如 fr_FR )所決定的翻譯源加載。如果locale不存在,則由 fallback locale 所決定的翻譯信息,也將被加載并且合并到目錄之中。最終結(jié)果就是生成了一個“翻譯大詞典”;

  • 如果能夠從目錄中找到待翻信息,翻譯結(jié)果將被返回。否則, translator返回原始信息。

當(dāng)使用trans()方法時,Symfony從對應(yīng)的信息目錄中,尋找準(zhǔn)確的字符串,然后返回它(如果存在的話)。

譯注:message catalog

此處的目錄,原文是catalog,是指Symfony在處理“翻譯”的過程中,從翻譯源提取出來的已經(jīng)翻譯好的待用信息集合,也就是一個包含了很多條message的xliff文件。參考后面“翻譯源/文件的命名和位置”中的domain部分)

信息占位符 ?

有時,一條包含變量的信息,需要被翻譯:

use Symfony\Component\HttpFoundation\Response; public function indexAction($name){$translated = $this->get('translator')->trans('Hello '.$name); return new Response($translated);}

可是,對于這樣一個字符串,創(chuàng)建相應(yīng)的翻譯是不可能的,因為translator始終在嘗試尋找“確定信息”,包括變量值本身(比如“Hello Ryan”和“Hello Fabien”在translator看來是兩條不同的信息)。

對于這種情形,請參考組件文檔中的 信息占位符/Message Placeholders。同樣情況在模板中的處理方法,參考 Twig Templates。

復(fù)數(shù)處理 ?

另一個復(fù)雜場面,則是你在翻譯中要面對基于某些變量的“復(fù)數(shù)狀況”:

1
2
There is one apple.
There are 5 apples.

要處理這個,應(yīng)使用 transChoice() 方法,或者用模板中的transchoice標(biāo)簽/調(diào)節(jié)器,請 參考這里。

更多信息,參考Translation組件文檔的 復(fù)數(shù)處理章節(jié)。

模板中的翻譯 ?

多數(shù)情況下,翻譯發(fā)生在模板中,對于Twig和PHP模板,Symfony提供了原生支持。

Twig模板 ?

Symfony提供了特殊的Twig標(biāo)簽(transtranschoice),用于對“靜態(tài)文本塊”信息提供翻譯幫助。

{% trans %}Hello %name%{% endtrans %} {% transchoice count %}{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples{% endtranschoice %}

transchoice標(biāo)簽,自動地從當(dāng)前上下文關(guān)系中得到%count%變量,并將其傳給translator。這種機制,只在你使用%var%這種格式的占位符時生效。

在Twig模板中使用 trans/transchoice 標(biāo)簽進行翻譯時,%var% 占位符注釋是必須要提供的。

如果你需要在字符串中使用百分號%,要寫兩次來為它轉(zhuǎn)義:

1
{% trans %}Percent: %percent%%%{% endtrans %}

你也可以指定信息域(message domain),并傳遞一些附加的變量進來:

{% trans with {'%name%': 'Fabien'} from "app" %}Hello %name%{% endtrans %} {% trans with {'%name%': 'Fabien'} from "app" into "fr" %}Hello %name%{% endtrans %} {% transchoice count with {'%name%': 'Fabien'} from "app" %}{0} %name%, there are no apples|{1} %name%, there is one apple|]1,Inf[ %name%, there are %count% apples{% endtranschoice %}

trans和transchoice調(diào)節(jié)器,可用于翻譯變量文本和復(fù)雜表達式:

{{ message|trans }} {{ message|transchoice(5) }} {{ message|trans({'%name%': 'Fabien'}, "app") }} {{ message|transchoice(5, {'%name%': 'Fabien'}, 'app') }}

在翻譯時無論使用標(biāo)簽還是調(diào)節(jié)器,效果是相同的,但有一個微小區(qū)別:自動輸出轉(zhuǎn)義功能僅對調(diào)節(jié)器有效。換言之,如果你需要翻譯出來的信息“不被轉(zhuǎn)義”,則必須在translation調(diào)節(jié)器后面再跟一個raw調(diào)節(jié)器:

{# 標(biāo)簽中被翻譯的文本從不被轉(zhuǎn)義#}{% trans %}<h3>foo</h3>{% endtrans %} {% set message = '<h3>foo</h3>' %} {# 變量調(diào)節(jié)器翻譯的字符串和變量,默認將被轉(zhuǎn)義 #}{{ message|trans|raw }}{{ '<h3>bar</h3>'|trans|raw }}

你可以通過單一標(biāo)簽,為整個twig模板設(shè)置一個翻譯域(translation domain):

1
{% trans_default_domain "app" %}

注意這時僅會影響到當(dāng)前模板,而不包括任何“被包容(included)”的模板(為的是減少副作用)。

PHP模板 ?

translator也可以在PHP模板中通過translator helper來使用:

<?php echo $view['translator']->trans('Symfony is great') ?> <?php echo $view['translator']->transChoice('{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples',10,array('%count%' => 10)) ?>

翻譯源/文件的命名和位置 ?

Symfony在以下位置尋找信息文件(即是translations/翻譯信息):

  • app/Resources/translations 目錄;

  • app/Resources/<bundle name>/translations 目錄;

  • 任何bundle下的 Resources/translations/ 目錄

上面的位置是按照“高優(yōu)先權(quán)在前”的順序排列的。這意味著,你可以用前面兩個目錄之一,來覆寫某個bundle中的翻譯信息。

覆寫機制基于鍵等級(key level)而執(zhí)行:只有被覆寫的鍵需要被列在高優(yōu)先級的信息文件中。當(dāng)一個鍵沒有在信息文件中被找到時,translator將自動回滾到低優(yōu)先級的信息文件中。

信息文件的文件名也很重要,每一個信息文件必須按下列命名路徑來命名:domain.locale.loader:

  • domain: 這是一個可選項,用于組織信息文件成為群組(例如admin, navigation 或default messages)。參閱 使用翻譯信息的域 Using Message Domains

  • locale: 這是翻譯信息的locale (例如 en_GB, en, 等等);

  • loader: 這是Symfony如何來加載和解析信息文件 (也就是 xlf, php, yml 等文件后綴).

加載器(loader)可以是任何已注冊加載器的名稱。Symfony默認提供了許多加載器,包括:

  • xlf: 加載XLIFF文件;

  • php: 加載PHP文件;

  • yml: 加載YAML文件;

使用何種加載器的選擇權(quán)完全在你,隨你喜好。推薦使用xlf作為翻譯的信息文件。更多選擇,參考 加載信息目錄 Loading Message Catalogs。

你也可以將翻譯信息存在數(shù)據(jù)庫中,或任何其他介質(zhì),只要提供一個自定義的類去實現(xiàn) LoaderInterface 接口即可。參考 translation.loader 標(biāo)簽,以了解更多。

你可以在配置文件中通過paths選項添加一個目錄:

PHP:// app/config/config.php$container->loadFromExtension('framework', array('translator' => array('paths' => array('%kernel.root_dir%/../translations',),),));
XML:<!-- app/config/config.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"           xmlns:framework="http://symfony.com/schema/dic/symfony"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"           xsi:schemaLocation="http://symfony.com/schema/dic/services    http://symfony.com/schema/dic/services/services-1.0.xsd    http://symfony.com/schema/dic/symfony    http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">     <framework:config>
        <framework:translator>
            <framework:path>%kernel.root_dir%/../translations</framework:path>
        </framework:translator>
    </framework:config></container>
YAML:# app/config/config.ymlframework:translator:paths:- '%kernel.root_dir%/../translations'

每次你創(chuàng)建一個新的翻譯源(translation resource)或安裝了一個包含翻譯源的bundle時,一定要清除緩存,這樣Symfony才能發(fā)現(xiàn)這個新的翻譯源。

1
$  php app/console cache:clear

翻譯時Locale的回滾 ?

假設(shè)一名用戶的locale信息是 fr_FR,而你正翻譯的鍵是 Symfony is great。為了找到法語信息,Symfony切實地檢查若干locale的翻譯源:

  1. 首先,Symfony在一個 fr_FR 的翻譯源(例如messages.fr_FR.xlf)尋找翻譯信息;

  2. 如果沒找到,Symfony在一個 fr 翻譯源(比如messages.fr.xlf)繼續(xù)尋找翻譯信息;

  3. 如果仍然沒找到,Symfony使用fallbacks這個配置參數(shù), 它被默認設(shè)為 en (參閱 FrameworkBundle配置信息)。

2.6版Symfony引入了將缺少的翻譯信息寫入日志的能力。

當(dāng)Symfony無法找到給定locale的翻譯信息時,它會把缺少的翻譯信息給添加到日志文件中。參閱 logging。

翻譯數(shù)據(jù)庫內(nèi)容 ?

翻譯數(shù)據(jù)庫內(nèi)容時要用到Doctrine擴展中的 Translatable ExtensionTranslatable Behavior(PHP 5.4+)。更多信息請參考相應(yīng)文檔。

譯注:使用Doctrine擴展有兩種方式

一個是類庫方式,一個是bundle方式。此處的Translatable Behavior,是指用bundle安裝之后,翻譯數(shù)據(jù)庫內(nèi)容時所應(yīng)參考的用法)

翻譯約束信息 ?

參考 如何翻譯驗證約束消息 以了解更多。

處理用戶的Locale ?

翻譯的過程是取決于用戶的locale的。閱讀 如何操作用戶的Locale 以了解如何處理。

對翻譯進行調(diào)試 ?

debug:translation 命令行語句從Symfony 2.5起引入。  Symfony 2.6之前,這一命令是translation:debug。

當(dāng)你在不同語言的大量翻譯信息中操作時,要跟蹤到丟失了哪條信息以及哪條信息沒有被使用,是很困難的。閱讀 如何找到丟失或未使用的翻譯信息 以了解如何發(fā)現(xiàn)這一類翻譯信息。

總結(jié) ?

使用Symfony的翻譯組件創(chuàng)建一個國際化的應(yīng)用程序?qū)⒉辉偈且粋€“痛苦過程”,而是歸結(jié)于以下簡單步驟:

  • 從程序中抽象出待翻譯的信息,把每一條信息用 trans()transChoice() 方法替換(通過 使用Translator一文了解更多);

  • 通過創(chuàng)建信息文件(translation message file)將待譯信息翻譯成多個locale語種。Symfony能夠找到并處理每一個文件,因為這些文件的名字遵循指定的命名約定;

  • 管理好用戶的locale,它可以存在request中,但是也可以存在用戶的session中。