Skip to content

Field Type form and template

FormMapper

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

It can implement two interfaces:

  • EzSystems\RepositoryForms\FieldType\FieldValueFormMapperInterface to provide editing support
  • EzSystems\RepositoryForms\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 EzSystems\RepositoryForms\Data\Content\FieldData;
use EzSystems\RepositoryForms\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 eZ\Publish\Core\FieldType\Value 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
33
use EzSystems\RepositoryForms\Data\FieldDefinitionData;
use EzSystems\RepositoryForms\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(
            // Creating from FormBuilder as we need to add a DataTransformer.
            $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 eZ\Publish\SPI\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
Acme\ExampleBundle\FieldType\Mapper\CustomFieldTypeMapper:
    tags:
        - { name: ez.fieldFormMapper.definition, fieldType: custom }
        - { name: ez.fieldFormMapper.value, fieldType: custom }

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

  • Add the ez.fieldFormMapper.value tag when providing content editing support (FieldValueFormMapperInterface interface).
  • Add the ez.fieldFormMapper.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 using the ez_render_field() Twig helper, you need to define a template containing a block for the Field.

1
2
3
{% block customfieldtype_field %}
{# Your code here #}
{% endblock %}

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

Tip

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

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

Template variables

The block can receive the following variables:

Name Type Description
field eZ\Publish\API\Repository\Values\Content\Field The field to display
contentInfo eZ\Publish\API\Repository\Values\Content\ContentInfo The ContentInfo of the Content item the Field belongs to
versionInfo eZ\Publish\API\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 ez_render_field() under the 'parameters' key
attr hash The attributes to add the generate the HTML markup, passed to ez_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 @EzPublishCore/content_fields.html.twig.

Registering your template

If you don't use eZ Design Engine or you want to have separate templates per Field Type and/or SiteAccess, you can register a template with the following configuration:

1
2
3
4
5
6
7
8
ezpublish:
    system:
        <siteaccess>:
            field_templates:
                -
                    template: 'AcmeExampleBundle: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 eZ Design is recommended with ez_platform_standard_design.override_kernel_templates set to true. With eZ Design you can apply a template (e.g. Resources/views/themes/admin/content_fields.html.twig) without any extra configuration.

If you do not use eZ Design, apply the following configuration:

1
2
3
4
5
ezpublish:
    systems:
        admin_group:
            field_templates:
                - { template: 'AcmeExampleBundle: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 key:

1
2
3
twig:
    form_themes:
        - 'AcmeExampleBundle: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 %}
Read the Docs