havit / twig-components
Twig components extension
Requires
- php: ^7.1
- twig/twig: ^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- symfony/var-dumper: ^3.2
- vimeo/psalm: ^3.11
README
This is a PHP package for automatically create Twig components as tags. This is highly inspired from Laravel Blade Components.
Installation
You can install the package via Composer:
composer require havit/twig-components
Configuration
This package work only with Silex and PHP 7.1
$app['twig.options'] = [ 'debug' => true, 'cache' => __DIR__.'/../storage/cache/twig', 'components' => [ 'path' => 'components', 'namespace' => 'App\View', ], ]; $app->register(new \App\Provider\TwigComponentsServiceProvider());
To enable the package just pass your Twig environment object to the function and specify your components folder relative to your Twig templates folder.
SILEX
Create Provider
use Pimple\{Container, ServiceProviderInterface}; class TwigComponentsServiceProvider implements ServiceProviderInterface { public function register(Container $app) { $app->extend('twig', function (\Twig_Environment $twig, $app) { $twig->addExtension(new \Havit\TwigComponents\Extension\ComponentExtension($twig)); $twig->setLexer(new \Havit\TwigComponents\Lexer\ComponentLexer($twig)); return $twig; }); } }
Usage
The components are just Twig templates in a folder of your choice (e.g. components
) and can be used anywhere in your Twig templates. The slot variable is any
content you will add between the opening and the close tag.
Named slots
{# /components/card.twig #} <div {{ attributes.class('bg-white shadow p-3 rounded') }}> <h2 {{ title.attributes.class('font-bold') }}> {{ title }} </h2> <div> {{ body }} </div> </div> {# /index.twig #} <x-card> <x-slot name="title" class="text-2xl">title</x-slot> <x-slot name="body">Body text</x-slot> </x-card>
Also with the standard syntax.
{# /index.twig #} {% x:card %} {% slot:title with {class: "text-2xl"} %} Title {% endslot %} {% slot:body %} Title {% endslot %} {% endx %}
Attributes
You can pass any attribute to the component in different ways. To interprate the content as Twig you need to prepend the attribute name with a :
but it works
also in other ways.
snake-case variables will be converted to kebabCase
Call
<x-button :class="'btn-' ~ 'success'" type="{{'this' ~ 'works' ~ 'too'}}" action="or this" this="{{'this' ~ 'does'}}{{ 'not work' }}" data-key="foo" > Submit </x-button>
Component
<a href="{{ action }}" {{ attributes.class('btn btn-sm me-3') }} data-type="{{ type }}" data-key="{{ dataKey }}"> {{ $slot }} </a>
Compiled
<a href="or this" class="btn btn-sm me-3 btn-success" data-type="thisworkstoo" data-key="foo"> Submit </a>
Component Class
<?php namespace App\View; use App\Application; class Test extends \Havit\TwigComponents\View\Component { public $title = ''; public function __construct(string $title = 'xyz') { $this->title = $title; } public function handle(Application $app) { // Do something $this->title = $app->trans($this->title); } public function template(): string { return 'components/test.twig'; } } ## Contributing Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate. ## License The MIT License (MIT). Please see [License File](LICENSE.md) for more information.