Aller au contenu principal
Making DigitalMaking Digital
Note technique

Laravel : corriger ou remplacer les traductions d'un package

En bref

Pour corriger la traduction d'un package Laravel, créez lang/vendor/{namespace}/{langue}/{fichier}.php avec uniquement les lignes à changer : le reste continue d'être lu dans le package. Le namespace est celui que le package passe à loadTranslationsFrom(). Les traductions JSON d'un package se remplacent dans le lang/fr.json de l'application. Si un ancien dossier resources/lang existe, Laravel l'utilise et ignore lang/.

Un package affiche "Bienvenu" au lieu de "Bienvenue", ou garde un libellé qui ne colle pas à votre métier. Corriger le fichier dans vendor/ marche jusqu'au prochain composer update, qui l'écrase. Laravel prévoit un emplacement pour ces corrections : un fichier lang/vendor/{package}/{langue}/{fichier}.php dans votre application, qui ne contient que les lignes à remplacer. Les traductions JSON d'un package se corrigent, elles, dans le lang/fr.json de l'application.

Où placer le fichier qui remplace la traduction ?

La documentation de Laravel donne le chemin : lang/vendor/{package}/{locale}. Le {package} n'est pas le nom Composer du package, mais le nom (namespace) sous lequel il enregistre ses traductions dans son service provider, avec loadTranslationsFrom(). Ses lignes s'appellent ensuite avec la syntaxe package::fichier.cle.

Pour le vérifier, nous avons créé dans une application neuve un faux package courier avec un fichier lang/fr/messages.php, enregistré ainsi :

PHP
// app/Providers/AppServiceProvider.php
public function boot(): void
{
    $this->loadTranslationsFrom(base_path('packages/courier/lang'), 'courier');
    $this->loadJsonTranslationsFrom(base_path('packages/courier/lang'));
}

Le package traduit courier::messages.welcome par "Bienvenu sur Courier" et courier::messages.goodbye par "À bientôt". Pour corriger la version française, le fichier va dans lang/vendor/courier/fr/messages.php : le nom du package, puis la langue corrigée, puis le même nom de fichier.

Pour un vrai package, cherchez loadTranslationsFrom dans son service provider. Par exemple, les traductions du panneau de Filament sont enregistrées sous le nom filament-panels : leurs corrections vont dans lang/vendor/filament-panels/fr/.

Faut-il recopier tout le fichier du package ?

Non, et c'est préférable : ne mettez que les lignes à corriger.

PHP
// lang/vendor/courier/fr/messages.php
return [
    'welcome' => 'Bienvenue sur Courier',
];

Résultat avec la langue fr : __('courier::messages.welcome') renvoie "Bienvenue sur Courier", et __('courier::messages.goodbye') toujours "À bientôt", lu dans le fichier du package. La documentation le confirme : les lignes non redéfinies restent chargées depuis les fichiers d'origine. Les nouvelles lignes ajoutées par une mise à jour du package continueront donc d'arriver.

Et les traductions JSON d'un package ?

Certains packages livrent des fichiers JSON (fr.json), dont les clés sont les phrases elles-mêmes, enregistrés avec loadJsonTranslationsFrom(). Pas besoin de dossier vendor pour eux : ajoutez la clé dans le lang/fr.json de l'application.

JSON
{
    "Save": "Enregistrer"
}

Dans notre test, le package traduisait Save par "Sauver" ; avec ce lang/fr.json, __('Save') renvoie "Enregistrer" : le fichier de l'application passe après celui du package et le remplace.

Le dossier lang n'existe pas : que faire ?

Une application neuve n'a pas de dossier lang : les messages du framework (validation, mots de passe...) sont lus dans Laravel lui-même. Vous pouvez simplement créer lang/vendor/... ou lang/fr.json à la main. Pour modifier aussi les messages du framework, la documentation indique la commande :

Terminal
php artisan lang:publish

Elle a créé lang/en/auth.php, lang/en/pagination.php, lang/en/passwords.php et lang/en/validation.php : seulement l'anglais. Pour les messages en français, créez lang/fr/validation.php, là encore avec les seules clés voulues :

PHP
// lang/fr/validation.php
return [
    'required' => 'Le champ :attribute est obligatoire.',
];

Avec la langue fr, __('validation.required', ['attribute' => 'email']) renvoie alors "Le champ email est obligatoire.", et une clé absente comme validation.email retombe sur l'anglais, la langue de secours (APP_FALLBACK_LOCALE, en par défaut). Relancer lang:publish n'a pas touché à notre fichier français ; l'option --force écrase en revanche les fichiers déjà publiés.

Pourquoi mes fichiers dans lang/ sont-ils ignorés ?

Les anciennes versions rangeaient les traductions dans resources/lang. Laravel utilise encore ce dossier s'il existe, et ignore alors lang/. Dans notre test, la simple présence d'un resources/lang/vendor/courier/fr/messages.php a fait passer __('courier::messages.welcome') sur ce fichier, et __('Save') est revenu à "Sauver" : le lang/fr.json n'était plus lu. lang_path() indique le dossier réellement utilisé. Sur une application mise à jour depuis une ancienne version, gardez un seul des deux dossiers.

Une correction ne s'affiche pas ?

Vérifiez dans l'ordre : le dossier lu (lang_path()), le namespace exact du package, la langue active (App::currentLocale()) et le nom du fichier, identique à celui du package.

Nous appliquons cette méthode sur les applications sur mesure que nous développons et maintenons, pour que les mises à jour des packages restent sans surprise. Un back-office à traduire ou à corriger ? Parlons-en.

À retenir
  • Correction d'un package : lang/vendor/{namespace}/{langue}/{fichier}.php, avec seulement les lignes à changer.
  • Le namespace est celui passé à loadTranslationsFrom(), pas le nom Composer.
  • Traductions JSON d'un package : la clé dans le lang/fr.json de l'application.
  • Si resources/lang existe encore, lang/ est ignoré.

Testé avec Laravel 13.37.0 et PHP 8.3.6.

Questions fréquentes

Les corrections résistent-elles à un composer update ?

Oui : elles sont dans le dossier lang de l'application, que Composer ne touche pas. Les lignes que vous n'avez pas redéfinies continuent d'être lues dans le package, mises à jour comprises.

Faut-il publier les traductions du package avec vendor:publish ?

Ce n'est pas nécessaire. Si le package le propose, vendor:publish copie ses fichiers dans lang/vendor ; un fichier qui ne contient que les lignes à corriger suffit et reste plus simple à maintenir.

lang:publish installe-t-il les messages en français ?

Non. Dans notre test, la commande n'a publié que les fichiers anglais (auth, pagination, passwords, validation). Les fichiers français sont à créer dans lang/fr/.

Comment savoir quelle langue est active ?

App::currentLocale() renvoie la langue en cours. La langue par défaut est l'option locale de config/app.php, en général réglée par APP_LOCALE dans le .env.

Making Digital

Nous connectons les logiciels des PME, automatisons leurs tâches répétitives et créons des assistants IA, depuis 2010. Nos articles partent de nos projets réels.

Notre parcours
Une question sur ce sujet ?

Parlons-en 30 minutes.

Vous saurez si votre problème se règle, comment, et en combien de temps. Sans engagement.

Un échange de 30 minutes, en visio ou par téléphone

Gratuit, sans engagement. On parle de votre problème, pas de technique.