PHPackages                             ttbooking/twig-component - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. ttbooking/twig-component

ActiveLibrary[Templating &amp; Views](/categories/templating)

ttbooking/twig-component
========================

Класс-компоненты и слоты для Twig: тег {% component %}, {% slot %}, auto-discovery реестр с манифест-кэшем. Ядро без фреймворка + опциональная Laravel-интеграция.

0.3.2(3d ago)015↓100%MITPHP ^8.2

Since Jul 5Compare

[ Source](https://github.com/ttbooking/twig-component)[ Packagist](https://packagist.org/packages/ttbooking/twig-component)[ Docs](https://github.com/ttbooking/twig-component)[ RSS](/packages/ttbooking-twig-component/feed)WikiDiscussions Synced today

READMEChangelog (5)Dependencies (7)Versions (6)Used By (0)

TTBooking Twig Component
========================

[](#ttbooking-twig-component)

Класс-компоненты и слоты для Twig: тег `{% component %}`, функция `component()`, слоты `{% slot %}` в стиле Vue 3 и auto-discovery реестр компонентов с манифест-кэшем.

Ядро фреймворк-нейтрально — работает на голом Twig в любом PHP-приложении. Laravel-интеграция (DI через контейнер, рендер через `view()`, artisan-команды) — опциональный слой; интеграция с другим фреймворком — реализация двух небольших интерфейсов.

Возможности
-----------

[](#возможности)

- **Компоненты как классы.** Виджеты (свой класс с логикой + DI) и — в Laravel — презентационные компоненты на [`spatie/laravel-data`](https://github.com/spatie/laravel-data)(только пропсы).
- **Тег и функция.** `{% component 'name' with {...} %}…{% endcomponent %}` и inline `component('name', {...})`.
- **Слоты в стиле Vue 3.** Дефолтный слот (тело тега) + именованные `{% slot 'name' %}` с фолбэком `` в шаблоне компонента. Тело слота исполняется в области видимости вызова.
- **Auto-discovery.** Компоненты находятся по неймспейсу/пути; имя выводится из класса по конвенции (`App\View\TwigComponents\UI\Box` → `ui:box`). Манифест кэшируется для прода.
- **Точки интеграции.** `ComponentFactory` (как инстанцировать компонент) и `TemplateRenderer` (как отрендерить шаблон) — всё остальное фреймворка не касается.

Требования
----------

[](#требования)

- PHP ≥ 8.2
- Twig ≥ 3.21

Опционально (Laravel-интеграция): Laravel ^13, [`rcrowe/twigbridge`](https://github.com/rcrowe/TwigBridge) ^0.14, [`spatie/laravel-data`](https://github.com/spatie/laravel-data) ^4 для Data-компонентов.

Установка
---------

[](#установка)

```
composer require ttbooking/twig-component
```

### Без фреймворка (голый Twig)

[](#без-фреймворка-голый-twig)

```
use TTBooking\TwigComponent\{ComponentExtension, ComponentRegistry, NativeComponentFactory, TwigTemplateRenderer};
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

$registry = new ComponentRegistry(
    namespace: 'App\\View\\TwigComponents\\',
    componentsPath: __DIR__.'/src/View/TwigComponents',
    manifestPath: __DIR__.'/var/cache/twig-component.php',
);

$twig = new Environment(new FilesystemLoader(__DIR__.'/templates'));
$twig->addExtension(new ComponentExtension(
    $registry,
    new NativeComponentFactory($psr11Container), // контейнер опционален: без него — props-only конструкторы
    new TwigTemplateRenderer($twig),             // принимает и замыкание fn (): Environment
));
```

`NativeComponentFactory` инстанцирует виджеты через `new` с именованными аргументами; если передан любой PSR-11 контейнер, параметры конструктора без дефолта автовайрятся из него по типу. Прогреть манифест в деплое: `$registry->cache()`.

### Laravel

[](#laravel)

ServiceProvider подключается через package-discovery. Опубликуйте конфиг и включите Twig-расширение в `config/twigbridge.php`:

```
php artisan vendor:publish --tag=twig-component-config
```

```
// config/twigbridge.php
'extensions' => [
    'enabled' => [
        // …
        TTBooking\TwigComponent\ComponentExtension::class,
    ],
],
```

Провайдер сам биндит Laravel-реализации: виджеты собираются контейнером (`app($class, $props)`), шаблоны рендерятся через `view()`, доступны Data-компоненты.

Компонент можно отрендерить и напрямую из PHP — удобно в тестах компонентов приложения; Twig-окружение для этого не нужно:

```
$html = app(ComponentExtension::class)->renderComponent('ui:box', ['title' => 'Заказы']);
```

### Другой фреймворк

[](#другой-фреймворк)

Реализуйте `ComponentFactory` (инстанцирование компонента из props средствами вашего DI) и, при необходимости, `TemplateRenderer` (если рендер должен идти не напрямую через Twig) — и соберите `ComponentExtension` как в примере выше.

Конфигурация (Laravel)
----------------------

[](#конфигурация-laravel)

`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
    {
        // имя, понятное активному рендереру:
        // standalone — путь Twig-шаблона: return 'components/ui/box.html.twig';
        // Laravel — view-имя (view()->name() даёт IDE-навигацию):
        return view('components/ui/box')->name();
    }

    public function context(): array
    {
        return [];
    }
}
```

Шаблон `components/ui/box.html.twig` (`this` — экземпляр компонента, `slots` — переданные слоты):

```

        {% slot 'header' %}{{ this.title }}{% endslot %}

    {% slot %}{% endslot %}

```

Использование на месте вызова:

```
{% component 'ui:box' with { title: 'Заказы' } %}
    Содержимое тела — дефолтный слот.
    {% slot 'header' %}Свой заголовок вместо фолбэка{% endslot %}
{% endcomponent %}
```

Презентационный компонент (только данные, **Laravel-интеграция**) наследует `Spatie\LaravelData\Data`; пропсы доступны в шаблоне напрямую. Вне Laravel этот вид недоступен — ограничение самого laravel-data; используйте виджеты.

Манифест-кэш
------------

[](#манифест-кэш)

Реестр компонентов кэшируется в плоский манифест. В Laravel (вшит в `optimize`):

```
php artisan twig-component:cache   # собрать (входит в php artisan optimize)
php artisan twig-component:clear   # удалить (входит в optimize:clear)
```

Без фреймворка — `$registry->cache()` / `$registry->clearCache()` в скрипте деплоя.

Как устроены слоты
------------------

[](#как-устроены-слоты)

Компонент рендерится отдельным проходом Twig, поэтому тело слота **захватывается в строку**и внедряется в шаблон компонента, а не связывается нативным `{% embed %}`. Следствия: слоты рендерятся сразу (eager), scoped-слотов нет.

Правила (по образцу Vue 3):

- `{% slot 'name' %}` **верхнего уровня** внутри `{% component %}` передаёт именованный слот (аналог ``); весь остальной контент тела — дефолтный слот `content`.
- Дефолтный слот можно передать и явно: `{% slot %}…{% endslot %}` без имени (аналог ``). Совмещать явный дефолтный слот и loose-контент нельзя — ошибка компиляции шаблона.
- Тело из одних пробелов/переводов строк (форматирование вокруг `{% slot %}`) дефолтным слотом не считается — фолбэк `{% slot %}` в шаблоне компонента сохраняется.
- `{% slot %}` глубже верхнего уровня (например, внутри `{% if %}`) — это не передача слота, а «дырка с фолбэком» в скоупе текущего шаблона. В шаблоне компонента это позволяет пробрасывать свои слоты во вложенный компонент; на обычной странице `slots` нет, и такой тег просто отрендерит свой фолбэк на месте.
- Ключи `this` и `slots` в контексте рендера зарезервированы: `context()`/пропсы с такими именами вызовут ошибку, а не молчаливое перекрытие.

Тесты
-----

[](#тесты)

```
composer install
vendor/bin/phpunit                    # оба сьюта
vendor/bin/phpunit --testsuite Core   # ядро на голом Twig, без фреймворка
vendor/bin/phpunit --testsuite Laravel # интеграционный слой на Orchestra Testbench
```

БД не требуется.

Лицензия
--------

[](#лицензия)

[MIT](LICENSE).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance99

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

5

Last Release

3d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/fa409df9a204429e6f7bb8a0f2baf6516891c903be4d176b463bc79453a1b555?d=identicon)[EgorGruzdev](/maintainers/EgorGruzdev)

---

Tags

laraveltwiguicomponentstwig-extensiontwig-componentsslots

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ttbooking-twig-component/health.svg)

```
[![Health](https://phpackages.com/badges/ttbooking-twig-component/health.svg)](https://phpackages.com/packages/ttbooking-twig-component)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.8k543.8M20.2k](/packages/laravel-framework)[symfony/symfony

The Symfony PHP framework

31.4k87.2M2.2k](/packages/symfony-symfony)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6942.5M422](/packages/drupal-core-recommended)[symfony/ux-twig-component

Twig components for Symfony

22018.6M361](/packages/symfony-ux-twig-component)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M204](/packages/sulu-sulu)[symfony/ux-live-component

Live components for Symfony

1647.0M131](/packages/symfony-ux-live-component)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
