This document is for a version of CakePHP that is no longer supported. Please upgrade to a newer release!
TranslateBehavior es bastante fácil de configurar y trabaja fuera de la caja con muy poca configuración. En esta sección, usted aprenderá cómo añadir y configurar el comportamiento (behavior) para usarlo en cualquier modelo.
Puede utilizar la consola de CakePHP o puede crearlo manualmente. Se recomienda utilizar la consola para esto, por que podrían pasar que hallan cambios de diseño en las futuras versiones de CakePHP. Si lo haces por consola, puedes estar seguro que tiene el correcto diseño.
./cake i18n
Seleccione [I]
y se ejecuta el script e inicializa la Base de datos
i18n. Se le preguntará si desea eliminar cualquiera que exista y si
desea crearla.Responde un Sí, si usted esta seguro de que no existe una
tabla i18n, y responda con Sí para crear la tabla de nuevo.
Se debe incorporar al modelo haciendo uso de la propiedad $actsAs
como en el siguiente ejemplo.
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array(
'Translate'
);
}
?>
Esto no hará nada aún, pues es necesario configurar algunas opciones antes de comenzar a funcionar. Se deben definir qué campos de el modelo actual serán rastreados en la tabla de traducciones creada en el paso anterior.
Se pueden establecer los campos simplemente extendiendo el valor
'Translate'
con otro array, por ejemplo:
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array(
'Translate' => array(
'campoUno', 'campoDos', 'campoN'
)
);
}
?>
Luego de haber hecho esto (por ejemplo poner «nombre» como uno de los campos) ya has terminado la configuración básica. Genial! De acuerdo con el ejemplo anterior, ahora el modelo debería verse algo así:
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array(
'Translate' => array(
'nombre'
)
);
}
?>
Desde ahora en cada actualización/creación de un registro hará que TranslateBehavior copie el valor «nombre» en la tabla de traducciones (por defecto: i18n) de acuerdo a la localización actual. Una localización corresponde al identificador de una lengua
La localización actual es el valor actual de
Configure::read('Config.language')
. El valor de Config.language es
establecido en la Clase L10n - a no ser que ya se haya establecido. Sin
embargo, TranlateBehavior te permite invalidar esto último “al vuelo”,
lo cual permite al usuario de tus páginas crear multiples versiones sin
la necesidad de que este cambie sus preferencias. Más sobre esto en la
siguiente sección.
Si se desea obtener todos los registros de traducción asociados al modelo actual, simplemente se extiende el arreglo de campos en la configuracion como se muestra abajo. El nombre se puede definir sin restricciones
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array(
'Translate' => array(
'name' => 'nameTranslation'
)
);
}
?>
Con esta configuración el resultado de find() se verá similar a esto:
Array
(
[Post] => Array
(
[id] => 1
[name] => Beispiel Eintrag
[body] => lorem ipsum...
[locale] => de_de
)
[nameTranslation] => Array
(
[0] => Array
(
[id] => 1
[locale] => en_us
[model] => Post
[foreign_key] => 1
[field] => name
[content] => Example entry
)
[1] => Array
(
[id] => 2
[locale] => de_de
[model] => Post
[foreign_key] => 1
[field] => name
[content] => Beispiel Eintrag
)
)
)
Nota: El registro del modelo contiene un campo virtual llamado «locale», el cual indica que «locale» es usado en el resultado.
You can also retrieve all translations, only when you need them, using the bindTranslation method
bindTranslation($fields, $reset)
$fields
is a named-key array of field and association name, where
the key is the translatable field and the value is the fake association
name.
$this->Post->bindTranslation(array ('name' => 'nameTranslation'));
$this->Post->find('all', array ('recursive'=>1)); // need at least recursive 1 for this to work.
With this setup the result of your find() should look something like this:
Array
(
[Post] => Array
(
[id] => 1
[name] => Beispiel Eintrag
[body] => lorem ipsum...
[locale] => de_de
)
[nameTranslation] => Array
(
[0] => Array
(
[id] => 1
[locale] => en_us
[model] => Post
[foreign_key] => 1
[field] => name
[content] => Example entry
)
[1] => Array
(
[id] => 2
[locale] => de_de
[model] => Post
[foreign_key] => 1
[field] => name
[content] => Beispiel Eintrag
)
)
)
You can force the model which is using the TranslateBehavior to save in a language other than the on detected.
To tell a model in what language the content is going to be you simply
change the value of the $locale
property on the model before you
save the data to the database. You can do that either in your controller
or you can define it directly in the model.
Example A: In your controller
<?php
class PostsController extends AppController {
var $name = 'Posts';
function add() {
if ($this->data) {
$this->Post->locale = 'de_de'; // we are going to save the german version
$this->Post->create();
if ($this->Post->save($this->data)) {
$this->redirect(array('action' => 'index'));
}
}
}
}
?>
Example B: In your model
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array(
'Translate' => array(
'name'
)
);
// Option 1) just define the property directly
var $locale = 'en_us';
// Option 2) create a simple method
function setLanguage($locale) {
$this->locale = $locale;
}
}
?>
If you expect a lot entries you probably wonder how to deal with a rapidly growing database table. There are two properties introduced by TranslateBehavior that allow to specify which «Model» to bind as the model containing the translations.
These are $translateModel and $translateTable.
Lets say we want to save our translations for all posts in the table «post_i18ns» instead of the default «i18n» table. To do so you need to setup your model like this:
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array(
'Translate' => array(
'name'
)
);
// Use a different model (and table)
var $translateModel = 'PostI18n';
}
?>
Important is that you have to pluralize the table. It is now a usual model and can be treated as such and thus comes with the conventions involved. The table schema itself must be identical with the one generated by the CakePHP console script. To make sure it fits one could just initialize a empty i18n table using the console and rename the table afterwards.
For this to work you need to create the actual model file in your models folder. Reason is that there is no property to set the displayField directly in the model using this behavior yet.
Make sure that you change the $displayField
to 'field'
.
<?php
class PostI18n extends AppModel {
var $displayField = 'field'; // important
}
// filename: post_i18n.php
?>
That’s all it takes. You can also add all other model stuff here like
$useTable. But for better consistency we could do that in the model
which actually uses this translation model. This is where the optional
$translateTable
comes into play.
If you want to change the name of the table you simply define $translateTable in your model, like so:
<?php
class Post extends AppModel {
var $name = 'Post';
var $actsAs = array(
'Translate' => array(
'name'
)
);
// Use a different model
var $translateModel = 'PostI18n';
// Use a different table for translateModel
var $translateTable = 'post_translations';
}
?>
Please note that you can’t use $translateTable alone. If you don’t
intend to use a custom $translateModel
then leave this property
untouched. Reason is that it would break your setup and show you a
«Missing Table» message for the default I18n model which is created in
runtime.