Reputation: 2377
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
Upvotes: 5
Views: 5217
Reputation: 522382
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.
Upvotes: 5
Reputation: 8746
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.
Upvotes: 2