# Builder Block

Its gives you total control to build with blocks.

![](/_static/img/editors/builder.png)

![](/_static/img/editors/builder2.png)

## Add the builder in forms

### Classic form

```php-inline title="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

```php-inline title="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);
    }

    // ...
}
```

Create a template:

```twig-inline title="templates/page/your_page/default.html.twig"
{% extends 'base.html.twig' %}

{% block page %}
    {{ _page.myBlock.value|block_to_html }}
{% endblock %}
```


## 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.

```php-inline title="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:

```twig-inline title="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!

![](/_static/img/editors/builder3.png)

## 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`:

```php-inline title="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:

```twig-inline title="templates/builder_block/custom.html.twig"
{{ vars.bar }}
```

