本文目录导读:

我来详细介绍如何在Symfony项目中创建自定义Twig扩展。
创建自定义Twig扩展类
首先创建一个继承 AbstractExtension 的类:
// src/Twig/AppExtension.php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;
class AppExtension extends AbstractExtension
{
// 注册过滤器
public function getFilters(): array
{
return [
new TwigFilter('price', [$this, 'formatPrice']),
new TwigFilter('truncate', [$this, 'truncateText']),
];
}
// 注册函数
public function getFunctions(): array
{
return [
new TwigFunction('greet', [$this, 'greetUser']),
new TwigFunction('random_color', [$this, 'getRandomColor']),
];
}
// 自定义过滤器方法
public function formatPrice($number, $currency = '¥', $decimals = 2)
{
$formatted = number_format($number, $decimals);
return $currency . ' ' . $formatted;
}
public function truncateText($text, $length = 100, $suffix = '...')
{
if (mb_strlen($text) <= $length) {
return $text;
}
return mb_substr($text, 0, $length) . $suffix;
}
// 自定义函数方法
public function greetUser($name)
{
$time = date('H');
$greeting = 'Hello';
if ($time < 12) {
$greeting = 'Good morning';
} elseif ($time < 18) {
$greeting = 'Good afternoon';
} else {
$greeting = 'Good evening';
}
return sprintf('%s, %s!', $greeting, ucfirst($name));
}
public function getRandomColor()
{
$colors = ['primary', 'secondary', 'success', 'danger', 'warning', 'info'];
return $colors[array_rand($colors)];
}
}
注册服务
如果使用自动装配(Symfony 5+),扩展会自动注册,否则手动配置:
# config/services.yaml
services:
App\Twig\AppExtension:
tags: ['twig.extension']
在模板中使用
{# 使用自定义函数 #}
{{ greet('John') }}
{# 输出: Good morning, John! #}
{# 使用随机颜色函数 #}
<div class="alert alert-{{ random_color() }}">
This is a random colored alert!
</div>
{# 使用自定义过滤器 #}
{{ 99.99|price }}
{# 输出: ¥ 99.99 #}
{{ 99.99|price('$', 0) }}
{# 输出: $ 100 #}
{{ 'This is a very long text...'|truncate(10) }}
{# 输出: This is a... #}
高级用法 - 带依赖注入
// src/Twig/AdvancedExtension.php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Routing\RouterInterface;
class AdvancedExtension extends AbstractExtension
{
private $entityManager;
private $security;
private $router;
public function __construct(
EntityManagerInterface $entityManager,
Security $security,
RouterInterface $router
) {
$this->entityManager = $entityManager;
$this->security = $security;
$this->router = $router;
}
public function getFunctions(): array
{
return [
new TwigFunction('get_user_count', [$this, 'getUserCount']),
new TwigFunction('is_admin', [$this, 'isAdmin']),
new TwigFunction('active_route', [$this, 'isActiveRoute']),
];
}
public function getUserCount(): int
{
return $this->entityManager
->getRepository(User::class)
->count([]);
}
public function isAdmin(): bool
{
return $this->security->isGranted('ROLE_ADMIN');
}
public function isActiveRoute(string $routeName): bool
{
$currentRoute = $this->router->getRouteCollection()
->get($routeName);
return $currentRoute !== null;
}
}
创建带全局变量的扩展
// src/Twig/GlobalExtension.php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;
class GlobalExtension extends AbstractExtension implements GlobalsInterface
{
private $appName;
private $appVersion;
public function __construct(string $appName, string $appVersion)
{
$this->appName = $appName;
$this->appVersion = $appVersion;
}
public function getGlobals(): array
{
return [
'app_name' => $this->appName,
'app_version' => $this->appVersion,
'current_year' => date('Y'),
];
}
}
在模板中使用全局变量
{# 直接使用全局变量 #}
<footer>
© {{ current_year }} {{ app_name }} v{{ app_version }}
</footer>
测试自定义扩展
// tests/Twig/AppExtensionTest.php
namespace App\Tests\Twig;
use App\Twig\AppExtension;
use PHPUnit\Framework\TestCase;
class AppExtensionTest extends TestCase
{
private $extension;
protected function setUp(): void
{
$this->extension = new AppExtension();
}
public function testFormatPrice()
{
$result = $this->extension->formatPrice(99.99);
$this->assertEquals('¥ 99.99', $result);
}
public function testTruncateText()
{
$text = 'This is a very long text that needs to be truncated';
$result = $this->extension->truncateText($text, 10);
$this->assertEquals('This is a...', $result);
}
public function testGreetUser()
{
$result = $this->extension->greetUser('john');
$this->assertStringContainsString('john', strtolower($result));
}
}
最佳实践建议
- 命名规范:使用有意义的名称,添加后缀如
Extension - 单一职责:每个扩展负责一组相关功能
- 缓存友好:避免在扩展中进行数据库查询(使用服务层)
- 类型提示:使用PHP类型声明
- 文档注释:为方法添加PHPDoc注释
这样你就可以在Symfony项目中轻松创建和使用自定义Twig扩展了!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播