2010-03-23 170 views
23

我覺得Yii是一個很好的框架,用yiic shell創建的示例網站是一個很好的開始...但不包括多語言網站的主題,不幸的是, 。該文檔涵蓋翻譯短消息,但不保留多語言內容的主題...Yii:多語言網站 - 最佳實踐

我即將開始工作的網站至少需要兩種語言,我想知道什麼是保持內容的最佳方式... 問題是,內容廣泛地與常見元素(如嵌入式視頻文件)混合使用。

我需要避免重複那些公......到目前爲止,我曾經有包含文本(通常不超過1-2小段)數組的數組,然後視圖文件只是從一個陣列呈現文本。

現在,我想,以避免其保存在陣列(把雙引號時,需要注意「」,而且不利於一般...)。

那麼,保留這些短段落的最好方法是什麼?我是否應該將它們保存在數據庫中(id | msg_id | language | content),然後通過msg_id &語言選擇它們?這仍然需要我創造一些MSG_ID的和將它們嵌入到視圖文件...

是否有其Yii有一些解決方案,任何建議的範式?

謝謝, 米。

回答

17

默認甲Yii應用使用YII ::噸()用於翻譯文本消息的方法和有3種不同類型的消息的來源:

  1. CPhpMessageSource:翻譯被存儲爲鍵 - 值對在一個PHP陣列。
  2. CGettextMessageSource:翻譯存儲爲GNU Gettext文件。 (PO文件)
  3. CDbMessageSource:消息轉換存儲在數據庫表中。

如果我不要誤會,你使用的是經典陣列進行翻譯。我建議你在Yii上使用GetText和PO文件進行翻譯操作。

你可以找到很多關於此official documentation page翻譯和國際化與誼信息。

+0

問題與GetText IMO是他們很難維護和保持更新也可以遇到原子問題。我首選的方法是數據庫,因此您可以即時更新消息。如果你真的渴望速度GetText更快,否則數據庫是要走的路。 – Atherion 2013-01-04 19:24:22

+0

注意:我建議不要使用沒有緩存的GettextMessageSource。純PHP PHP的gettext性能比php數組慢(yii2本身使用php數組),因爲它重複讀取文件,但是使用php gettext擴展(vs gettext純php代碼)比php數組快一些,但使用php ext需要服務器重啓爲每個變化。 http://mel.melaxis.com/devblog/2006/04/10/benchmarking-php-localization-is-gettext-fast-enough/ – Alix 2016-09-05 08:23:33

1

嗯,我覺得在這裏所關心的是如何在頁面上翻譯靜態文本/消息和Yii的解決它很好使用Yii:T(),並也迪古的回答吧。

我在FlexicaCMS上查看關於在數據庫中翻譯動態內容的文章,最終在解決靜態文本/消息問題後將是下一個,這是使用Yii行爲的一個真正的好方法。不確定FlexicaCMS作者是否過於雄心勃勃地支持翻譯,因爲它會使內容翻譯成爲一件無憂的事情 - 非常棒。

他們沒有提到的一件事是翻譯頁面的網址。例如your.site.com/fr/translated_article_title.html。我的意思是url必須有/ language_id/part,所以它可以幫助搜索引擎優化。

19

Gettext對於易於翻譯很有好處,但默認的PHP實現不是線程安全的。Yii因此使用它自己的解包器,與php數組相比,它大大增加了處理時間。

由於我建立了一個高容量,高交易站點,因此性能不佳是不可接受的。另外,通過使用APC,我們可以緩存PHP翻譯以進一步提高性能。

因此,我的做法是使用PHP數組,但爲了便於翻譯,將翻譯保留在數據庫中,以便在翻譯發生更改時生成所需的文件。

的DB是與此類似:

TABLE Message   // stores source language, updated by script 
id INT UNSIGNED 
category VARCHAR(20)   // first argument to Yii::t() 
key TEXT      // second argument to Yii::t() 
occurences TINYINT UNSIGNED // number of times found in sources 

TABLE MessageTranslation // stores target language, translated by human 
id INT UNSIGNED 
language VARCHAR(3)   // ISO 639-1 or 639-3, as used by Yii 
messageId INT UNSIGNED  // foreign key on Message table 
value TEXT 
version VARCHAR(15) 
creationTime TIMESTAMP DEFAULT NOW() 
lastModifiedTime TIMESTAMP DEFAULT NULL 
lastModifiedUserId INT UNSIGNED 

我然後修改的CLI工具的yiic「消息」命令轉儲收集串到DB。

http://www.yiiframework.com/wiki/41/how-to-extend-yiic-shell-commands/

一旦在DB,一個簡單的CMS可以設置爲譯者提供一個簡單的方法來翻譯,並在同一時間提供版本信息,回覆到舊版本,檢查翻譯的質量,等等。

另一個腳本,也從yiic修改,然後採取數據庫信息和編譯到PHP數組。基本上是每種語言的兩個表的JOIN,然後使用'Message','key'和'MessageTranslation','value'作爲(還有什麼?)key => value ...來保存到名爲'消息'。'category'在由語言指定的文件夾中。

Yii CPhpMessageSource正常載入生成的文件。

對於圖像,這很簡單,只需將它們放置在具有適當語言的文件夾中,並在鏈接時獲取應用程序語言即可。

<img src="/images/<?php echo Yii::app()->language; ?>/help_button.png"> 

請注意,在現實生活中,我寫了一個小幫手方法從語言字符串中剝離國家,'en_us'應該是'en'。

0

在Yii1和Yii2中yii \ i18n \ GettextMessageSource無論如何都不使用Yii完美的緩存引擎(查看源代碼)來增強PO或MO文件的加載。它不推薦使用PHP純代碼(包括警予\國際化\ GettextMessageSource)來加載這些文件(它是如此之比PHP陣列IDX慢): http://mel.melaxis.com/devblog/2006/04/10/benchmarking-php-localization-is-gettext-fast-enough/

然而,對於MO文件PHP的gettext的分機是幾比翻譯PHP快數組,因爲它使用緩存,但負面的一點是:MO中的每個更改都需要重新啓動服務器。

我認爲最好的解決方案是在自己的代碼庫中擴展yii \ i18n \ GettextMessageSource,並將緩存功能添加到GettextMessageSource中以增強其性能並將擴展版本用作組件。

protected function loadMessages($category, $language); 

只是不檢查MO修改日期在每一個負荷來比較緩存,而不是清除緩存時,MO或PO文件被更改(也可以是一個時間表)。