Bonjour,

Je souhaite internationalisé mon site, Fr par défaut et EN anglais et EO esperanto.

Ce que je fais

L'idée en partant simplement déjà de la page index :
Donc par défaut en fr sauf si:

  • symfony détecte la locale du navigateur en EN ou EO pour afficher le texte correspondant
  • L'utilisateur choisit dans le menu "Langue du site" : en ou eo ou fr

    Un fois connecté j'aimerai que la class User conserve la langue du site et qu'elle soit utilisé pour l'affichage.

    Pour l'instant j'ai testé en envoyant via le controller la variable "_locale" qui sera atribué suivant le menu, ou detection par symfony :

return new Response($twig->render('index/index.twig',
                array(
                    'title'=> 'Jaaser.',
                    '_locale'=>'en',
                )
            )
        );

Dans twig, j'ai mis :

{% trans from "messages" into ( _locale ) %}Salut{% endtrans %}

Et si je change manuellement la variable _locale, ça fonctionne (suivant mes fichiers translations/messages.eo.yaml et messages.en.yaml), j'ai bien Hello ou Saluton

1 ) Mais est-ce que la façon de faire est bonne ou je m'y prend pas bien du tout ?
2 ) L'url dans ce cas, restera toujours la même (ex: /home/ et pas /fr/home ou /eo/home), donc c'est peut etre pas bien ?
3) Est ce que je devrais pas faire simplement Fr par défaut et seulement choix par menu de la langue du site (sans detection par symfony) ?

Pour info, j'ai déjà lu plusieurs fois la doc symfony4 translations, mais ça ne répond pas à mes questions, et je suis débutant en symfony (je commence par le 4)
Merci pour votre aide

2 réponses


laplumaencre
Auteur
Réponse acceptée

Salut bleduc_weglot,
Je te remercie, je n'ai pas mis en résolu le post car je voulais prendre un peu de temps pour expliquer et afficher un de code pour aider d'autre personne qui serait dans le même cas.
Bon je me lance, déjà le code dans routes.yaml (j'ai abandonnée les routes par Annotations)

before:
    path: /{_locale}
    controller: App\Controller\StartController::getIndex
    defaults:   {_locale: fr}
    requirements:
        _locale: en|fr|eo

index:
    path: /{_locale}/
    controller: App\Controller\StartController::getIndex
    defaults:   {_locale: fr}
    requirements:
        _locale: en|fr|eo

admin:
    path: /{_locale}/admin/
    controller: App\Controller\StartController::getAdmin
    requirements:
        _locale: en|fr|eo

login:
    path: /{_locale}/login
    controller: App\Controller\SecurityController::login
    requirements:
        _locale: en|fr|eo

register:
    path: /{_locale}/register
    controller: App\Controller\RegistrationController::register
    requirements:
        _locale: en|fr|eo

before permet que quand on arrive sur le site sans /fr/ dans l'url ou si l'utilisateur bidouille l'url, ça affiche quand meme l'index.

Dans framework.yaml, pas grand chose =>

framework:
    secret: '%env(APP_SECRET)%'
    default_locale: fr

Dans translation.yaml =>

framework:
    default_locale: '%locale%'
    translator:
        paths:
            - '%kernel.project_dir%/translations'
        fallbacks:
            - '%locale%'

Ensuite il faut créer dans le dossier translations, les fichiers de traduction avec y compris la langue par défaut.
Par exemple moi pour le site en fr/eo/en, j'ai messages.fr.yaml messages.en.yaml messages.eo.yaml, le fr me sert de base, ensuite je mets pareil dans les autres, exemple =>

fr
header:
  btnLangueduSite: Langue du site
  btnConnexion: Connexion
  btnInscription: S'inscrire
  btnDeconnexion: Déconnexion

en
header:
  btnLangueduSite: Site language
  btnConnexion: Login
  btnInscription: Sign Up
  btnDeconnexion: Logout

eo
header:
  btnLangueduSite: Rejeto lingvo
  btnConnexion: Ensaluti
  btnInscription: Registriĝi
  btnDeconnexion: Elsaluti

Attention à l'indentation, ensuite pour simplement l'afficher dans twig (exemple {{ 'header.btnConnexion'|trans }}) =>

<header class="row col-12 justify-content-around">
  <h2 class="jaaser">Jaaser<span class="logo-orange">.com</span></h2>
  <nav class="nav">
    {% include 'layout/navLanguage.twig' %}

    {% block boutonHeader %}
      <div>
        <a href="{{ path('login') }}" class="btn btn-secondary btn-md" id="connexionButton">{{ 'header.btnConnexion'|trans }}</a>
      </div>
    {% endblock %}

  </nav>   
</header>  

Voilà une fois fait, symfony gere tout seul si l'user choisit par exemple esperanto, les page ensuite resterons en eo grâce au route qui inclus {_locale} (voir plus au fichier routes.yaml

On peut aussi l'utiliser dans un controller =>

$this->addFlash('success',$this->get('translator')->trans('register.message.success'));

Et dans un FormType (avec bien sur les traduction dans les fichiers messages.XX.yaml =>

<?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\RadioType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;

class RegistrationType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('username', EmailType::class, array(
                'label' => 'register.label.email', 'required'=> true
                ))
            ->add('password', PasswordType::class, array(

                'label' => 'register.label.password',

                'required'=> true
                ))
            ->add('nickname', TextType::class, array(
                'label' => 'register.label.nickname', 'required'=> true
                ))
            ->add('nativeLang', TextType::class, array(
                'label' => 'register.label.nativeLanguage', 'required'=> true
                ))

            ->add('languagesLearn',TextType::class, array(
                'label' => 'register.label.languagesLearn'
                ))

            ->add('presentation', TextareaType::class, array(
                'label' => 'register.label.presentation', 'required'=> true
                ))

            ->add('country', TextType::class, array(
                'label' => 'register.label.country', 'required'=> true
                ))

            ->add('city', TextType::class, array(
                'label' => 'register.label.city', 'required'=> true
                ))

            ->add('gender', ChoiceType::class, array('label' => 'register.label.gender', 'choices' => array(
                'register.label.man'=> 'm', 'register.label.woman' => 'f'),
                'expanded' => true,
                'multiple' => false
                ))

            ->add('interest',TextType::class, array(
                'label' => 'register.label.interest'
                ))

            ->add('picture', FileType::class, array(
                'label' => 'register.label.picture', 'required'=> false
                ))
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => User::class,
        ));
    }
}

Bon j'arrête, ça va déjà aider les nouveaux sur SF4.

Bonjour !

Si ça t'intéresse j'ai fait un post à propos d'un bundle de traduction que je développe: https://www.grafikart.fr/forum/topics/28928
N'hésite pas à revenir vers moi si tu as des questions :)

Cordialement,
Baptiste - Weglot