2014-01-24 23 views
4

我想解決這個問題以加載兩個mo文件。 我有兩個mo文件都有不同的msgid和msgstr。如何爲gettext漢化加載兩個mo文件

我的文件夾結構如下。 local/en_US/LC_MESSAGES/lang.mo local/en_US/LC_MESSAGES/brand.mo

以下代碼我用來加載mo文件。

define('PROJECT_DIR', realpath('./')); 
define('LOCALE_DIR', PROJECT_DIR .'/locale'); 
define('DEFAULT_LOCALE', 'en_US'); 
$encoding = 'UTF-8'; 
$locale = (isset($_SESSION['lang']))? $_SESSION['lang'] : DEFAULT_LOCALE; 
// gettext setup 
T_setlocale(LC_MESSAGES, $locale); 
// Set the text domain as 'messages' 
$our_domain = 'lang'; 
T_bindtextdomain($our_domain, LOCALE_DIR); 
T_bind_textdomain_codeset($our_domain, $encoding); 
T_textdomain($our_domain); 

我怎麼能在這裏補充一個多莫文件

+0

當我在PHP中使用Gettext時,我用一個.po/.mo對與一個或多個腳本關聯,而不是相反。但是,您可以切換.mo文件,但我不記得確切的功能,我會仔細研究並回來。 – Johnride

+0

一個mo文件都工作正常。但是,在這裏我有多個不同的字符串我想要加載所有莫文件一次。 –

回答

1

您可以簡單地使用bindtextdomaintextdomain功能,再次樹立了新的翻譯文件設置爲默認的資源。

簡化它會創建utilitary功能讓我們說selectTrFile($filename)這將使它看起來像一個好辦法:

function selectTrFile($trFile) { 
    bindtextdomain($trFile, TRANSLATION_BASE_DIR); // The constant being the path of you translations file directory 
    textdomain($trFile); 
} 

// Now set the first file 

selectTrFile('default'); 

// Do your stuff with this translations file 

selectTrFile('anotherTranslationsResource'); 

// Have fun with it 

你甚至可以讓它更快地在另一切換包裝上面的功能自動爲你的文件。

function _f($msgid, $trFile){ // called _f to make it very short to type 
    selectTrFile($trFile); // Switch the translations file 
    return _($msgid); // Return the translated string 
} 

// Then wrap your translations filenames in short variables 
$f1 = 'lang'; 
$f2 = 'brand'; 

// now you can translate Strings easily from one file or another. 
_f("to be translated in file 'lang'", $f1); 
_f("to be translated in file 'brand'", $f2); 

如果你不知道在哪個文件翻譯是什麼,你可以使用這個功能,而不是_f($msgid, $trFile);

function _f($msgid){ 

    selectTrFile('lang'); // or set a variable containing the filename and use it 

    $msgstr = _($msgid); 

    if($msgstr == $msgid){ // if the Strings are equals it means that there was no match in the first file 
     selectTrFile('brand'); // or set a variable containing the second filename and use it 
     $msgstr = _$(msgid); 
    } 

    return $msgstr; 
} 

利用這最後一個問題是,它可能會減慢很多過程中,我不知道在什麼時候。你可以通過每次不更改爲'lang'來優化它,看看如果字符串沒有被翻譯或者類似的東西是什麼實際的。

編輯

我不認爲你可以在一次裝倍數的翻譯資源。這對於msgid的衝突太危險了。你會更好的做一個更大的.mo文件比加載多個。

這就是msgfmt在編譯時確保沒有衝突的msgids的原因。不要害怕非常大的.po/.mo文件。 Mo是一種編譯和非常快速的格式。

現在可能出現的問題是有一個非常笨拙的.po文件。爲了避免這種情況,最好的方法是分段分割文件。

有兩種方法可以通過文件或者子文件來分開部分。如果您打算在多個文件中使用相同的翻譯(如果您正確使用包含,這種情況很少會發生),您可以按主題分開。

通常的方法是按文件分開並添加註釋,其中字符串來自。

## 
# File : /your/php/file.php 
## 
msgid "first String in file.php" 
msgstr "first translation in file.php 
. 
. 
. 
## 
# File : your/other/file.php 
## 
msgid "other translation" 
msgstr "and then you go on" 

所以問題是,你不應該需要從一個單一的PHP文件訪問多個文件的.mo如果你按照正確的指導方針。

有關更多信息,請參見here (The format of PO files)

+0

您的答案是否允許一起使用兩個.mo文件?它會允許從兩個文件中獲得翻譯嗎? –

+0

是的,但不是同時的。每次你想從另一個文件中獲取翻譯時,你都必須調用該函數。我會再次編輯以更好地解釋。 – Johnride

+0

我明白這一點。但要求是將某個ID保存在單獨的文件中。兩個文件中都不會有重複的ID。我收到兩個月不同的ID。並且需要在同一頁面中使用兩者的翻譯。無論如何,如果有可能實現請給我建議。 –

4

的想法是你的字符串分類爲不同

locale/ 
    en/     <-- language 
     LC_MESSAGES/  <-- category 
      messages.mo  <-- domain 
      brands.mo  <-- domain 

你綁定你不同的域爲locale目錄告訴gettext的哪些領域可以發現哪裏。然後,您選擇一個默認域,當您撥打​​時會使用該域。然後,使用更專業的功能切換域或類別:

_('Foo')         // LC_MESSAGES/messages.mo 
dgettext('brands', 'Foo')     // LC_MESSAGES/brands.mo 
dcgettext('brands', 'Foo', LC_MONETARY) // LC_MONETARY/brands.mo 

的想法是分類您的源代碼中的字符串。

相關問題