mj-zana / translation
Translation catalogs, locale negotiation and the request locale for Zana applications
v2.1.0
2026-10-25 20:38 UTC
Requires
- php: ^8.5
- mj-zana/core: ^2.1
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
Requires (Dev)
- mj-zana/validation: ^2.1
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5
Suggests
- ext-intl: To format ICU messages: plurals, numbers, select
- mj-zana/validation: To translate validation messages
Provides
None
Conflicts
None
Replaces
None
README
Translation catalogs, locale negotiation and the request locale for Zana applications.
composer require mj-zana/translation
Setup
Register TranslationServiceProvider and list the locales; the first is the
fallback:
// config/translation.php return ['locales' => ['en', 'fr']];
Catalogs are PHP files named after their locale. Each module's
Resources/translations/ folder is loaded in module order, then the
application's translations/ folder, which wins:
// translations/fr.php return [ 'nav' => ['home' => 'Accueil'], 'contact' => ['thanks' => 'Merci {name} !'], ];
$translator->translate('nav.home'); // current locale $translator->translate('contact.thanks', ['name' => 'Ada'], 'fr');
The request locale
Add LocaleMiddleware to http.middleware. It picks the locale from the
first path segment (/fr/...), then Accept-Language, then the fallback,
and sets:
LocaleContextfor the duration of the request;- the
_localerequest attribute; Content-Languageon the response, andVary: Accept-Languagewhen the browser's languages decided.
Rules
- Missing keys never throw. The fallback locale is tried, then the key is returned with its placeholders replaced.
- ICU messages (
{count, plural, one {# item} other {# items}}) are formatted whenext-intlis loaded. - Validation messages are translated when
mj-zana/validationis installed: use keys as custom messages,#[NotBlank(message: 'contact.error.name_required')], and translate the built-in English messages by their text. - Outside a request the locale is the fallback;
LocaleContext::run()changes it for a block of code, e.g. in a console command.
License
MIT