open-ecommerce.org
open-ecommerce.org

Reputation: 1814

Lost in yii2 module i18n translation

I am trying to add multilanguage functionality to a module I found in Russian, but I am getting problems when I try to implement it probably the configuration, no sure.

I did the text replacement as I normaly do in the applications:

'department' => Yii::t('app', 'Departament'),

Then I generated the translations files with the message command and so far all fine and I got the correct structure:

vendor/rico/yii2-ticket/messages/en/app.php
vendor/rico/yii2-ticket/messages/es/app.php

Then I added a function in the init of the yii2-ticket module file:

public function init() {
    User::$user = ($this->userModel !== false) ? $this->userModel : Yii::$app->user->identityClass;
    parent::init();
    $this->registerTranslations();
}
/**
 * Registration of translation class.
 */
protected function registerTranslations()
{
    Yii::$app->i18n->translations['ricco/ticket'] = [
        'class' => 'yii\i18n\PhpMessageSource',
        'sourceLanguage' => 'en',
        'basePath' => '@ricco/ticket/messages',
        'fileMap' => [
            'ricco/ticket' => 'app.php',
        ],
    ];
}

I am consuming this module in a yii2 application based in to advanced application and in the configuration file i have the following:

$config = [
'name' => 'London Literary Scouts',
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'extensions' => require(__DIR__ . '/../../vendor/yiisoft/extensions.php'),
'sourceLanguage' => 'en',
'language' => 'en',
'bootstrap' => ['log'],
'modules' => [
    'treemanager' => [
        'class' => '\kartik\tree\Module',
    // other module settings, refer detailed documentation
    ],
    'newsletter' => [
        'class' => 'tikaraj21\newsletter\Newsletter',
    ],
    'comment' => [
        'class' => 'yii2mod\comments\Module',
    ],
    'ticket' => [
        'class' => 'ricco\ticket\Module'
    ],
],

...

    'i18n' => [
        'translations' => [
            'app' => [
                'class' => 'yii\i18n\PhpMessageSource',
                'basePath' => '@common/messages',
            ],
            '*' => [
                'class' => 'yii\i18n\PhpMessageSource',
                'basePath' => '@common/messages',
                'fileMap' => [
                    'common' => 'common.php',
                    'backend' => 'backend.php',
                    'frontend' => 'frontend.php',
                ],
                'on missingTranslation' => ['\backend\modules\i18n\Module', 'missingTranslation']
            ],

Runing the application in development mode I don't get any error in the logs.

But if I copy the en/app.php file into the common/messages/en folder of my application it works.

But I wanted to have the translation running from the module so another people can use it based in there general configuration.

EDITED

After playing around and making sense from the csminb answer I deleted all the i18n configuration from my main application.

1- I made all the translations in the module harcoded texts as follow:

<?= Yii::t('ticket', 'Go back') ?>

2- Created the configuration file in my console/config folder ./yii message/config @app/config/i18n-ricco.php

3- Edited to add the languages and the correct path

return [
'color' => null,
'interactive' => true,
'help' => null,
'sourcePath' => '@vendor/ricco/yii2-ticket',
'messagePath' => '@vendor/ricco/yii2-ticket/messages',
'languages' => ['en','ru','es'],
'translator' => 'Yii::t',
'sort' => false,
'overwrite' => true,
'removeUnused' => false,
'markUnused' => true,
'except' => [
    '.svn',
    '.git',
    '.gitignore',
    '.gitkeep',
    '.hgignore',
    '.hgkeep',
    '/messages',
    '/BaseYii.php',
],
'only' => [
    '*.php',
],
'format' => 'php',
'db' => 'db',
'sourceMessageTable' => '{{%source_message}}',
'messageTable' => '{{%message}}',
'catalog' => 'messages',
'ignoreCategories' => [],

];

4- Run the message command

./yii message/config @app/config/i18n-ricco.php

The message command generated all the languages folders with the ticket.php files.

5- Added the configuration in the init function of the module:

    /**
 * @inheritdoc
 */
public function init() {
    User::$user = ($this->userModel !== false) ? $this->userModel : Yii::$app->user->identityClass;
    parent::init();
    $this->registerTranslations();
}
/**
 * Registration of translation class.
 */
protected function registerTranslations()
{
    Yii::$app->i18n->translations['ticket'] = [
        'class' => 'yii\i18n\PhpMessageSource',
        'sourceLanguage' => 'en',
        'basePath' => '@ricco/ticket/messages',
        'fileMap' => [
          'ticket' => 'ticket.php',
        ],
    ];
}

Upvotes: 0

Views: 2039

Answers (1)

csminb
csminb

Reputation: 2382

adding up to my prev comment here

if you want to have separate module translation, i would use a different scope than app for anything that's in that module, and add that scope to the application when your module initializes.

the reason you're not getting errors most likely is the * in your config

```

'i18n' => [
    'translations' => [
        'app' => [
            'class' => 'yii\i18n\PhpMessageSource',
            'basePath' => '@common/messages',
        ],
        // you could remove this (at least in your local dev to make sure errors will be thrown if files are not setup)
        '*' => [
            'class' => 'yii\i18n\PhpMessageSource',
            'basePath' => '@common/messages',
            'fileMap' => [
                'common' => 'common.php',
                'backend' => 'backend.php',
                'frontend' => 'frontend.php',
            ],
            'on missingTranslation' => ['\backend\modules\i18n\Module', 'missingTranslation']
     ]
]

```

once you have setup a translation file in your module /common/modules/Ticket/messages/en/ticket.php make sure to add this message source whenever the module is initialized

/common/modules/Ticket/Module.php

... 

public function init()
{
    parent::init();
    if (!isset(Yii::$app->i18n->translations['ticket'])) {
        Yii::$app->i18n->translations['ticket'] = [
            'class' => 'yii\i18n\PhpMessageSource',
            'sourceLanguage' => 'en',
            'basePath' => '@vendor/rico/ticket/messages'
        ];
    }
}

this way just by including the module, it will add the module-specific translations and not interfere with your app config

edit:

updated paths to @vendor/rico, (@rico works too if you've setup aliases)
in the mean time, another thing which might cause confusion is the fileMap in your example.

```

// this is hard to make sense of, :
// it's a category named `rico/ticket` will point to @vendor/rico/ticket/messages/en/app.php 
// are you usinging it like this? Yii:t('rico/ticket', 'sample') 
'fileMap' => [
    'ricco/ticket' => 'app.php',
],

unless the translation files are too big to manage, or their names are too verbose (like this example), i dont see any reason to use it, the standard name mapping is much simpler

Upvotes: 0

Related Questions