Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cakephp 3.x - Internationalization a full page

I'm working with cakephp 3.x and I would like to translate my website in several languages. I read the documentation about internationalization ( http://book.cakephp.org/3.0/en/core-libraries/internationalization-and-localization.html ) for cakephp 3.x and it is only explained how to translate words and sentences but not a full page.

What is the best solution to translate a full page of text ? What I think to do is to have a page for each language and in the beforeFilter function, select the correct page. Is it a good solution ?

I'm asking also how to have a translation of some paragraph that are saved in a database, for instance my news page are saved in the database and I would like to have a version of my news in deferent language. Must I add a row for each language in my database or is there a better solution ?

Thanks for your time

Dany

like image 884
Snnopy_87 Avatar asked Jul 30 '15 06:07

Snnopy_87


2 Answers

Internationalization & Localization has two basic tasks, in both cases the intention is that the only thing you need to do at run time to change the language is to call I18n::locale e.g.:

use Cake\I18n\I18n;
...
public function beforeFilter()
{
    if (should show german) {
        I18n::locale('de_DE');
    }
}

Once set up there are no extra steps to having a multilingual site. Be sure to set the default locale in the bootstrap file as this is what's used if the locale is not overriden at runtime.

Static content

think to do is to have a page for each language and in the beforeFilter function, select the correct page. Is it a good solution ?

No.

Static files, unless you intend to have fundamentally different page layouts per language or similar, are normally a single template using translate functions and po files.

From the docs:

Below is an example of some code for a single-language application:

<h2>Popular Articles</h2>

To internationalize your code, all you need to do is to wrap strings in __() like so:

<h2><?= __('Popular Articles') ?></h2>

There are more steps involved (see the docs), but using the double-underscore method with your default language text prepares your application to be used with multiple languages.

Dynamic content

Database content is normally translated using the translate behavior.

This behavior stores all translated content, for all tables using the behavior, in a separate table. At run time translations are automatically retrieved. To illustrate:

$articles = TableRegistry::get('Articles');

I18n::locale('eng');
$article = $articles->get(12);
echo $article->title; // Echoes 'A title'

I18n::locale('spa');
$article = $articles->get(12);
echo $article->title; // Echoes 'Un titulo'

Putting it all together

Using both static translations and the translate behavior, your template files will look something like this:

<h1><?= h($article->title) ?></h1>
<?= $article->body ?>
<p><?= __('Did you like that article? Let us know') ?></p>

Note that appart from using the double-underscore method, it's exactly the same as you'd expect for a single language application.

like image 106
AD7six Avatar answered Sep 23 '22 18:09

AD7six


Hi for me the best way is :

initializing the i18n Database Table

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)
);

Attaching the Translate Behavior to Your Tables

class ArticlesTable extends Table
{

    public function initialize(array $config)
    {
        $this->addBehavior('Translate', ['fields' => ['title', 'body']]);
    }
}

The first thing to note is that you are required to pass the fields key in the configuration array. This list of fields is needed to tell the behavior what columns will be able to store translations.

use Cake\ORM\Behavior\Translate\TranslateTrait;
use Cake\ORM\Entity;

class Article extends Entity
{
    use TranslateTrait;
}

Saving Multiple Translations

$translations = [
    'en_US' => ['title' => "An article"],
    'fr_FR' => ['title' => "Un article"]
];

foreach ($translations as $lang => $data) {
    $article->translation($lang)->set($data, ['guard' => false]);
}

$articles->save($article);

Reading Translated Content

I18n::locale('en_US');
$articles = TableRegistry::get('Articles');

// All entities in results will contain english translation
$results = $articles->find()->all();

CakePHP : Translate

CakePHP : Internationalization & Localization

like image 22
eclaude Avatar answered Sep 22 '22 18:09

eclaude