Skip to content

Form and template

FormMapper

The FormMapper maps Field definitions into Symfony forms, allowing Field editing.

It can implement two interfaces:

  • Ibexa\Contracts\ContentForms\FieldType\FieldValueFormMapperInterface to provide editing support
  • Ibexa\AdminUi\FieldType\FieldDefinitionFormMapperInterface to provide Field Type definition editing support, when you require non-standard settings

FieldValueFormMapperInterface

The FieldValueFormMapperInterface::mapFieldValueForm method accepts two arguments:

  • FormInterface — form for the current Field
  • FieldData — underlying data for current field form

You have to add your form type to the content editing form. The example shows how ezboolean injects the form:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use Ibexa\Contracts\ContentForms\Data\Content\FieldData;
use Ibexa\ContentForms\Form\Type\FieldType\CheckboxFieldType;
use Symfony\Component\Form\FormInterface;

public function mapFieldValueForm(FormInterface $fieldForm, FieldData $data)
{
    $fieldDefinition = $data->fieldDefinition;
    $formConfig = $fieldForm->getConfig();

    $fieldForm
        ->add(
            $formConfig->getFormFactory()->createBuilder()
                ->create(
                    'value',
                    CheckboxFieldType::class,
                    [
                        'required' => $fieldDefinition->isRequired,
                        'label' => $fieldDefinition->getName(
                            $formConfig->getOption('languageCode')
                        ),
                    ]
                )
                ->setAutoInitialize(false)
                ->getForm()
        );
}

Your type has to be called value. In the example above, CheckboxFieldType::class is used, but you can use standard Symfony form type instead.

It's good practice to encapsulate Fields with custom types as it allows easier templating. Type has to be compatible with your Field Type's Ibexa\Core\FieldType implementation. You can use a DataTransformer to achieve that or just assure correct property and form field names.

FieldDefinitionFormMapperInterface

Providing definition editing support is almost identical to creating content editing support. The only difference are field names:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
use Ibexa\AdminUi\Form\Data\FieldDefinitionData;
use Ibexa\ContentForms\Form\Type\FieldType\CountryFieldType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormInterface;

public function mapFieldDefinitionForm(FormInterface $fieldDefinitionForm, FieldDefinitionData $data)
{
    $fieldDefinitionForm
        ->add(
            'isMultiple',
            CheckboxType::class, [
                'required' => false,
                'property_path' => 'fieldSettings[isMultiple]',
                'label' => 'field_definition.ezcountry.is_multiple',
            ]
        )
        ->add(
            $fieldDefinitionForm->getConfig()->getFormFactory()->createBuilder()
                ->create(
                    'defaultValue',
                    CountryFieldType::class, [
                        'choices_as_values' => true,
                        'multiple' => true,
                        'expanded' => false,
                        'required' => false,
                        'label' => 'field_definition.ezcountry.default_value',
                    ]
                )
                // Deactivate auto-initialize as you're not on the root form.
                ->setAutoInitialize(false)->getForm()
        );
}

Use names corresponding to the keys used in Field Type's Ibexa\Core\FieldType\FieldType::$settingsSchema implementation. The special defaultValue key allows you to specify a field for setting the default value assigned during content editing.

Registering the service

The FormMapper must be registered as a service:

1
2
3
4
App\FieldType\Mapper\CustomFieldTypeMapper:
    tags:
        - { name: ibexa.admin_ui.field_type.form.mapper.definition, fieldType: custom }
        - { name: ibexa.admin_ui.field_type.form.mapper.value, fieldType: custom }

Tag the mapper according to the support you need to provide:

  • Add the ibexa.admin_ui.field_type.form.mapper.value tag when providing content editing support (FieldValueFormMapperInterface interface).
  • Add the ibexa.admin_ui.field_type.form.mapper.definition tag when providing Field Type definition editing support (FieldDefinitionFormMapperInterface interface). The fieldType key has to correspond to the name of your Field Type.

Content view templates

To render the Field in content view by using the ibexa_render_field() Twig helper, you need to define a template containing a block for the Field.

1
2
3
{% block customfieldtype_field %}

{% endblock %}

By convention, your block must be named <fieldTypeIdentifier>_field.

Tip

Template blocks for built-in Field Types are available in Core/Resources/views/content_fields.html.twig.

This template is also exposed as a part of Standard Design, so you can override it with the design engine. To do so, place the template themes/standard/content_fields.html.twig in your Resources/views (assuming ibexa_standard_design.override_kernel_templates is set to true).

Template variables

The block can receive the following variables:

Name Type Description
field Ibexa\Contracts\Core\Repository\Values\Content\Field The field to display
contentInfo Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo The ContentInfo of the content item the Field belongs to
versionInfo Ibexa\Contracts\Core\Repository\Values\Content\VersionInfo The VersionInfo of the content item the Field belongs to
fieldSettings array Settings of the Field (depends on the Field Type)
parameters hash Options passed to ibexa_render_field() under the 'parameters' key
attr hash The attributes to add the generate the HTML markup, passed to ibexa_render_field()under the'attr'` key.
Contains at least a class entry, containing -field

Reusing blocks

For easier Field Type template development you can take advantage of all defined blocks by using the block() function.

You can for example use simple_block_field, simple_inline_field or field_attributes blocks provided in content_fields.html.twig.

Caution

To be able to reuse built-in blocks, your template must inherit from @IbexaCore/content_fields.html.twig.

Registering a template

If you don't use the design engine or you want to have separate templates per Field Type and/or SiteAccess, you can register a template under the ibexa.system.<scope>.field_templates configuration key:

1
2
3
4
5
6
7
8
ibexa:
    system:
        <scope>:
            field_templates:
                -
                    template: 'fields/custom_field_template.html.twig'
                    # Priority is optional (default is 0). The higher it is, the higher your template gets in the list.
                    priority: 10

Back Office templates

Back Office view template

For templates for previewing the Field in the Back Office, using the design engine is recommended with ibexa_standard_design.override_kernel_templates set to true. With the design engine you can apply a template (e.g. Resources/views/themes/admin/content_fields.html.twig) without any extra configuration.

If you do not use the design engine, apply the following configuration:

1
2
3
4
5
ibexa:
    systems:
        admin_group:
            field_templates:
                - { template: 'adminui/field/custom_field_view.html.twig', priority: 10 }

Field edit template

To use a template for the Field edit form in the Back Office, you need to specify it in configuration under the twig.form_themes configuration key:

1
2
3
twig:
    form_themes:
        - 'adminui/field/custom_field_template.html.twig'

We encourage using custom form types for encapsulation as this makes templating easier by providing Twig block name. All built-in Field Types are implemented with this approach. In that case overriding form theme can be done with:

1
2
3
4
{% block custom_fieldtype_widget %}
    Hello world!
    {{ block('form_widget') }}
{% endblock %}

Tip

For more information on creating and overriding form type templates, see Symfony documentation.