Skip to content

Block bundle

Introduction

With the BlockBundle you can use blocks to create your content dynamic over the admin. Blocks can be nested and therefore they are a very powerfully feature to create grid layouts. Default blocks are one_column, two_column, text or text_picture. But you could add any block you want.

Installation

bash
$ composer require enhavo/block-bundle

Node Model

tbc

Rendering

To render the content in the frontend, you can use the twig function block_render. This function has three parameters. The first one is the block node object. The second one is optional and is used to render a different template set. For further information read the section Render sets below. The third parameter is optional as well and can be used to exclude block types from rendering.

If you use block_render with one parameter, it will render the default template for the item which is defined in your configuration in config/packages/enhavo_block.yaml.

twig
block_render(node)

{# render with specific set #}
block_render(node, 'my_render_set_name')

{# only render text fields #}
block_render(node, null, ['text'])

Render sets

If you want to render two different templates for the same item type in your application, then you can use render sets.

In the configuration in config/packages/enhavo_block.yml you can define render sets. In this example, we defined one called my_render_set_name. Now we can define a new template for each item. Items without a defined template will use the default template.

yaml
enhavo_grid:
    render:
        sets:
            my_render_set_name:
                picture: theme/block/different-path/picture.html.twig
                text: theme/block/different-path/text.html.twig

Use block

Adding to the model

To add a property of type node to your resource model, add a one-to-one association to your doctrine definition and update your entity. In this case, the property is called "content".

yaml
oneToOne:
    content:
        cascade: ['persist', 'refresh', 'remove']
        targetEntity: Enhavo\Bundle\BlockBundle\Model\NodeInterface
php
<?php

//...

class Foo {

//...

/**
 * @var NodeInterface
 */
protected $content;

public function getContent() {...}
public function setContent(...) {...}

//...

}

Adding to form

To properly edit a property of the type node in your form, use the form type BlockNodeType::class or enhavo_block_block_node.

php
$builder->add('content', BlockNodeType::class);

Limit node types for a FormType

If you don't add any options, all item types configured in config/packages/enhavo_block.yaml will be available in the form

items (array)

You can restrict the available types by setting the option items.

php
$builder->add('content', BlockNodeType::class, array(
    'items' => ['text','my_block_node_name']
));

item_groups (array)

You can restrict the available types also by setting the option item_groups. Beforehand you need to define these item_groups in each block node definition in config/packages/enhavo_block.yaml like so:

yaml
enhavo_block:
    blocks:
        my_block_node:
            groups: [ my_group, maybe_a_second_group ]
        my_second_block_node:
            groups: [ maybe_a_second_group ]

Afterwards you can use these groups in your FormType:

php
$builder->add('content', BlockNodeType::class, array(
    'item_groups' => ['my_group']
));

In this case, only "my_block_node" would be available, as "my_second_block_node" does not belong to that group.

Block Configruation

yaml
Block/MyBlock: # name of the entity including subdirectory for all gereated files/classes. the subdirectory is optional.
    namespace: App # add Block files to a certain Bundle [optional]
    groups: # groups to use in block-config/type [optional]
        - layout
        - content
    label: 'Logowall' # the label to use in block-config/type [optional]
    block_type: true # generate block type [optional]
    use: # add use statements to Block entity
        - Doctrine\Common\Collections\Collection
        - Doctrine\Common\Collections\ArrayCollection
    form:
        use: # add use statements to Block FormType
            - Symfony\Component\Form\Extension\Core\Type\TextType

    properties: # a list of properties to be added to block/orm/form-type
        overline:
            type: string # the php data-type
            orm_type: string # can be used to have another type in ORM
            nullable: true # configure the property nullable in Block entity and ORM [optional]
            form:
                class: TextType # form type to be used
                options:
                    label: "'Overline'"
        layout:
            template: ChoiceType # use/create templates for complex types that are used multiple times
            form:
                options:
                    choices:
                        'Linksbündig': "'left'" # for ChoiceType choices you need to escape the keys also!
                        'Rechtsbündig': "'right'" # double AND single quotes to add string values!
                    expanded: 'true' # single OR double quotes to add boolean values!
        text:
            template: TextareaType

        children:
            type: ListType
            type_options:
                entry_class: MyBlockItem # means that adder/remover is generated
            relation: # defines the doctrine relation
                target_entity: MyBlockItem::class # target entity for the relation (entry_class but including namespace)
                mapped_by: myBlock # orm relation and also creates setMyBlock($this/null) in adder/remover
            form: # settings for the BlockFormType
                options: # form type options
                    entry_type: MyBlockItemType::class # no quotes to place value directly
                    label: "'Children'"

    classes: # you can create multiple related or non related entities here. config rules as read above.
        Block/MyBlockItem:
            properties:
                myBlock:
                    type: MyBlock
                    nullable: true
                    relation:
                        type: ManyToOne
                        target_entity: MyBlock::class
                        inversed_by: children
                position:
                    template: PositionType
                title:
                    template: TextType
                picture:
                    template: MediaType
                    form:
                        options:
                            label: "'Bild'"
                content:
                    template: BlockNodeType # Blocks that also contain other Blocks
                    form:
                        options:
                            label: "'Logowall-Item-Content'"
                            item_groups: "['logowall']" # groups to be loaded into BlockNodeType
                files:
                    template: MediaTypeMultiple # multiple files