2 votes

Appliquer le comportement de traduction de CakePHP après coup

J'apprends lentement à appliquer le comportement de traduction de CakePHP et je pense avoir saisi les bases, mais je travaille sur un projet existant avec des données existantes. C'est génial que Cake insère de nouveaux enregistrements pour moi, mais j'ai besoin d'insérer manuellement (je suppose) quelques traductions pour certaines données existantes. Ma première question :

Dois-je avoir un enregistrement dans ma table i18n pour en_us si c'est ma langue par défaut et la langue utilisée dans ma table principale ? Par exemple, si categories.name = 'Entertainment', dois-je vraiment créer un enregistrement "duplicate" dans i18n pour indiquer de spécifier la traduction anglaise de "Entertainment" ? L'évidence empirique semble dire que oui, mais cela semble être beaucoup de travail supplémentaire, alors j'espère que quelqu'un pourra me dire que je manque quelque chose.

Deuxièmement, existe-t-il un moyen "facile" d'introduire des enregistrements de traduction dans la base de données ? Au fur et à mesure que des langues sont ajoutées au cours d'un projet, il va être très difficile de revenir en arrière et de créer des enregistrements i18n pour les données existantes.

Merci.

3voto

Ramiro Araujo Points 138

Je sais que cette question est ancienne, mais comme elle est restée sans réponse et que j'ai eu du mal à la résoudre, voici mes deux cents :

scope, Cakephp 1.3.

tout d'abord, vous avez besoin d'un enregistrement i18n pour chaque champ -> enregistrement -> modèle dans votre application, bien sûr seulement les modèles avec le comportement Translate et seulement pour les champs spécifiés, donc oui, vous vous retrouverez avec un contenu dupliqué à la fois dans les champs réels du modèle et dans la table i18n.

En outre, vous devez disposer de traductions existantes pour toutes les langues que vous spécifiez pour que les méthodes de recherche puissent retourner quelque chose. Cette question m'a laissé perplexe, car j'ai également ajouté le comportement de traduction à un projet déjà développé, avec des tonnes de données. En fait, j'ai créé une méthode de synchronisation afin de créer chaque traduction pour chaque champ de chaque modèle avec le comportement translate. Si j'ajoute une nouvelle langue à l'avenir, je devrai l'exécuter à nouveau.

Voici le code pour cela :

$locales = array( 'spa', 'eng', 'por' );
$models = array( 'Event', 'News', 'Promotion', 'Shop', 'ShopCategory' );

foreach ( $models as $model )
{
    $this->loadModel( $model );
    $records = $this->{$model}->find( 'all', array(
                                                  'fields' => array( "*" ),
                                                  'contain' => FALSE
                                             ) );

    $fields = $this->{$model}->actsAs['Translate'];
    foreach ( $records as $record )
    {
        foreach ( $fields as $field )
        {
            foreach ( $locales as $locale )
            {
                $content = mysql_real_escape_string( $record[$model][$field] );
                $this->{$model}->query( "INSERT INTO `i18n` (`locale`, `model`, `foreign_key`, `field`, `content`) VALUES('{$locale}', '{$model}', '{$record[$model]['id']}', '{$field}', '{$content}');" );
            }
        }
    }
}

Conseil : créez un index unique dans la table i18n avec les clés locale, model, foreign_key et field.

Ainsi, maintenant que mes données d'origine sont répliquées dans toutes les langues, je dois être en mesure de créer de nouveaux enregistrements avec une langue donnée. Le problème est que si je crée un nouvel enregistrement en anglais, je devrais pouvoir le mettre à jour en espagnol, mais comme il n'y a pas d'enregistrement i18n pour l'espagnol, je ne peux pas voir l'enregistrement dans mon CMS et je ne peux pas le modifier. La façon dont j'ai résolu ce problème est de créer des enregistrements i18n pour chaque langue lors de la création de nouveaux enregistrements, mais de n'utiliser que la langue actuelle lors de l'édition des enregistrements.

J'ai utilisé cette modification pour le comportement de Translate : http://bin.cakephp.org/view/1939852942

Mais la plupart des exemples avec cette modification echo $this->Form->input('nom.eng') ; echo $this->Form->input('nom.spa') ; echo $this->Form->input('description.eng') ; echo $this->Form->input('description.spa') ;

Je trouve cela ennuyeux, donc j'ai créé une fonction d'aide dans app_controller pour convertir les champs traduisibles en cette structure de données :

function _expandLocalizations( $data )
{
    foreach ( $data as $modelName => $modelData )
    {
        if ( !isset( $modelData[$this->{$modelName}->primaryKey] ) )
        {
            foreach ( $this->{$modelName}->actsAs['Translate'] as $field )
            {
                $translations = array();
                foreach ( $this->languages as $language )
                {
                    $translations[$language] = $this->data[$modelName][$field];
                }
                $data[$modelName][$field] = $translations;
            }
        }
    }
    return $data;
}

et dans chaque méthode d'ajout :

if ( !empty( $this->data ) )
    {
        $this->News->set( $this->data );
        if ( $this->News->validates() )
        {
            $this->News->create();
            $data = $this->_expandLocalizations( $this->data );
            $saved = $this->News->save( $data );
            if ( $saved )
            {

De cette façon, je peux utiliser les formulaires traditionnels et je n'ai pas besoin de modifier la vue si j'ajoute de nouvelles langues. J'ai besoin de modifier la méthode d'ajout traditionnelle car j'ai besoin des données soumises pour la validation, mais des données modifiées pour la sauvegarde.

Enfin, j'ai suivi ces étapes pour changer la langue dans le site/admin : http://nuts-and-bolts-of-cakephp.com/2008/11/28/cakephp-url-based-language-switching-for-i18n-and-l10n-internationalization-and-localization/

En gros, c'est ça. 1. Vous créez des traductions pour chaque donnée que vous avez déjà dans la BD, chacune étant copiée dans chaque langue. 2. Vous créez chaque traduction pour les nouveaux enregistrements à la création, toutes avec la même valeur bien sûr. 3. Modifiez chaque enregistrement dans la traduction sélectionnée.

0voto

Rob Wilkerson Points 12220

Je n'ai pas de réponse à la deuxième question, mais la réponse à la première semble être "oui". Après avoir creusé dans le code source, il semble que la clause where des requêtes générées limite les résultats à ceux où le nom du champ récupéré a une valeur de locale pour la locale actuelle. C'est assez limitatif.

Il y a un billet existant pour cela (ou quelque chose de très similaire).

0voto

Kristoffer Darj Points 103

Pour ce qui est de la première question, la réponse est non. Il n'est pas nécessaire de dupliquer les données, même si je le pensais aussi au début.

J'ai écrit un article de blog à ce sujet pour aider les âmes perdues. http://kristofferdarj.se/2012/05/cakephp-how-to-actually-use-i18n/

0voto

Kristof Neirynck Points 1347

L'utilisation du comportement de traduction avec de nombreuses colonnes ralentit considérablement votre site. Le moyen le plus simple que j'ai trouvé pour l'accélérer était d'ajouter cet index. Cet index est commenté dans cakephp/app/Config/Schema/i18n.sql et je ne sais pas pourquoi.

ALTER TABLE rabotvins_i18n
ADD UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X