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>