twig/string-extra
Twig extension integrating Symfony String: add filters u (UnicodeString methods), slug (AsciiSlugger), and singular/plural (Inflector) to manipulate text, generate slugs, and handle basic inflection directly in Twig templates.
Installation Add the package via Composer in your Laravel project:
composer require twig/string-extra
Register the Twig extension in your config/view.php (or a custom Twig config file):
'extensions' => [
// ...
Twig\Extra\String\StringExtension::class,
],
First Use Case
Use the filter or replace filters in a Twig template:
{{ ' Hello, World! ' | trim | title }}
Output: Hello, World!
Or in a Blade template (via @twig directive if using laravel-twig-bridge):
@twig
{{ 'hello@example.com' | email }}
@endtwig
Text Sanitization
Use strip_tags or nl2br for HTML-safe text processing:
{{ user_input | strip_tags | escape('html') }}
URL/Email Handling Validate and format URLs/emails:
{{ 'contact@example.com' | email | lower }}
{{ 'https://example.com' | url | absolute_url('https://app.example.com') }}
String Manipulation
Leverage slugify, truncate, or wordwrap:
{{ 'Laravel 10 Features' | slugify }}
{{ long_text | truncate(50, '...') }}
Integration with Laravel
$cleanedInput = Str::of($request->input('bio'))->replace(['*', '#'], '');
Blade::directive('twigFilter', function ($expression) {
return "<?php echo Twig\Extra\String\StringExtension::filter({$expression}); ?>";
});
Usage:
@twigFilter('user_input | trim')
Dynamic Filter Chaining Build reusable Twig filters in your templates:
{% macro cleanText(text) %}
{{ text | trim | strip_tags | escape('html') }}
{% endmacro %}
Blade vs. Twig Syntax
@twig directives or PHP-based alternatives:
Str::of($text)->trim()->toUpper();
Str::of() (Laravel) and Twig filters for the same operation (e.g., trim).Performance
| trim | lower | slugify) can be slow for large datasets. Pre-process in PHP when possible:
$cleaned = Str::of($text)->lower()->slug();
Locale Sensitivity
title, slugify) rely on locale settings. Explicitly set locales in Twig:
{% set app %}{{ 'app name' | title('en_US') }}{% endset %}
Security
escape vs. htmlspecialchars: Prefer Twig’s escape filter over raw htmlspecialchars for consistency:
{{ untrusted_input | escape('html') }} {# Safe #}
{{ untrusted_input | htmlspecialchars }} {# Less safe; may double-escape #}
strip_tags.Deprecation Notes
absolute_url may change behavior if Symfony’s Url component evolves.Custom Filters Extend the package by creating a custom Twig extension:
use Twig\TwigFilter;
use Twig\Extension\AbstractExtension;
class CustomStringExtension extends AbstractExtension
{
public function getFilters()
{
return [
new TwigFilter('custom_filter', [$this, 'customFilter']),
];
}
public function customFilter($text)
{
return Str::of($text)->replace(['foo', 'bar'], 'baz');
}
}
Register it in config/view.php.
Debugging
{{ dump(text | filter) }} to inspect intermediate results.@php @endphp for graceful fallbacks:
@php
try {
$result = Twig\Extra\String\StringExtension::filter($text, 'nonexistent_filter');
} catch (\Exception $e) {
$result = $text;
}
@endphp
{{ $result }}
Configuration
config/view.php:
'twig' => [
'options' => [
'charset' => 'UTF-8',
'auto_reload' => true,
],
],
if (!function_exists('twigFilter')) {
function twigFilter($text, $filter)
{
return Twig\Extra\String\StringExtension::filter($text, $filter);
}
}
Usage:
{{ twigFilter($text, 'slugify') }}
Testing
$twig = new \Twig\Environment($loader);
$twig->addExtension(new \Twig\Extra\String\StringExtension());
$result = $twig->render('template.twig', ['text' => $input]);
$this->assertEquals(expected, $result);
Performance Optimization
DB::table('posts')->update([
'slug' => Str::of($post->title)->slug(),
]);
{# Less efficient #}
{{ text | trim | lower | slugify }}
{# More efficient #}
{{ text | custom_slug }} {# Custom filter handling all steps #}
How can I help you explore Laravel packages today?