> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Surcharge et mise à jour des traductions d'un package

> En analysant le chargeur de traductions de Laravel 13, découvrez la surcharge partielle des traductions PHP, les clés partagées des traductions JSON et comment mettre à jour sans casser les traductions publiées.

## 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](/fr/localization) couvre les opérations de base dans une application, et [Développement de packages Laravel](/fr/advanced/package-development) les bases de l'enregistrement et de la publication. Cette page approfondit l'implémentation de `ServiceProvider`, `FileLoader` et `Translator` dans Laravel 13.

<Info>
  `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.
</Info>

## 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`.

```text theme={null}
courier/
├── src/
│   └── CourierServiceProvider.php
└── lang/
    ├── en/
    │   └── messages.php
    └── ja/
        └── messages.php
```

Préparez les valeurs par défaut en japonais dans `lang/ja/messages.php`.

```php theme={null}
<?php

return [
    'delivery' => [
        'queued' => ':nameさんへの配送を受け付けました。',
        'failed' => '配送できませんでした。',
    ],
];
```

Préparez également l'anglais comme langue de repli dans `lang/en/messages.php`.

```php theme={null}
<?php

return [
    'delivery' => [
        'queued' => 'Delivery to :name has been queued.',
        'failed' => 'Delivery failed.',
    ],
];
```

Enregistrez le chargement et, de manière facultative, la publication dans la méthode `boot()` du service provider.

```php theme={null}
<?php

namespace Acme\Courier;

use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        $this->loadTranslationsFrom(__DIR__.'/../lang', 'courier');

        $this->publishes([
            __DIR__.'/../lang' => $this->app->langPath('vendor/courier'),
        ], 'courier-translations');
    }
}
```

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.

```php theme={null}
echo __('courier::messages.delivery.queued', ['name' => '山田'], 'ja');
```

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')`.

```php theme={null}
<?php

return [
    'delivery' => [
        'queued' => ':name様への配送予約が完了しました。',
    ],
];
```

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()`.

```mermaid theme={null}
flowchart TD
    A["courier::messages.delivery.queued<br>locale: ja"] --> B["lang/ja/messages.php<br>du package"]
    B --> C["lang/vendor/courier/ja/messages.php<br>de l'application"]
    C --> D["Remplacement des clés indiquées<br>avec array_replace_recursive"]
    D --> E["Récupération de la chaîne traduite<br>et remplacement des placeholders"]
```

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é.

| Situation | Résultat |
| - | - |
| La clé existe côté application | Sa valeur remplace celle du package |
| Le fichier existe mais pas la clé | La valeur du package pour la même langue est conservée |
| La clé est introuvable dans la langue demandée | La traduction PHP de `fallback_locale` est normalement recherchée |
| La clé est absente aussi de la langue de repli | Par défaut, la clé demandée est renvoyée |

<Warning>
  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.
</Warning>

## 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.

```php theme={null}
public function boot(): void
{
    $this->loadJsonTranslationsFrom(__DIR__.'/../lang');
}
```

Exemple de `lang/ja.json` dans le package :

```json theme={null}
{
  "Courier delivery queued": "配送を受け付けました。"
}
```

```php theme={null}
echo __('Courier delivery queued', [], 'ja');
```

`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.

```json theme={null}
{
  "Courier delivery queued": "配送予約が完了しました。"
}
```

* 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.

<Warning>
  `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.
</Warning>

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.

```bash theme={null}
php artisan vendor:publish --provider="Acme\Courier\CourierServiceProvider" --tag=courier-translations
```

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.

<Tip>
  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.
</Tip>

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](/fr/advanced/package-assets), et l'évaluation de la compatibilité lors des montées de version dans [Gestion de la compatibilité de versions de package](/fr/advanced/package-versioning).

## 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](/fr/advanced/package-testing).

| Cas | Points à vérifier |
| - | - |
| Traductions PHP non publiées | Le japonais et l'anglais du package sont récupérés |
| Seule `queued` est surchargée en japonais | `queued` change et `failed` garde sa valeur par défaut |
| Ajout d'une clé lors d'une mise à jour du package | Les clés absentes du fichier de surcharge existant sont aussi récupérées |
| Clé absente dans la langue demandée | La traduction PHP est récupérée depuis la langue de repli configurée |
| Même clé définie dans le JSON | Dans la configuration standard, le JSON de l'application l'emporte |
| JSON placé uniquement dans `lang/vendor/courier` | Dans la configuration standard, il ne sert pas de surcharge JSON |
| Traduction contenant `:name` | Elle correspond au tableau de remplacement de l'appelant et aucune chaîne non remplacée ne subsiste |

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`.

* [Documentation officielle de Laravel : fichiers de langue des packages](https://github.com/laravel/docs/blob/13.x/packages.md#language-files)
* [Documentation officielle de Laravel : surcharge des traductions de packages](https://github.com/laravel/docs/blob/13.x/localization.md#overriding-package-language-files)
* [ServiceProvider : enregistrement des traductions](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Support/ServiceProvider.php)
* [TranslationServiceProvider : chemins de langue standard](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Translation/TranslationServiceProvider.php)
* [FileLoader : remplacement récursif PHP et ordre de chargement JSON](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Translation/FileLoader.php)
* [Translator : récupération prioritaire du JSON et tableaux déjà chargés](https://github.com/laravel/framework/blob/v13.35.0/src/Illuminate/Translation/Translator.php)
* [Tests officiels : chargeur de traductions](https://github.com/laravel/framework/blob/v13.35.0/tests/Translation/TranslationFileLoaderTest.php)


## Related topics

- [Développement de packages Laravel](/fr/advanced/package-development.md)
- [Sujets avancés](/fr/advanced/index.md)
- [Surcharger et mettre à jour les vues d'un package](/fr/advanced/package-views.md)
- [Assets publics d'un package et mises à jour](/fr/advanced/package-assets.md)
- [Publier et mettre à jour les migrations d'un package](/fr/advanced/package-migrations.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.