Skip to main content

Objectif de cette page

Il s’agit de distribuer les messages de votre package en plusieurs langues tout en permettant à l’application consommatrice de ne modifier que les libellés dont elle a besoin. Nous verrons aussi comment traiter les clés de traduction et les placeholders comme une API publique, afin de préserver les personnalisations lors des mises à jour du package. La page Localisation couvre les opérations de base dans une application, et Développement de packages Laravel les bases de l’enregistrement et de la publication. Cette page approfondit l’implémentation de ServiceProvider, FileLoader et Translator dans Laravel 13.
loadTranslationsFrom() enregistre un emplacement de chargement, tandis que publishes() enregistre une destination de copie de fichiers. Les utilisateurs n’ont pas besoin d’exécuter vendor:publish pour utiliser les traductions.

Distribuer des traductions PHP avec un namespace

Si vous souhaitez disposer de clés propres au package, utilisez le format tableau PHP et un namespace. Voici l’exemple d’un package nommé Acme\Courier.
Préparez les valeurs par défaut en japonais dans lang/ja/messages.php.
Préparez également l’anglais comme langue de repli dans lang/en/messages.php.
Enregistrez le chargement et, de manière facultative, la publication dans la méthode boot() du service provider.
Côté utilisation, on indique le namespace, le nom du fichier et la clé du tableau. Le code de langue suit la configuration de Laravel et vaut ja. Il est distinct de jp, utilisé dans les URL de ce site de documentation.
Le namespace courier correspond au deuxième argument de loadTranslationsFrom(). Il n’est pas déterminé automatiquement à partir du nom du package Composer.

Les traductions PHP ne remplacent pas le fichier entier

Dans l’application consommatrice, avec le répertoire de langues standard, il suffit d’écrire uniquement les clés à modifier dans lang/vendor/courier/ja/messages.php. Si vous avez changé le répertoire de langues, utilisez l’emplacement situé sous $this->app->langPath('vendor/courier').
Dans cet exemple, seule queued change ; failed utilise la traduction japonaise du package.

Ordre de chargement de FileLoader

ServiceProvider::loadTranslationsFrom() enregistre le namespace une fois le Translator résolu. La lecture effective des fichiers a lieu au moment où une traduction est demandée. FileLoader::loadNamespaced() charge les fichiers de langue du package enregistré et transmet ce tableau à loadNamespaceOverrides(). Celle-ci lit vendor/{namespace}/{locale}/{group}.php dans chacun des chemins de langue du chargeur et effectue le remplacement avec array_replace_recursive(). Le TranslationServiceProvider standard transmet au chargeur le chemin de langues du framework puis celui de l’application, dans cet ordre. Même si une extension enregistre des chemins supplémentaires, le tableau de surcharge chargé en dernier l’emporte pour une même clé.
Si le namespace n’est pas enregistré, FileLoader::loadNamespaced() renvoie un tableau vide. Placer simplement des fichiers dans lang/vendor/courier ne compense pas l’oubli d’enregistrement dans le service provider. Par ailleurs, si un autre package enregistre le même namespace, la destination enregistrée est remplacée : choisissez donc un nom qui n’entre pas en collision.

Les traductions JSON n’ont pas de namespace propre au package

Pour les traductions JSON, qui utilisent des phrases comme clés, enregistrez le répertoire comme suit. C’est une option distincte des traductions PHP présentées plus haut.
Exemple de lang/ja.json dans le package :
loadJsonTranslationsFrom() n’accepte pas d’argument de namespace. Les traductions JSON enregistrées partagent le même espace de clés que les autres packages et que l’application.

La surcharge JSON se fait dans le ja.json de l’application

FileLoader::loadJsonPaths() lit d’abord les chemins JSON enregistrés, puis les chemins de langue habituels, et les fusionne avec array_merge(). Dans la configuration standard, une même clé de chaîne dans le lang/ja.json de l’application remplace la valeur du package.
  • Si plusieurs packages utilisent la même clé de chaîne, la valeur du JSON chargé en dernier l’emporte. Évitez une conception qui dépend de l’ordre des providers.
  • lang/vendor/courier/ja.json n’est pas une destination de surcharge pour le chargeur JSON standard. Même si vous réutilisez tel quel pour le JSON la configuration de publication prévue pour le PHP, cet emplacement n’est pas lu automatiquement.
  • Publier le JSON du package vers le lang/ja.json de l’application avec publishes() ne fusionne pas le contenu des fichiers. Pour ne pas casser les traductions existantes, indiquez aux utilisateurs une procédure consistant à n’ajouter que les clés nécessaires.
