Question

I am trying to solve this to load two mo file. I have two mo files both have different msgid and msgstr.

My folder structure is as below. local/en_US/LC_MESSAGES/lang.mo local/en_US/LC_MESSAGES/brand.mo

Following code I am using to load mo file.

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);

How can I add here one more mo file

Was it helpful?

Solution 2

You can simply use the bindtextdomain and textdomain functions once again to set a new translations file as the default resource.

A good way to simplify it would be to create the utilitary function let's say selectTrFile($filename) which would make it look like this :

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

You can even make it quicker by wrapping the function above in another that switches automatically the file for you.

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);

If what you do not know in which file the translation is, you can use this function instead of _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;
 }

The problem with this last one is that it may slow down a lot the process, I don't know at what point. You could optimize it by not changing to 'lang' every time, looking what is the actual one if the String was not translated or something like this.

Edit

I don't think you can have multiples translations resources loaded at once. It would be too dangerous for msgid's conflicts. You would be better of making one bigger .mo file than loading multiple ones.

This is the reason why msgfmt makes sure that there are no conflicting msgids at compile time. Do not be afraid of very large .po/.mo files. Mo is a compiled and very fast format.

The problem that could appear now is having a very clumsy .po file. To avoid it, the best way is to separate the file in sections.

There are two ways of separating the sections, either by file or subjet. If you plan on having the same translations in multiple files (which should happen very rarely if you use your includes properly), you can separate by subject.

The usual way is to separate by file and add in a comment where the string is from.

##
# 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"

So the point is that you should never need to access multiple .mo files from a single .php file if you follow properly the guidelines.

See here (The format of PO files) for more informations.

OTHER TIPS

The idea is to categorise your strings into different domains and categories:

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

You bind your different domains to locale directories to tell gettext which domain can be found where. You then select a default domain, which is used when you call _('Foo'). You then use more specialised functions to switch domains or categories:

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

The idea is to categorise your strings inside your source code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top