# Translate Behavior in Cakephp 5.x

**URL:** <https://discourse.cakephp.org/t/translate-behavior-in-cakephp-5-x/11530>\
**Category:** Need Help\
**Tags:** translation, behavior, i18n, help\
**Created:** [September 22, 2023, 11:57am UTC](https://discourse.cakephp.org/t/translate-behavior-in-cakephp-5-x/11530 "2023-09-22T11:57:05Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![harikt](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/harikt/32/2908_2.png) [@harikt](https://discourse.cakephp.org/u/harikt)\
**Post date:** [September 22, 2023, 11:57am UTC](https://discourse.cakephp.org/t/translate-behavior-in-cakephp-5-x/11530/1 "2023-09-22T11:57:06Z")

</div>

Hi all,

I have been experimenting with the cakephp Translate Behaviour. Reading the docs, I liked the concept, but trying out I felt some discomforts. So I would like to share so that it can be improved.

The current view is assuming all languages contents are translating at the same time.

1. Call inside the template

```auto
<!-- File: templates/Articles/add.php -->

<h1>Add Article : ('title').</h1>
<?php
echo $this->Form->create($article);
// Hard code the user for now.
echo $this->Form->control('user_id', ['type' => 'hidden', 'value' => 1]);
echo $this->Form->control('title');
echo $this->Form->control('body', ['rows' => '3']);
/*
<fieldset>
    <legend>English</legend>
    <?= $this->Form->control('_translations.en_GB.title'); ?>
    <?= $this->Form->control('_translations.en_GB.body', ['rows' => '3']); ?>
</fieldset>
*/
?>
<fieldset>
    <legend>Spanish</legend>
    <?= $this->Form->control('_translations.es_AR.title'); ?>
    <?= $this->Form->control('_translations.es_AR.body'); ?>
</fieldset>
<?php
echo $this->Form->control('tag_string', ['type' => 'text']);
echo $this->Form->button(__('Save Article'));
echo $this->Form->end();
?>

```

If you have closely looked at the above template, you can see the default locale field is using `$this->Form->control('title')` for rendering and not as `$this->Form->control('_translations.en_GB.title')` .

If we go with `$this->Form->control('_translations.en_GB.title')` path, the title field inside the articles table will be empty. The default locale `en_GB` goes to the `articles_translations` table.

1. Validation

According to the [docs](https://book.cakephp.org/5/en/orm/behaviors/translate.html#validating-translated-entities) we can add validation as

```auto
$this->addBehavior('Translate', [
    'strategyClass' => ShadowTableStrategy::class,
    'fields' => ['title', 'body'],
    'validator' => 'translated'
]);

```

so a validator as

```auto
public function validationTranslated(Validator $validator): Validator
{
    $validator
        ->notEmptyString('title')
        ->minLength('title', 10)
        ->maxLength('title', 255)

        ->notEmptyString('body')
        ->minLength('body', 10);

    return $validator;
}

```

But as we are using the `$this->Form->control('title')` for the defaultLocale. So to validate the default fields we need to add another default validator.

```auto
public function validationDefault(Validator $validator): Validator
{
    $validator
        ->notEmptyString('title')
        ->minLength('title', 10)
        ->maxLength('title', 255)

        ->notEmptyString('body')
        ->minLength('body', 10);

    return $validator;
}

```

I think that is an extra overhead.

1. Accessing the value

```auto
$lang = I18n::setLocale('es_AR');

// Update retrieving tags with contain()
$article = $this->Articles
    ->find('translations')
    ->where(['slug' => $slug])

    ->contain('Tags')
    ->firstOrFail();

```

Suppose you have the article object now you can access the value as

1. `$article->title` : Which will provide the value from the current locale.
2. `$article->translation('es_AR')->title);` get the value of the locale.

The above two works. But lets assume your default locale is `en_GB` and your current locale set is different. Now in-order to get the default locale, calling `$article->translation('en_GB')->title);` is not giving you value.

Not sure if this is a bug or this is the default behavior.

All the source code for the experiment is located at [GitHub - harikt/cakephp-experiments](https://github.com/harikt/cakephp-experiments) if anyone want to test this.

---

<div class="post-metadata">

**Author:** ![harikt](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/harikt/32/2908_2.png) [@harikt](https://discourse.cakephp.org/u/harikt)\
**Post date:** [September 23, 2023, 4:19pm UTC](https://discourse.cakephp.org/t/translate-behavior-in-cakephp-5-x/11530/2 "2023-09-23T16:19:38Z")

</div>

So I digged a bit into the code. 3rd case is as expected as in code.

> <https://github.com/cakephp/cakephp/blob/fbd042b57ea0f30224e8c1df01fc6e45e9f04c93/src/ORM/Behavior/Translate/TranslateTrait.php#L38>

As we can alter this behavior via a different trait, that seems not a big deal.

---

<div class="post-metadata">

**Author:** ![ADmad](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/admad/32/20_2.png) [@ADmad](https://discourse.cakephp.org/u/ADmad)\
**Post date:** [October 1, 2023, 4:04pm UTC](https://discourse.cakephp.org/t/translate-behavior-in-cakephp-5-x/11530/3 "2023-10-01T16:04:35Z")

</div>

#2 is also a non issue. Using a validator named `translated` is not mandatory, it’s just an example. You can just use the default validator by setting `'validator' => 'default'` for the behavior.