Translator::get() vérifie d’abord le JSON de la langue demandée, puis, à défaut, recherche la clé au format PHP. Il ne parcourt pas successivement le JSON de la langue de repli comme il le fait pour les traductions PHP. Si vous utilisez des phrases en anglais comme clés JSON, distinguez ce cas du comportement standard qui affiche la clé d’origine en l’absence de traduction.
Le namespace des traductions PHP isole les clés PHP des autres packages. Cependant, comme Translator::get() examine d’abord les clés JSON en correspondance exacte, définir dans le JSON une clé telle que courier::messages.delivery.queued la fait primer sur le côté PHP. En règle générale, adoptez une politique qui évite de mélanger clés-phrases et clés au format PHP.

Mettre à jour sans casser les traductions publiées

Aux utilisateurs qui souhaitent publier toutes les traductions PHP en une fois, vous pouvez indiquer une commande ciblée.
Cependant, si vous copiez toutes les valeurs par défaut, cette copie devient elle aussi une valeur de surcharge. Même si vous corrigez une coquille dans le package, la nouvelle valeur n’apparaîtra pas tant que la même clé subsiste dans le fichier publié. En revanche, les nouvelles clés absentes de la copie sont complétées depuis le package.
Pour ne modifier que quelques libellés, il est plus facile d’intégrer les mises à jour en ne plaçant que les clés nécessaires dans le fichier de surcharge, plutôt que de publier tous les fichiers. Cette pratique tire parti de la surcharge partielle des traductions PHP.
Pour une maintenance à long terme, concevez les mises à jour dans l’ordre suivant.
  1. Conserver les clés et le namespace — Supprimer ou déplacer une clé affecte les appels __() des utilisateurs et leurs destinations de surcharge. Envisagez une période de transition où vous ajoutez la nouvelle clé tout en conservant l’ancienne.
  2. Conserver les placeholders — Remplacer :name par :recipient impose aussi de modifier le tableau de remplacement côté appelant. Ne considérez pas cela comme une simple modification des fichiers de traduction.
  3. Comparer les fichiers publiés — Comparez les surcharges de l’utilisateur avec les nouvelles valeurs par défaut. Supprimer les clés de surcharge devenues inutiles permet de revenir aux valeurs du package.
  4. Éviter la republication inconditionnelle — Une republication avec --force écrase les personnalisations de l’utilisateur. Avec une conception qui copie le JSON dans le fichier de l’application, d’autres traductions risquent aussi d’être perdues.
  5. Vérifier avec les processus persistants — Translator::load() conserve dans l’instance les tableaux par namespace, groupe et langue. Dans un processus où subsiste un Translator déjà chargé, une simple modification de fichier ne déclenche pas forcément de rechargement. Redémarrez les workers ou équivalents selon votre exploitation.
La sélection des cibles de publication et les options d’écrasement sont complétées dans Assets publics d’un package et mises à jour, et l’évaluation de la compatibilité lors des montées de version dans Gestion de la compatibilité de versions de package.

Points à vérifier dans l’application consommatrice

Dans une application de test où le service provider est enregistré, vérifiez les combinaisons suivantes. Pour la mise en place de l’environnement de test au sein du package, consultez Tester des packages Laravel avec Orchestra Testbench. Dans les tests qui créent un fichier de surcharge après le chargement, veillez à ce que les résultats déjà chargés par le Translator n’interfèrent pas. Préparez les fichiers avant la récupération, ou utilisez une nouvelle instance d’application pour chaque cas.

Sources primaires consultées

La documentation officielle a été vérifiée sur la branche par défaut la plus récente 13.x, et l’implémentation interne sur la dernière release disponible au moment de la consultation, v13.35.0.
Dernière modification le 8 octobre 2026