#[AsTwigExtension]
Register a class as a Twig extension for Timber templates.
Signature
php
#[Attribute(Attribute::TARGET_CLASS)]
final readonly class AsTwigExtension
{
public function __construct(
public int $priority = 10,
) {}
}Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
priority | int | 10 | Loading priority (lower values load first) |
Requirements
The class must extend Twig\Extension\AbstractExtension.
Usage
Basic Usage
php
<?php
namespace App\Twig;
use Studiometa\Foehn\Attributes\AsTwigExtension;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
#[AsTwigExtension]
final class MyExtension extends AbstractExtension
{
public function getFunctions(): array
{
return [
new TwigFunction('hello', fn(string $name) => "Hello, {$name}!"),
];
}
}Then use it in your templates:
twig
{{ hello('World') }} {# Output: Hello, World! #}Adding Filters
php
<?php
namespace App\Twig;
use Studiometa\Foehn\Attributes\AsTwigExtension;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
#[AsTwigExtension]
final class TextExtension extends AbstractExtension
{
public function getFilters(): array
{
return [
new TwigFilter('excerpt', [$this, 'excerpt']),
new TwigFilter('reading_time', [$this, 'readingTime']),
];
}
public function excerpt(string $text, int $length = 150): string
{
if (mb_strlen($text) <= $length) {
return $text;
}
return mb_substr($text, 0, $length) . '…';
}
public function readingTime(string $text): int
{
$wordCount = str_word_count(strip_tags($text));
return max(1, (int) ceil($wordCount / 200));
}
}Usage:
twig
<p>{{ post.content | excerpt(200) }}</p>
<span>{{ post.content | reading_time }} min read</span>With Priority
Control the order extensions are loaded:
php
#[AsTwigExtension(priority: 5)]
final class CoreExtension extends AbstractExtension
{
// Loads before extensions with default priority (10)
}
#[AsTwigExtension(priority: 20)]
final class OverrideExtension extends AbstractExtension
{
// Loads after default priority extensions
}With Dependency Injection
Extensions are resolved through the container, so you can inject dependencies:
php
<?php
namespace App\Twig;
use App\Services\PriceFormatter;
use Studiometa\Foehn\Attributes\AsTwigExtension;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
#[AsTwigExtension]
final class PriceExtension extends AbstractExtension
{
public function __construct(
private readonly PriceFormatter $formatter,
) {}
public function getFilters(): array
{
return [
new TwigFilter('price', [$this->formatter, 'format']),
];
}
}Built-in Extensions
Føhn provides built-in extensions that you can use as examples:
InteractivityExtension— Helpers for WordPress Interactivity APIVideoEmbedExtension— Video URL transformation utilities