twig/intl-extra
Twig Intl Extra adds internationalization helpers to Twig: look up country, currency, language, locale and timezone names, list country timezones, and format numbers, currencies, dates and times using ICU/Intl-style formatting.
Installation:
composer require twig/intl-extra
Add the extension to your Twig environment in Laravel:
// config/twig.php (or in your service provider)
$twig->addExtension(new \Twig\Extra\Intl\IntlExtension());
First Use Case: Format a date in a Twig template:
{{ '2024-05-20'|date('full', 'en_US') }}
Output: Monday, May 20, 2024
Where to Look First:
vendor/twig/twig/src/Extra/Intl/ for extension source (if customizing).Localization:
{{ 1234.56|number_format(2, 'en_US') }} {# 1,234.56 #}
{{ 1234.56|number_format(2, 'de_DE') }} {# 1.234,56 #}
{{ 5|pluralize('item', 'items') }} {# items #}
Date/Time Handling:
{{ '2024-05-18'|relative_date('en_US') }}
{{ now|date('medium', 'Europe/Paris') }}
Text Processing:
{% set sorted = ['résumé', 'apple', 'banana']|sort %}
{{ 'résumé'|transliterate }}
Integration with Laravel:
BladeOne or twigblade/twig-bridge to mix Twig filters in Blade:
// In a Blade view:
@twig('{{ date|date("full", "en_US") }}')
use Twig\Extra\Intl\IntlExtension;
$validator->extend('locale_date', function ($attribute, $value, $parameters, $validator) {
$intl = new IntlExtension();
return $intl->getDateFormatter($parameters[0], $parameters[1])->parse($value) !== false;
});
Dynamic Locale Switching:
// In a middleware/service
$twig->addGlobal('locale', session('locale', 'en_US'));
{{ 1234|number_format(2, locale) }}
ICU Extension Dependency:
intl extension (not enabled by default on some hosts).php -m | grep intl
php.ini or use a Docker image with intl pre-installed (e.g., php:8.2-cli-intl).Locale Fallbacks:
zh_Hant_TW) throw errors. Use fallbacks:
{{ '2024-05-20'|date('full', 'zh_Hant_TW', 'zh_Hans_CN') }}
$fallbackLocales = [
'zh_Hant_TW' => 'zh_Hans_CN',
'en_GB' => 'en_US',
];
Performance:
$formatter = $intlExtension->getDateFormatter('full', 'en_US');
// Reuse $formatter in multiple templates.
Twig Caching:
$twig->setCache(false); // Or use a per-locale cache key.
Blade Integration Quirks:
|raw if needed:
@twig('{{ "script"|raw }}')
| in Blade attributes (e.g., {{ date|date('full') }} may break). Use @twig blocks.Check ICU Data:
php -r "print_r(\IntlDateFormatter::getAvailableLocales());"
php -r "echo \IntlBreakIterator::getICUVersion();"
Fallback Logic:
{% set formatter = _intl.getDateFormatter('full', 'unknown_locale') %}
{% if formatter is null %}
Locale not supported! Falling back to 'en_US'.
{% endif %}
Custom Extensions:
IntlExtension class to add Laravel-specific filters:
class LaravelIntlExtension extends \Twig\Extra\Intl\IntlExtension {
public function getFunctions() {
return array_merge(parent::getFunctions(), [
new \Twig\TwigFunction('laravel_pluralize', [$this, 'laravelPluralize']),
]);
}
public function laravelPluralize($count, $singular, $plural) {
return parent::pluralize($count, $singular, $plural);
}
}
Custom Formatters:
$twig->addFunction(new \Twig\TwigFunction('api_date', function ($date) {
return (new \DateTime($date))->format('Y-m-d\TH:i:sP');
}));
Locale Provider:
$twig->addFunction(new \Twig\TwigFunction('get_locale', function () {
return app(\App\Services\LocaleService::class)->get();
}));
Testing:
IntlExtension in tests:
$intl = $this->createMock(\Twig\Extra\Intl\IntlExtension::class);
$intl->method('pluralize')->willReturn('items');
$twig->addExtension($intl);
How can I help you explore Laravel packages today?