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
Register the extension in Laravel’s Twig service provider (e.g., AppServiceProvider):
use Twig\Extra\Intl\IntlExtension;
public function boot()
{
$this->app['twig']->addExtension(new IntlExtension());
}
First Use Case:
Format a currency in a Twig template (e.g., resources/views/emails/invoice.twig):
{{ 1000.50|format_currency('USD') }} {# Output: $1,000.50 #}
Or format a date for a user’s locale:
{{ now|format_datetime('medium', 'fr_FR') }} {# Output: 20 mai 2024 à 14:30:00 #}
Where to Look First:
twig/bridge if integrating Twig with Laravel’s service container.
composer require twig/bridge
Configure in config/twig.php:
'bridge' => [
'enabled' => true,
],
app()->getLocale()) aligns with Twig’s expectations. Override per-template if needed:
{% set locale = 'ja_JP' %}
{{ '2024-05-20'|format_date('full') }} {# 2024年5月20日 (月曜日) #}
{{ 1234.56|format_number(2, 'de_DE') }} {# 1.234,56 #}
{{ 1000|format_currency('EUR', 'de_DE') }} {# 1.000,00 € #}
{{ '2024-05-20T14:30:00'|format_datetime('long', 'en_US') }}
{# May 20, 2024 at 2:30:00 PM GMT+2 #}
// Controller
return view('dashboard', ['userLocale' => $user->locale]);
{% set locale = userLocale %}
{{ 1000|format_currency('GBP') }} {# £1,000 (if locale=en_GB) #}
{{ 1|pluralize('item', 'items') }} {# item #}
{{ 2|pluralize('item', 'items') }} {# items #}
{{ 1|select('one', 'two', 'few', 'many', 'other') }}
{# 'one' #}
{{ '2024-05-20T14:30:00+00:00'|timezone('America/New_York')|format_datetime('short') }}
{# 5/20/24, 10:30 AM #}
{{ 'US'|country_timezones }}
{# ['America/New_York', 'America/Chicago', ...] #}
default filter for unsupported locales:
{{ '2024-05-20'|format_date('full', 'xx_XX', 'en_US') }}
{# Falls back to 'en_US' if 'xx_XX' is invalid #}
Blade + Twig Hybrid:
@twig directives:
@twig
{{ '1000'|format_currency('USD') }}
@endtwig
twig/bridge and configuring Blade to parse Twig syntax.API Responses:
$response = view('api.response', ['data' => $data])->render();
return response()->json(['formatted' => $response]);
Mailables:
// In a Mailable
$this->with(['locale' => $user->locale]);
{% set locale = locale %}
{{ order.total|format_currency('EUR') }}
Testing:
$twig = new \Twig\Environment($loader);
$twig->addExtension(new IntlExtension());
$twig->addGlobal('locale', 'fr_FR');
$this->assertEquals('$1,000.00', $twig->render('{{ 1000|format_currency("USD") }}'));
config/twig.php:
'cache' => env('APP_DEBUG') ? false : storage_path('framework/views'),
NumberFormatter) and pass to Twig for consistency:
$formatter = new \NumberFormatter('de_DE', \NumberFormatter::CURRENCY);
$formatted = $formatter->format($amount);
return view('dashboard', ['amount' => $formatted]);
{% for item in items %}
{{ item.price|format_currency('EUR') }} {# Expensive in loops #}
{% endfor %}
// Controller
$formattedItems = array_map(fn($item) => formatCurrency($item->price, 'EUR'), $items);
return view('items', ['items' => $formattedItems]);
Locale Mismatch:
{% set locale = 'fr_FR' %}
{{ now|format_datetime('short') }} {# Uses 'fr_FR', not app()->getLocale() #}
$twig->addFunction(new \Twig\TwigFunction('app_locale', function() {
return app()->getLocale();
}));
Then use:
{% set locale = app_locale() %}
Intl Extension Missing:
intl extension is disabled.php.ini or runtime:
if (!extension_loaded('intl')) {
throw new \RuntimeException('Intl extension is required for Twig Intl filters.');
}
Caching Quirks:
\Artisan::call('twig:clear');
Blade Integration Complexity:
@twig directives in Blade can bloat templates and reduce readability.Unsupported Locales:
xx_XX) may not work.$locale = Locale::canonicalize($userLocale);
if (Locale::getRegion($locale) === null) {
$locale = app()->getFallbackLocale();
}
Timezone Ambiguity:
How can I help you explore Laravel packages today?