Skip to content

Builder Block

Its gives you total control to build with blocks.

Add the builder in forms

Classic form

src/Form/ExampleType.php
namespace App\Form\ExampleType;

use App\Core\Form\Type\BuilderType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class ExampleType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add(
            'myField',
            BuilderType::class
        );

        // ...
    }

    // ...
}

Page form

src/Entity/Page/YourPage.php
namespace App\Entity\Page;

use App\Core\Entity\Site\Page\Block;
use App\Core\Entity\Site\Page\BuilderBlock;
use App\Core\Form\Site\Page\BuilderBlockType;
use Symfony\Component\Form\FormBuilderInterface;

#[ORM\Entity]
class YourPage extends Page
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add(
            'myBlock',
            BuilderBlockType::class,
            [
                'label' => 'My block',
                'row_attr' => [
                ],
                'options' => [
                    // options given to the sub form
                ],
            ]
        );

        // ...
    }

    public function setMyBlock(Block $block)
    {
        return $this->setBlock($block);
    }

    public function getMyBlock(): Block
    {
        return $this->getBlock('myBlock', BuilderBlock::class);
    }

    // ...
}

Creating custom block

The easy way is to run: php bin/console make:builder-block.

First, create a service which extends App\Core\BuilderBlock\BuilderBlock and tagged builder_block.widget. Then, implement the method configure as below.

src/BuilderBlock/CustomBlock.php
namespace App\BuilderBlock;

use App\Core\BuilderBlock\BuilderBlock;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;

#[AutoconfigureTag('builder_block.widget')]
class CustomBlock extends BuilderBlock
{
    public function configure()
    {
        $this
            ->setName('custom')
            ->setCategory('Category')
            ->setLabel('My custom block')
            ->setOrder(1)
            ->setIsContainer(false) // set `true` if the block can contain blocks
            ->setIcon('<i class="fas fa-pencil-alt"></i>')
            ->setTemplate('builder_block/custom.html.twig')
            ->setClass('col-md-12')
            ->addSetting(name: 'value', label: 'Value', type: 'textarea', attributes: [], default: 'Default value')
        ;
    }
}

Create a template:

templates/builder_block/custom.html.twig
<div id="{{ id }}">
    {{ settings.value|default(null) }}

    {# If it's a container: #}
    {% for item in children %}
        {{ item|block_to_html(context) }}
    {% endfor %}
</div>

That's all folks!

Rendering

To render blocks, simply use {{ value|block_to_html }}.

If you need to build variables depending of the content, you can override the method buildVars:

src/BuilderBlock/CustomBlock.php
namespace App\BuilderBlock;

use App\Core\BuilderBlock\BuilderBlock;
use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag;

#[AutoconfigureTag('builder_block.widget')]
class CustomBlock extends BuilderBlock
{
    // ...

    public function buildVars(array $data, array $context)
    {
        $this->vars['bar'] = 'bar';
    }
}

And you can access variables in the template:

templates/builder_block/custom.html.twig
{{ vars.bar }}