ttbooking/twig-component
Composer 安装命令:
composer require ttbooking/twig-component
包简介
Класс-компоненты и слоты для Twig в Laravel: тег {% component %}, {% slot %}, auto-discovery реестр с манифест-кэшем.
README 文档
README
Класс-компоненты и слоты для Twig в Laravel: тег {% component %}, функция component(),
слоты {% slot %} в стиле Vue 3 и auto-discovery реестр компонентов с манифест-кэшем.
Возможности
- Компоненты как классы. Виджеты (свой класс с логикой + DI через контейнер) и
презентационные компоненты на
spatie/laravel-data(только пропсы). - Тег и функция.
{% component 'name' with {...} %}…{% endcomponent %}и inlinecomponent('name', {...}). - Слоты в стиле Vue 3. Дефолтный слот (тело тега) + именованные
{% slot 'name' %}с фолбэком<slot>в шаблоне компонента. Тело слота исполняется в области видимости вызова. - Auto-discovery. Компоненты находятся по неймспейсу/пути; имя выводится из класса по
конвенции (
App\View\TwigComponents\UI\Box→ui:box). Манифест кэшируется для прода.
Требования
- PHP ≥ 8.2
- Laravel ^13
- Twig ^3 (через
rcrowe/twigbridge)
Установка
composer require ttbooking/twig-component
ServiceProvider подключается через package-discovery. Опубликуйте конфиг и включите
Twig-расширение в config/twigbridge.php:
php artisan vendor:publish --tag=twig-component-config
// config/twigbridge.php 'extensions' => [ 'enabled' => [ // … TTBooking\TwigComponent\ComponentExtension::class, ], ],
Конфигурация
config/twig-component.php — где искать компоненты и куда писать манифест:
return [ 'namespace' => 'App\\View\\TwigComponents\\', 'path' => app_path('View/TwigComponents'), 'manifest' => base_path('bootstrap/cache/twig-component.php'), ];
Быстрый старт
Виджет-компонент:
namespace App\View\TwigComponents\UI; use TTBooking\TwigComponent\TwigComponent; class Box implements TwigComponent { public function __construct( public string $title = '', public bool $collapsible = false, ) {} public function template(): string { return view('components/ui/box')->name(); } public function context(): array { return []; } }
Шаблон components/ui/box.html.twig (this — экземпляр компонента, slots — переданные слоты):
<div class="box"> <div class="box-header"> {% slot 'header' %}<h3>{{ this.title }}</h3>{% endslot %} </div> <div class="box-body">{% slot %}{% endslot %}</div> </div>
Использование на месте вызова:
{% component 'ui:box' with { title: 'Заказы' } %}
<p>Содержимое тела — дефолтный слот.</p>
{% slot 'header' %}<h3>Свой заголовок вместо фолбэка</h3>{% endslot %}
{% endcomponent %}
Презентационный компонент (только данные) наследует Spatie\LaravelData\Data; пропсы
доступны в шаблоне напрямую.
Манифест-кэш
Реестр компонентов кэшируется в плоский манифест (вшит в optimize):
php artisan twig-component:cache # собрать (входит в php artisan optimize) php artisan twig-component:clear # удалить (входит в optimize:clear)
Как устроены слоты
Компонент рендерится отдельным проходом Twig (view()->render()), поэтому тело слота
захватывается в строку и внедряется в шаблон компонента, а не связывается нативным
{% embed %}. Следствия: слоты рендерятся сразу (eager), scoped-слотов нет.
Правила (по образцу Vue 3):
{% slot 'name' %}верхнего уровня внутри{% component %}передаёт именованный слот (аналог<template #name>); весь остальной контент тела — дефолтный слотcontent.- Дефолтный слот можно передать и явно:
{% slot %}…{% endslot %}без имени (аналог<template #default>). Совмещать явный дефолтный слот и loose-контент нельзя — ошибка компиляции шаблона. - Тело из одних пробелов/переводов строк (форматирование вокруг
{% slot %}) дефолтным слотом не считается — фолбэк{% slot %}в шаблоне компонента сохраняется. {% slot %}глубже верхнего уровня (например, внутри{% if %}) — это не передача слота, а «дырка с фолбэком» в скоупе текущего шаблона. В шаблоне компонента это позволяет пробрасывать свои слоты во вложенный компонент; на обычной страницеslotsнет, и такой тег просто отрендерит свой фолбэк на месте.- Ключи
thisиslotsв контексте рендера зарезервированы:context()/пропсы с такими именами вызовут ошибку, а не молчаливое перекрытие.
Тесты
composer install vendor/bin/phpunit
Тесты изолированы на Orchestra Testbench и фикстурах — БД не требуется.
Лицензия
MIT.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-05