Statamic Peak

Article

Traduire Laravel Jetstream et Inertia

Comment traduire un nouveau projet à base de Laravel Jetstream et InertiaJs avec vue-i18n / Matice ? Je vous explique les différentes possibilités !

Pour traduire les différents contenus de Laravel et de Jetstream, le package laravel-lang/lang fournit des fichiers clef en main à copier / coller. Il nous reste seulement à gérer la traduction des fichiers Vue.

Pour cela, nous avons 2 possibilités :

  • Baser notre traduction uniquement coté serveur. C'est le partie pris du package GENL/Matice.
  • Séparer les traductions front-end / back-end et utiliser le package vue-i18n

En fonction de votre équipe et de vos possibilités d'évolution, une solution ou l'autre est préférable. Matice s'utilise très simplement pour une équipe qui vient de Blade / Laravel parce qu'il reprend le fonctionnement des fonctions côté PHP. Le package est encore jeune et pour l'instant il ne gère pas encore le lazy loading de plusieurs langues : on choisit dans un fichier de config les langues à inclure. C'est seulement un problème si votre projet gère de nombreuses langues ou traductions

À l'inverse, vue-i18n est la solution la plus utilisée pour traduire des projets Vue mais ne propose pas d'intégration particulière pour Laravel.

Utiliser GENL/Matice

On ajoute le package composer :

composer require genl/matice

On ajoute la directive @translations dans notre fichier app.blade.php avant le chargement de nos fichiers JS.

Coté JS, un package est également disponible pour ajouter les fonctions de traductions inspirées de Laravel :

npm install matice --save-dev

Ensuite, les fonctions et leurs paramètres sont détaillés dans le README du projet et sont similaires à Laravel.

Utiliser Vue-i18n

Installation de Vue-i18n dans un projet Laravel Jetstream

Pour vue-i18n, la solution est uniquement côté front-end.

npm i --save-dev vue-i18n@next

Pour utiliser des fichiers JSON ou des traductions dans les fichiers Vue, il est nécessaire d'ajouter @intlify/vue-i18n-loader et de configurer webpack.

npm i --save-dev @intlify/vue-i18n-loader@next

Dans le fichier webpack.config.js :

module: {
        rules: [
            {
                test: /\\.vue$/,
                loader: 'vue-loader',
            },
            {
                test: /\\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
                type: 'javascript/auto',
                loader: '@intlify/vue-i18n-loader',
                include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled
                    path.resolve(__dirname, 'src/locales')
                ]
            },
            {
                resourceQuery: /blockType=i18n/,
                type: 'javascript/auto',
                loader: '@intlify/vue-i18n-loader'
            },
        ]
    }

Utilisation de Vue-i18n dans un projet Laravel Jetstream

Il ne nous reste plus qu'à ajouter vue-i18n à notre instance de Vue.

Pour cela, on modifie notre fichier app.js.

import { createI18n } from 'vue-i18n'

const i18n = createI18n({
    locale: 'fr',
    fallbackLocale: 'fr',
    messages: {
        fr
    }
});

// ajouter après .use(InertiaPlugin)
.use(i18n)

Il est alors possible de créer des blocs i18n directement dans un composant :

<i18n locale="fr">{
    "forgot_password": "Mot de passe oublié?",
    "login": "Se connecter",
    "remember_me": "Se souvenir de moi"
}</i18n>

Sinon, on peut mettre nos traductions dans un fichier js.

export default {
    "agree": "J'accepte les {tos} et la {privacyPolicy}",
    "email": "Email",
    "name" : "Raison sociale",
    "password": "Mot de passe",
}

Notre installation rend disponible une fonction this.$t() dans nos composants qui prend en paramètre la clef de traduction et renvoie le contenu en fonction de la langue définie.

Par exemple :

<jet-label for="password_confirmation" :value="$t('confirm_password')" />

Parfois, ce fonctionnement n'est pas suffisant. Je veux afficher le message

"J'accepte les Conditions d'Utilisation et la Politique de Confidentialité" et créer des liens vers 2 pages différentes.

Pour des cas complexes, vue-i18n permet de créer une balise i18n-t qui dans notre exemple va remplacer {tos} et {privacyPolicy} par les templates fournis. Coté traduction, on a juste à indiquer

"agree": "J'accepte les {tos} et la {privacyPolicy}".

<i18n-t keypath="agree">
    <template #tos>
        <a target="_blank" :href="route('terms.show')" class="underline text-sm text-gray-600 hover:text-gray-900">noparse_b262f3093d421b0598f49ae543c45a43</a>
    </template>
    <template #privacyPolicy>
        <a target="_blank" :href="route('policy.show')" class="underline text-sm text-gray-600 hover:text-gray-900">noparse_0b056d589fb911d197db8823ab246b2b</a>
    </template>
</i18n-t>