fyrkat / multilang
Requires
- php: >=8.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3
- phan/phan: ^5.4
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^5.13
README
Language picker that supports translation files in a directory and multi-language strings that are made programmatically (e.g. retrieved from a database or configuration file). It supports the Accept-Language header, including its more arcane uses, such as excluding languages by giving them a lower quality score than the catch-all wildcard.
Basic usage
Create translation files in a separate directory, see the directories in tests/fyrkat/multilang for an example.
<?php
$translator = new \fyrkat\multilang\TranslationContext(
userLocale: $_COOKIE['lang'],
localeDirectory: '../locale',
);
The localeDirectory
must contain files such as en-GB.json
.
Now when you want to translate a string:
<?php
$text = 'This text must be translated';
echo $translator->translate( $text );
In an HTML document, you should use this instead, so that the language is correct marked if translations are missing:
<?php
echo "<html lang=\"{$translator->primaryLocale}\">"; // e.g. nl or nl-NL
echo $translator->translateHtml('Hello'); // Hallo
echo "\n";
echo $translator->translateHtml('How are you'); // <span lang="en">How are you</span>
Multi-language fields in application data
If you have multi-language entities in your application, you can use the MultiLanguageString
within your application.
<?php
$blogpostTitle1 = new \fyrkat\multilang\MultiLanguageString([
'en-GB' => 'My first blogpost',
'nl-NL' => 'Mijn eerste blogpost',
]);
$blogpostTitle2 = new \fyrkat\multilang\MultiLanguageString([
'en-GB' => 'My second blogpost',
]);
These MultiLanguageStrings can be translated the same way as a normal string. They are not looked up in the locale directory, instead the most appropriate translation is chosen from the available translations.
<?php
echo "<html lang="{$translator->primaryLocale}">"; // e.g. nl or nl-NL
echo '<h1>';
echo $translator->translateHtml($blogpostTitle1); // Mijn eerste blogpost
echo '</h1>';
// more code goes here
echo '<h1>';
echo $translator->translateHtml($blogpostTitle2); // <span lang="en-GB">My second blogpost</span>
echo '</h1>';
Reporting the locale
If you are not creating an HTML document, but you still want to report the locale to the user, you can do that like this:
<?php
$text = 'This text must be translated';
$locale = null; // this is the language the text was translated into
$translated = $translator->translate( $text, $locale ); // this sets $translated and $locale
echo $locale; // nl-NL
echo ': ';
echo $translated; // Deze tekst moet vertaald worden
Listing supported languages
If you want to allow the user to choose a language, overriding the Accept-Language header
<ul>
<?php foreach($translator->getSupportedLocales() as $displayName => $locale): ?>
<?php $locale->is($translator->primaryLocale)): ?>
<li><strong><?= $displayName ?></strong></li>
<?php else: ?>
<li><a href="?lang=<?= $locale ?>"><?= $displayName ?></a></li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
Alternatively, if you want to present the user a list of languages displayed in the current language,
use $translator->getSupportedLocalesWithCurrentLocale()
instead.
This is recommended if the language choice won't change the display language,
for example setting the language tag for a blog post.