Multilingual in cakephp 3
Hello friends, welcome to findnerd. Today I am going to tell you how to use multilingual in cakephp 3.x. Before moving ahead, lets create articles table. Here we are going to translate the title of articles
table to french and spanish.
Step 1: Run the following query in order to create a new table articles
:
CREATE TABLE IF NOT EXISTS `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`body` text NOT NULL,
`category_id` int(11) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
`user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Step 2: Now lets create i18n table to store multiple translations in it. Run the following query:
CREATE TABLE i18n (
id int NOT NULL auto_increment,
locale varchar(6) NOT NULL,
model varchar(255) NOT NULL,
foreign_key int(10) NOT NULL,
field varchar(255) NOT NULL,
content text,
PRIMARY KEY (id),
UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
INDEX I18N_FIELD(model, foreign_key, field)
);
Step 3: Run the bake command to create Articles Controller with add/edit/delete/views functionalities. Go to the terminal window by pressing ctrl+alt+t. Now go to the root directory of the project where we are going to run the bake command. In my case it is /var/www/version_one/bikewale/
. Now run the following command to run bake:
$ sudo bin/cake bake all
Welcome to CakePHP v3.3.11 Console
---------------------------------------------------------------
App : src
Path: /var/www/version_one/bikewale/src/
PHP : 5.5.9-1ubuntu4.20
---------------------------------------------------------------
Bake All
---------------------------------------------------------------
Possible model names based on your database:
- articles
- categories
- users
You will see the list of model names available to bake. In order to bake articles run the following command and hit Enter.
$ sudo bin/cake bake all articles
This command will create model, views and controller of Articles.
Step 4: Now open the file cakephp3/src/Model/Table/ArticlesTable.php
and attach the behaviour to the table object. Add the following line in initialize
function : $this->addBehavior('Translate', ['fields' => ['title', 'body']]);
class ArticlesTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Translate', ['fields' => ['title']]);
}
}
To do multiple translations you need to modify Entity class: cakephp3/src/Model/Entity/Article.php
use Cake\ORM\Behavior\Translate\TranslateTrait;
use Cake\ORM\Entity;
class Article extends Entity
{
use TranslateTrait;
}
Include following lines to the controller:
use Cake\ORM\Behavior\Translate\TranslateTrait;
use Cake\I18n\I18n;
Following function will translate the language in french and spanish and save it in i18n
table. You can modify the code in your own way, its just a demo.
public function newTranslation(){
$article = $this->Articles->newEntity();
if ($this->request->is('post')) {
$article = $this->Articles->patchEntity($article, $this->request->data);
if(isset($this->request->data['french']) && !empty($this->request->data['french'])){
$article->translation('fr')->title = $this->request->data['french'];
}
if(isset($this->request->data['spanish']) && !empty($this->request->data['spanish'])){
$article->translation('es')->title = $this->request->data['spanish'];
}
// Added this line
$article->user_id = $this->Auth->user('id');
if ($this->Articles->save($article)) {
$this->Flash->success(__('Your article has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your article.'));
}
$this->set('article', $article);
// Just added the categories list to be able to choose
// one category for an article
$categories = $this->Articles->Categories->find('treeList');
$this->set(compact('categories'));
}
$article->translation('fr')->title, $article->translation('es')->title
:
These variables will save french and spanish in i18n table in the following way:
Now create the view file for this function in cakephp3/src/Template/Articles/new_translation.ctp
and save it. Access the following url: http://localhost/cakephp3/articles/newTranslation
<nav class="large-3 medium-4 columns" id="actions-sidebar">
<ul class="side-nav">
<li class="heading"><?= __('Actions') ?></li>
<li><?= $this->Html->link(__('List Articles'), ['action' => 'index']) ?></li>
</ul>
</nav>
<div class="articles form large-9 medium-8 columns content">
<?= $this->Form->create($article) ?>
<fieldset>
<legend><?= __('Add New Article') ?></legend>
<?php
echo $this->Form->input('title');
echo $this->Form->input('body');
echo $this->Form->input('french');
echo $this->Form->input('spanish');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
Index function in Articles controller looks like:
public function index()
{
$articles = $this->paginate($this->Articles);
$this->set(compact('articles'));
$this->set('_serialize', ['articles']);
}
You can see the output of articles page in the following url: http://localhost/cakephp3/articles
In order to translate in Spanish you need to write the following line: "I18n::locale('es')
" as shown below:
public function index()
{
I18n::locale('es'); // Translate is Spanish
$articles = $this->paginate($this->Articles);
$this->set(compact('articles'));
$this->set('_serialize', ['articles']);
}
You can have a look on the following output. You can see that 'An Article' has been translated to 'Un Articulo'. Similarly rest of the titles have been translated as shown below.
Similarly for translating to French keywords, you need to write the following code: I18n::locale('fr')
public function index()
{
I18n::locale('fr'); // Convert to French keywords
$articles = $this->paginate($this->Articles);
$this->set(compact('articles'));
$this->set('_serialize', ['articles']);
}
For further help you can go through Cakephp 3 tutorials:
All done!.
Thanks for reading the blog.
0 Comment(s)