Type and Value classes¶
A Field Type must contain a Type class which contains the logic of the Field Type: validating data, transforming from various formats, describing the validators, etc.
A Type class must implement
Ibexa\Core\FieldType\FieldType ("Field Type interface").
All native Field Types also extend the
Ibexa\Core\FieldType\FieldType abstract class that implements this interface and provides implementation facilities through a set of abstract methods of its own.
You should also provide a Value object class for storing the custom Field value provided by the Field Type.
The Value is used to represent an instance of the Field Type within a Content item.
Each Field will present its data using an instance of the Type's Value class.
A Value class must implement the
It may also extend the
Ibexa\Core\FieldType\Value abstract class.
It is meant to be stateless and as lightweight as possible.
This class must contain as little logic as possible, because the logic is handled by the Type class.
The Type class of a Field Type provides an implementation of the
Field Definition handling¶
A custom Field Type is used in a Field definition of a custom Content Type. You can additionally provide settings for the Field Type and a validator configuration. Since the Public API cannot know anything about these, their handling is delegated to the Field Type itself through the following methods:
Returns a unique identifier for the custom Field Type which is used to assign the type to a Field definition.
By convention it should be prefixed by a unique vendor shortcut (e.g.
ibexa for Ibexa DXP).
This method retrieves via Public API a schema for the Field Type settings. A typical setting would be e.g. default value. The settings structure defined by this schema is stored in the
FieldDefinition. Since it is not possible to define a generic format for such a schema, the Field Type is free to return any serializable data structure from this method.
In addition to normal settings, the Field Type should provide schema settings for its validation process. The schema describes what kind of validation can be performed by the Field Type and which settings the user can specify to these validation methods. For example, the
ezstring type can validate minimum and maximum length of the string. It therefore provides a schema to indicate to the user that they might specify the corresponding restrictions, when creating a
FieldDefinition with this type. The schema does not underlie any regulations, except for that it must be serializable.
The type is asked to validate the settings (provided by the user) before the Public API stores those settings for the Field Type in a
FieldDefinition. As a result, the Field Type must return if the given settings comply to the schema defined by
validateFieldSettings(), this method verifies that the given validator configuration complies to the schema provided by
It is important to note that the schema definitions of the Field Type can be both of arbitrary and serializable format. It is highly recommended to use a simple hash structure.
Since it is not possible to enforce a schema format, the code using a specific Field Type must basically know all Field Types it deals with.
This will also apply to all user interfaces and the REST API, which therefore must provide extension points to register handling code for custom Field Type. These extensions are not defined yet.
Field Type name¶
The content item name is retrieved by the
Ibexa\Core\FieldType\FieldType::getName method which must be implemented.
To generate Content item name or URL alias the Field Type name must be a part of a name schema or a URL schema.
A Field Type needs to deal with the custom value format provided by it. In order for the public API to work properly, it delegates working with such custom Field values to the corresponding Field Type. The
Ibexa\Core\FieldType\FieldType interface therefore provides the following methods:
This method is responsible for accepting and converting user input for the Field. It checks the input structure by accepting, building, and returning a different structure holding the data.
For example: a user provides an HTTP link as a string,
acceptValue() converts the link to a URL Field Type value object. Unlike the
FieldType\Value constructor, it is possible to make this method aware of multiple input types (object or primitive).
acceptValue() asserts structural consistency of the value, but does not validate plausibility of the value.
The Field Type can specify that the user may define a default value for the
Field of the type through settings. If no default value is provided, the Field Type is asked for an "empty value" as the final fallback.
The value chain for filling a specific Field of the Field Type is as follows:
- Is a value provided by the filling user?
- If not, is a default value provided by the
- If not, take the empty value provided by the
In contrast to
acceptValue() this method validates the plausibility of the given value.
It is based on the Field Type settings and validator configuration and stored in the corresponding
When REST API is used, conversion needs to be done for Field Type values, settings and validator configurations. These are converted to and from a simple hash format that can be encoded in REST payload. As conversion needs to be done both when transmitting and receiving data through REST, Field Type implements the following pairs of methods:
||Converts Field Type Value into a plain hash format.|
||Converts the other way around.|
||Converts Field Type settings to a simple hash format.|
||Converts the other way around.|
||Converts Field Type validator configuration to a simple hash format.|
||Converts the other way around.|
The Field Type must be registered in
1 2 3 4 5
As described in the Symfony service container documentation, the
parent config key indicates that you want your service to inherit from the parent's dependencies, including constructor arguments and method calls. This helps avoiding repetition in your Field Type configuration and keeps consistency between all Field Types.
If you need to inject other services into your Type class, skip using the
parent config key.
Like most API components, Field Types use the Symfony service tag mechanism.
A service can be assigned one or several tags, with specific parameters.
When the service container is compiled into a PHP file,
tags are read by
CompilerPass implementations that add extra handling for tagged services.
Each service tagged as
ezplatform.field_type is added to a registry using the
alias key as its unique
Each Field Type must also inherit from the abstract
This ensures that the initialization steps shared by all Field Types are executed.
The configuration of built-in Field Types is located in
To make the search engine aware of the data stored in a Field Type, register it as indexable
Field Type settings¶
It is recommended to use a simple associative array format for the settings schema returned by
Ibexa\Contracts\Core\FieldType\FieldType::getSettingsSchema(), which follows these rules:
- The key of the associative array identifies a setting (e.g.
- Its value is an associative array describing the setting using:
typeto identify the setting type (e.g.
defaultcontaining the default setting value
An example schema could look like this:
1 2 3 4 5 6 7 8 9 10
The settings are mapped into Symfony forms via the FormMapper.
Some Field Types will require additional processing, for example a Field Type storing a binary file, or one having more complex settings or validator configuration. For this purpose specific implementations of an abstract class
Ibexa\Contracts\Rest\FieldTypeProcessor are used.
This class provides the following methods:
||Performs manipulations on a received value hash, so that it conforms to the format expected by the
||Performs manipulations on a outgoing value hash, previously generated by the
||Performs manipulations on a received settings hash, so that it conforms to the format expected by the
||Performs manipulations on a outgoing settings hash, previously generated by the
||Performs manipulations on a received validator configuration hash, so that it conforms to the format expected by the
||Performs manipulations on a outgoing validator configuration hash, previously generated by the
Base implementations of these methods simply return the given hash, so you can implement only the methods your Field Type requires. Some built-in Field Types already implement processors and you are encouraged to take a look at them.