dzango/twig-truncate-extension
Twig extension that truncates text while preserving HTML tags. Adds a truncate filter with options for length, ending, exact word cutting, and HTML handling—works with rendered markdown or raw content. Easy to register in Twig or Symfony2.
Install via Composer:
composer require dzango/twig-truncate-extension
Register the Extension (Laravel 5.5+):
Add to config/app.php under providers:
Dzango\Twig\Extension\TruncateServiceProvider::class,
Publish the config (if needed):
php artisan vendor:publish --provider="Dzango\Twig\Extension\TruncateServiceProvider"
Laravel 5.4 or older: Manually register in app/Providers/AppServiceProvider:
public function register()
{
$this->app['twig']->addExtension(new \Dzango\Twig\Extension\Truncate());
}
First Use Case: Truncate a string in a Blade template:
{{ $longText|truncate }}
Output: First 100 characters (excluding HTML tags) with ... appended.
Basic Truncation:
{{ $article->content|truncate(50) }} {# 50 chars, default ending #}
{{ $comment|truncate(30, ' [read more]') }} {# Custom ending #}
HTML-Preserving Truncation:
{{ "<p>This <strong>is</strong> a <a href='#'>test</a>.</p>"|truncate(20, '', false, true) }}
Output: <p>This <strong>is</strong> a </p> (preserves <a> tag).
Markdown Integration:
{{ $markdownText|markdown|raw|truncate(80) }}
Note: Use raw to prevent double-encoding after markdown conversion.
Dynamic Lengths:
{{ $text|truncate($dynamicLength) }}
Pass a variable (e.g., from a config or user preference).
Exact Truncation:
{{ $text|truncate(100, '', true) }} {# Force exact length, even mid-word #}
Service Container Binding:
Bind the extension globally in AppServiceProvider:
$this->app->singleton(\Dzango\Twig\Extension\Truncate::class, function ($app) {
return new \Dzango\Twig\Extension\Truncate(config('truncate.defaults'));
});
Configure defaults in config/truncate.php:
return [
'length' => 120,
'ending' => '...',
'exact' => false,
'consider_html' => true,
];
Use in Blade:
{{ $text|truncate }} {# Uses config defaults #}
Eloquent Scopes:
Combine with Eloquent for database-level truncation (e.g., in a toSearchableArray accessor):
public function getSearchableContentAttribute()
{
return Str::of($this->content)->truncate(150)->toString();
}
API Responses: Truncate content in JSON responses:
return response()->json([
'title' => $post->title,
'teaser' => $post->content|truncate(100),
]);
Note: Use a custom Blade directive or Laravel’s Str::of() for non-Twig contexts.
Double Encoding:
htmlspecialchars) may break tags.raw:
{{ $encodedText|raw|truncate }}
Nested HTML:
<div><span>...</span></div>) may not truncate cleanly.length or use considerHtml=false for strict truncation.Markdown Parsing:
parsedown) may output malformed HTML.Str::of($text)->markdown()->toHtml() before truncating.Performance:
TEASER column).Laravel Mix/Blade Caching:
truncate.length).php artisan view:clear
{{ $text|truncate|e('htmlspecialchars') }} to debug hidden characters.$twig->addExtension(new class extends \Dzango\Twig\Extension\Truncate {
public function getTruncated($string, $length = 100, $ending = '...', $exact = false, $considerHtml = true) {
\Log::debug("Truncate called with: length=$length, exact=$exact");
return parent::getTruncated($string, $length, $ending, $exact, $considerHtml);
}
});
Custom Truncation Logic:
Extend the Truncate class to add features (e.g., word-based truncation):
class CustomTruncate extends \Dzango\Twig\Extension\Truncate {
public function getWordTruncated($string, $words = 10, $ending = '...') {
// Custom logic here
}
}
Twig Filter Aliases: Register an alias for readability:
$twig->addFunction(new \Twig\TwigFunction('teaser', [$this, 'getTruncated']));
Usage:
{{ $text|teaser(80) }}
Integration with Laravel Collectives:
Use with HTML::entityDecode() for encoded strings:
{{ $encodedText|raw|entityDecode|truncate }}
config/truncate.php:
'defaults' => [
'length' => 150,
'ending' => ' <a href="#">...read more</a>',
],
tags:
- { name: twig.extension, alias: truncate }
How can I help you explore Laravel packages today?