I'm using the Yii2 advanced template. I have implemented the translations(i18n) following this tutorial and reviewing this SO question. YES, I read the documentation.
My translations are not working and I found out in the debugger that it's looking for he translations in the frontend folder instead of he common folder where the message/extract created the translations files:
The message file for category 'app' does not exist: localhost/frontend/messages/es/app.php
I know the easiest thing would be to move the messages folder to the frontend folder since I'm not using translations in the backend, but I'd like to understand what I'm doing wrong.
This is my i18n file located in common/config:
'sourcePath' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR,
'languages' => ['es'], //Add languages to the array for the language files to be generated.
'translator' => 'Yii::t',
'sort' => false,
'removeUnused' => false,
'only' => ['*.php'],
'except' => [
'.svn',
'.git',
'.gitignore',
'.gitkeep',
'.hgignore',
'.hgkeep',
'/messages',
'/vendor',
],
'format' => 'php',
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'messages',
'overwrite' => true,
This is my common/config/main file
'i18n' => [
'translations' => [
'frontend*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
],
'backend*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
],
],
],
This is where the aliases are defined (default. common/config/bootstrap) and echoing #common returns common:
Yii::setAlias('#common', dirname(__DIR__));
Yii::setAlias('#frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('#backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('#console', dirname(dirname(__DIR__)) . '/console');
Your code is correct, but from the error message seems that you are calling:
Yii::t('app', '...');
Instead in your common/config/main you have declared entries for 'frontend*' and 'backend*', but not for 'app*'. So Yii will continue search inside frontend repository folder.
The common/config/main should contain (if you want to use Yii::t('app',...') ):
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
],
Using your configuration, the translations must be called using:
Yii::t('frontend','Frontend_string');
for the frontend and,
Yii::t('backend','Backend_string');
for the backend content.
See the point 6. in the tutorial
Related
I'm trying to add REST api to my existing classic Yii2 (advanced template) project. According to Creating a REST API for Yii2-basic-template
and RESTful API in Yii 2 Advanced Application Template I'm trying to achieve that by adding a new module to my existing app.
Here is my application structure now:
+ api
+ config
-main.php
+ modules
+ v1
+ controllers
-Module.php
-index.php
-.htaccess
+ backend
+ common
...
My api/config/main.php file:
<?php
$params = require(__DIR__ . '/../../backend/config/params.php');
return [
'id' => 'app-backend-api',
'basePath' => dirname(__DIR__) . '/..',
'bootstrap' => ['log'],
'modules' => [
'v1' => [
'class' => 'api\modules\v1\Module'
]
],
'components' => [
'request' => [
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => ['v1/goal']],
],
],
],
'params' => $params,
];
and my Module.php
<?php
namespace api\modules\v1;
class Module extends \yii\base\Module
{
public $controllerNamespace = 'api\modules\v1\controllers';
public function init()
{
parent::init();
}
}
The problem is that when I try to navigate to http://my-url/api/v1/goals I get the following error:
Invalid Configuration – yii\base\InvalidConfigException
Failed to instantiate component or class "api\modules\v1\Module".
Caused by: ReflectionException
Class api\modules\v1\Module does not exist
in C:\wamp64\www\agency\vendor\yiisoft\yii2\di\Container.php at line 453
Create file common/config/aliases.php:
Yii::setAlias('common', dirname(__DIR__));
Yii::setAlias('frontend', dirname(dirname(__DIR__)) . '/frontend');
Yii::setAlias('backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('console', dirname(dirname(__DIR__)) . '/console');
Yii::setAlias('api', dirname(dirname(__DIR__)) . '/api');
Add this line to file api/web/index.php
require(__DIR__ . '/../../common/config/aliases.php');
I have Yii2 advanced template, I want to set translation for my frontend views, here is what I did:
frontend/config/main.php:
'sourceLanguage'=>'en-US',
'language'=>'en-US',
'components' => [
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
'sourceLanguage' => 'en-US',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',
],
],
],
],
]
then I added i18n.php in common/config:
<?php
return [
'sourcePath' => __DIR__. '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR,
'languages' => ['fr-FR','en-US'], //Add languages to the array for the language files to be generated.
'translator' => 'Yii::t',
'sort' => false,
'removeUnused' => false,
'only' => ['*.php'],
'except' => [
'.svn',
'.git',
'.gitignore',
'.gitkeep',
'.hgignore',
'.hgkeep',
'/messages',
'/vendor',
],
'format' => 'php',
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'messages',
'overwrite' => true,
];
and the common/messages/en-US/app.php:
<?php
return[
// Menu texts
'menu.login'=>'login',
];
and I used it in the views as : Yii::t('app', 'menu.login');
but the translation didn't work, it displayed as menu.login
You Just Follow This Steps......
Step 1: In the common directory , create messages folder.
Step 2: Create i18n.php file inside common/config directory with following content:
<?php
return [
'sourcePath' => __DIR__. '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR,
'languages' => ['en-EN', 'ru-RU'], //Add languages to the array for the language files to be generated, here are English and Russian.
'translator' => 'Yii::t',
'sort' => false,
'removeUnused' => false,
'only' => ['*.php'],
'except' => [
'.svn',
'.git',
'.gitignore',
'.gitkeep',
'.hgignore',
'.hgkeep',
'/messages',
'/vendor',
],
'format' => 'php',
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'messages', //path of messages folder created above
'overwrite' => true,
];
Note: Make sure to add all required languages to 'languages' array. In the above example I have added English and Russian for Generate Yii2 Framework multi language.
Step 3: Add the i18n component in config file common/main.php configuration as follows:
'components' => [
...
'i18n' => [
'translations' => [
'frontend*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
],
'backend*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
],
],
],
...
],
Step 4:
Add the language module in common config file to use the default language on your app, such as:
'language' => 'en-EN' inside common/main.php.
You now can use Yii::$app->language = ‘en-EN’ at any runtime like URL request, query code.
Note: In any Model, Controller Generate by Gii, you can see Enable I18n ticket choice, just enable this for Multi language. Gii Tool will auto generate a Model has pre-defined as below, due to frontent or backend folder:
Yii::t('frontend', 'Translatable String');
Yii::t('backend', 'Translatable String');
Step 5: Run this command line from Yii2 app folder:
yii message/extract #common/config/i18n.php
This command line will Generate Yii2 Framework multi language translation files inside common/messages and divide into frontend and backend folder.
For example: Yii message will generate the translation files as follows:
common/
.....
messages/
en-EN/
backend.php
frontend.php
ru-RU/
backend.php
frontend.php
.....
If you want to edit the translate text, just open backend.php or frontend.php file and edit.
I'm trying to set up the website's frontend translation using the i18l thing. Here is my i18l.php file placed on frontend/config
<?php
return [
'sourcePath' => 'frontend',
'languages' => ['en-US', 'pt-BR'] , //Add languages to the array for the language files to be generated.
'translator' => 'Yii::t',
'sort' => false,
'removeUnused' => false,
'only' => ['*.php'],
'except' => [
'.svn',
'.git',
'.gitignore',
'.gitkeep',
'.hgignore',
'.hgkeep',
'/messages',
'/vendor',
],
'format' => 'php',
'messagePath' => 'frontend' . DIRECTORY_SEPARATOR . 'translations',
'overwrite' => true,
];
and here my main.php also on frontend
(...)
'language' => 'en-US',
'components' => [
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => 'frontend/translations',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',
],
],
],
]
I'm using the <?= Yii::t('app', 'some string') ?> on the sites and layouts and when I run the command ./yii message/extract #frontend/config/i18n.php it creates to me a folder called 'translations' contain other two folders 'en-US' and 'pt-BR' both with app.php which i already had filled with some translations. But still, no translation happens when i change the language on the main.php as it should be (i think).
I would appreciate if someone could give me a hand on that.
Thanks.
Great post, with all the needed details.
I was struggling with the same things, but you did it quite well.
So, if you can run the command and it generates the file, then the sourcePath is correct.
If it doesn't display the translation messages at runtime, despite your setting changes, then, I presume the issue could be on your basePath:
Try using, on your basePath configuration, the following:
'basePath' => '#frontend/translations',
Extension's Github project: https://github.com/mdmsoft/yii2-admin
I'm using the advanced template of yii2, so I've backend, frontend and common folders all into an advanced folder.
the advanced folder itself is on the same level of vendor folder.
I've others extensions and all is working
Then I installed yii2-admin by composer
php composer.phar require mdmsoft/yii2-admin "*"
Installation worked well.
Into vendor folder I've now mdmsoft folder with yii2-admin subfolder into it.
This is the actual content of vendor/yiisoft/extensions.php (modified by composer installation, I haven't manually touched it)
<?php
$vendorDir = dirname(__DIR__);
return array (
'yiisoft/yii2-jui' =>
array (
'name' => 'yiisoft/yii2-jui',
'version' => '2.0.0.0',
'alias' =>
array (
'#yii/jui' => $vendorDir . '/yiisoft/yii2-jui',
),
),
'mdmsoft/yii2-admin' =>
array (
'name' => 'mdmsoft/yii2-admin',
'version' => '1.0.2.0',
'alias' =>
array (
'#mdm/admin' => $vendorDir . '/mdmsoft/yii2-admin',
),
),
);
I added this configurations to common/config/main.php
<?php
return [
...
'components' => [
...
'authManager' => [
'class' => 'yii\rbac\DbManager', // or use 'yii\rbac\PhpManager'
],
],
];
And these configs adedd to backend/config/main.php
'modules' => [
'admin' => [
'class' => 'mdm\admin\Module',
]
],
'components' => [
'as access' => [
'class' => 'mdm\admin\components\AccessControl',
'allowActions' => [
'admin/*', // add or remove allowed actions to this list
]
],
],
(I omitted useless code in every code block)
I also have enabled pretty url. And it was working.
Complete error stack
2014-11-06 17:05:49 [127.0.0.1][-][-][error][ReflectionException] exception 'ReflectionException' with message 'Class mdm\admin\Module does not exist' in C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\di\Container.php:408
Stack trace:
#0 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\di\Container.php(408): ReflectionClass->__construct('mdm\\admin\\Modul...')
#1 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\di\Container.php(354): yii\di\Container->getDependencies('mdm\\admin\\Modul...')
#2 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\di\Container.php(147): yii\di\Container->build('mdm\\admin\\Modul...', Array, Array)
#3 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\BaseYii.php(344): yii\di\Container->get('mdm\\admin\\Modul...', Array, Array)
#4 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\base\Module.php(354): yii\BaseYii::createObject(Array, Array)
#5 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\base\Module.php(511): yii\base\Module->getModule('admin')
#6 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\base\Module.php(449): yii\base\Module->createController('admin/route')
#7 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\web\Application.php(83): yii\base\Module->runAction('admin/route', Array)
#8 C:\xampp\htdocs\advanced\vendor\yiisoft\yii2\base\Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))
#9 C:\xampp\htdocs\advanced\backend\web\index.php(18): yii\base\Application->run()
#10 {main}
The problem
If I open my backend at /admin I got this exception
ReflectionException Class mdm\admin\Module does not exist
It's my first Yii2 app, so I've no idea of what's the problem and how to debug it.
Edit 1
I checked C:\xampp\htdocs\vendor\mdmsoft\yii2-admin\Module.php and in its content there is the Module class definition
class Module extends \yii\base\Module
EDIT 2
My first error is that asAccess was put into components array. But It must be outside of it, at the same level
Now the error is changed:
Class mdm\admin\components\AccessControl does not exist
First: this is wrong
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'as access' => [
'class' => 'mdm\admin\components\AccessControl',
'allowActions' => [
// 'admin/*', // add or remove allowed actions to this list
]
],
],
It must be as here:
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
],
'as access' => [
'class' => 'mdm\admin\components\AccessControl',
'allowActions' => [
// 'admin/*', // add or remove allowed actions to this list
]
],
Second: you must run this command
php composer.phar require mdmsoft/yii2-admin "*"
from within the app root (htdocs\advanced), NOT from where you have executed the installation of yii (you were into htdocs). Only in this way to install yii2-admin into your app
Third: it's not true that console has not authManager ! if you have to use rbac, to simply do the default yii2 migration you must have it configured into console app. So my suggestione is: configure authManager into console, and other things into frontend and or backend where you need it
Fourth: you cannot admin frontend route from backend, so you need to enable this module even into frontend
"I added this configurations to common/config/main.php"
NOTE: !! Dont put at common, put in frontend or backend... console application has no user component and dont need access control.
Try adding this in backend/config/main right before 'modules'
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'extensions' => require(__DIR__ . '/../../vendor/yiisoft/extensions.php'),
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
],
and I can't but assume that the whole thing has return in front, so the whole code is like:
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'extensions' => require(__DIR__ . '/../../vendor/yiisoft/extensions.php'),
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
],
'modules'=>[
'admin' => [
'class' => 'mdm\admin\Module',
],
],
'as access' => [
'class' => 'mdm\admin\components\AccessControl',
'allowActions' => [
'admin/*',
],
],
];
Hope this helps :D
I have set 3 environments.
My app needs to load different sets of translations because each env is different.
I have the RO, HU, DE languages.
I am trying to set the translations, but it does not work.
in frontend/config main.php i have:
'sourceLanguage' => 'en',
'language' => 'en',
in the frontend/web/index.php i have:
defined('YII_ENV') or define('YII_ENV', 'dev_ro');
also, i am merging the config array:
(file_exists(__DIR__ . '/../../environments/' . YII_ENV . '/common/config/main-local.php') ? require(__DIR__ . '/../../environments/' . YII_ENV . '/common/config/main-local.php') : [])
now, in environments/dev_ro/common/config/, in components i have:
'i18n' => [
'translations' => [
'companie' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
'sourceLanguage' => 'en',
'fileMap' => [
'companie' => 'companie.php',
],
],
],
],
in the Companie model i have:
'nume' => Yii::t('companie', 'Name'),
this is the movie, with my thing:
movie
The problem is in app*, because it's not app* category, this works:
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
'fileMap' => [
'companie' => 'companie.php',
],
],
],
],
Or if you want write 'companie*' =>
If it is still not working, you did set incorrect path to translate files. By default it must be BasePath/messages/LanguageID/CategoryName.php.
If you want to use one file in backend and frontend you should create for example common alias in common config (advanced yii application) and set this alias in i18n config. This is full example:
Common config:
Yii::setAlias('#common', dirname(__DIR__));
return [
'language' => 'ru',
'sourceLanguage' => 'ru',
'components' => [
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#common/messages',
'fileMap' => [
'companie' => 'companie.php',
],
....
In traslate file /common/messages/en-US/companie.php
<?php
return [
'string in russian' => 'string in english'
];
Check translate using this code:
\Yii::$app->language = 'en-US';
echo \Yii::t('companie', 'string in russian');
You can also try to replace dash with underscore in language code and folder name:
en-US >> en_US
Works for me.