php-gettext / Gettext

PHP library to collect and manipulate gettext (.po, .mo, .php, .json, etc)
MIT License
688 stars 134 forks source link

How to load multiple *.mo files (general and for specific textdomain) #272

Open jasomdotnet opened 3 years ago

jasomdotnet commented 3 years ago

First of all, thank you for a library. Second, I don't know how to load multiple *.mo translation files and use them with textdomain context.

This is my code so far:

use Gettext\Translator;
use Gettext\Loader\MoLoader;

$lang = 'sk' // set by a side function
define('ROOT', '/path/to/root');

function __( string $string, string $textdomain = null ) {

    static $t = null;

    global $basic_lang;

    $translation = ROOT . '/languages/' . $lang . '.mo';

    if (!file_exists( $translation )) {
        return $string;
    }

    if ($t === null) {

        $loader = new MoLoader();
        $t = Translator::createFromTranslations( $loader->loadFile( $translation ) );
    }

    //return $textdomain ? $t->dgettext( $textdomain, $string ) : $t->gettext( $string );
    return $t->gettext( $string );

}

//echo __( 'Buy a ticket', 'reservation' ); // does not work right now, how to make it work?
echo __( 'Buy a ticket' ); // works

I guess that mode code samples would be helpful for others too.

oscarotero commented 3 years ago

As I can see, you're loading only one domain, but in gettext every domain is a different file. Maybe something like this:

$loader = new MoLoader();
$lang = "sk";
$default = $loader->loadFile(ROOT."/languages/{$lang}/default.mo";
$reservation = $loader->loadFile(ROOT."/languages/{$lang}/reservation.mo";

$t = Translator::createFromTranslations($default, $reservation);
jasomdotnet commented 3 years ago

Oka, thank you for a code sample.

And when I have more textdomains (files), like 'forum' loading also forum would be:

$loader = new MoLoader();
$lang = "sk";
$default = $loader->loadFile(ROOT."/languages/{$lang}/default.mo";
$reservation = $loader->loadFile(ROOT."/languages/{$lang}/reservation.mo";
$forum = $loader->loadFile(ROOT."/languages/{$lang}/forum.mo";
$shop = $loader->loadFile(ROOT."/languages/{$lang}/shop.mo";

$t = Translator::createFromTranslations($default, $reservation, $forum, $shop);

I would like to load forum.mo only when user interacts with forum controller otherwise it has no sense to split translated strings into multiple .mo files (textdomain).

Can you direct me to some tutorial or code example?

NOTE: Maybe I asking stupid questions from your point of you but I'm new within gettext environment / system / ...

oscarotero commented 3 years ago

You can see the code of how create a translator and add translations here: https://github.com/php-gettext/Translator/blob/master/src/Translator.php#L15

A pseudocode (not tested):

$loader = new MoLoader();
$arrayGenerator = new ArrayGenerator();

// Check if the domain hasn't loaded before
if (empty($domains[$domain])) {
    // Load the translations of this domain:
    $translations = $loader->loadFile(ROOT."/languages/{$lang}/${domain}.mo";

    // Convert the translations to an array:
    $array = $arrayGenerator->generateArray($translations);

    //Add the array of translations to the translator
    $t->addTranslations($array);

    //Mark the domain as loaded
    $domains[$domain] = true;
}