eZ Platform bundle which provides UI to manage custom attributes in Online Editor

1.2.4 2019-08-13 14:30 UTC

This package is auto-updated.

Last update: 2024-02-07 20:21:10 UTC


eZ Platform 2.x has evolved a lot - tons of great changes/improvements. But one vital feature is still missing: custom CSS classes and custom attributes. This could prevent a large number of eZ Publish 5.4 sites migrating to the latest eZ Platform version.

That's why we decided to help by submitting a few pull requests. Among them, are:

  1. EZP-29301: Added support for custom attributes on elements which extends eZ Platform schema and allows for the storage of custom attributes. It was merged in eZ Platform 2.5.1.
  2. Handled custom attributes when converting XmlText to RichText which allows running migrations from eZ Publish 5.4 to eZ Platform without custom attributes loss. It is going to be merged and released very soon.

So right now is possible to store custom attributes, and it will be possible to migrate them from eZ Publish 5.4 very soon. But there is no way to manage them in eZ Platform. eZ Systems plans to release this feature in upcoming 3.x.

In the meantime, ezplatform-custom-attributes solves this problem. It provides a way to set up custom classes and attributes. And it also brings the new UI to them in the Online Editor:


There is nothing special; you know the drill:

  1. Require contextualcode/ezplatform-custom-attributes via composer:
     composer require contextualcode/ezplatform-custom-attributes
  2. Activate the bundle in app/AppKernel.php:
     $bundles = [
        new ContextualCode\EzPlatformCustomAttributesBundle\EzPlatformCustomAttributesBundle(),
  3. Clear the caches:
     php bin/console cache:clear
  4. JavaScript translations are in use, so you need to dump them and run encore:
     php bin/console bazinga:js-translation:dump web/assets --merge-domains
     yarn encore dev

After the steps above, the installation is complete. You should now see the new "Elements Path" block in the Online Editor. You are able to click on any element in that block; if the clicked element has been defined to be able to have at least one custom class or attribute a new UI will be shown to edit them.

The next step is to configure custom classes and custom attributes.


Custom classes and attributes are set up per each HTML element in the yml configuration file. An example configuration looks like the following:

        p: [p-class-1, p-class-2, p-class-3]
        table: [table-class-1, table-class-2]
        a: [a-class-1, 'icon icon--upload']
                type: checkbox
                type: text
                default: 80
                type: select
                options: [javascript, php, java]
    embed_views: [embed, list, block, custom-1, custom-2]

Custom Classes

For custom_classes you just specify an HTML element and the array of its custom CSS classes. Admin will be able to select multiple options from the dropdown. You can define multiple classes separated by space as one selection option.

Custom Attributes

Similarly, for custom_attributes, it is required to define custom attribute settings per each HTML element. There are following options:

  • type possible values are: text, textarea, select, checkbox
  • default applicable only for text and textarea attributes
  • options is used only for select attributes, and it contains an array of possible options

Embed View Types

For embed_views you just need to specify an array of possible embed view types.


If you are migrating from eZ Publish 5.4 and your content has a lot of custom classes and attributes, it might be very time-consuming to configure all of them. To simplify this task its better to use the ezplatform:generate-custom-attributes-configuration command. This script will generate a configuration based on the content stored in the database. Example usage:

php bin/console ezplatform:generate-custom-attributes-configuration --config-file=src/AppBundle/Resources/config/custom_attributes.yml

Extracting Custom Classes from Rich Text fields

 2/2 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

Extracting Custom Attributes from Rich Text fields

 4/4 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

Extracting Embed Views from Rich Text fields

 3/3 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ! [NOTE] Found 2 elements with custom classes: table, p
 ! [NOTE] Found 3 elements with custom attributes: tr, pre, p
 ! [NOTE] Found 2 elements with embed views: line, embed

 [OK] Configurations are saved into "src/AppBundle/Resources/config/custom_attributes.yml"

After the custom classes/attributes and embed view types configuration is done you should see and be able to edit them in the Online Editor. At this point, you might want to make their labels more editor friendly. And it is done via translations.


We are using JavaScript translations (custom_attributes translations domain). So all the custom class and attribute labels are translated on the client side.

To set up custom labels start with creating a custom_attributes.<LANGUAGE-CODE>.yaml translation file in your bundle. A good example would be src/AppBundle/Resources/translations/custom_attributes.en.yaml.

Then you need to add the actual labels there. Supported types are:

Custom Classes

  1. Class label, its translation message key should follow options.<css-class-name>.label pattern. Examples:
     options.p-class-1.label: 'Paragraph Class 1'
     options.p-class-2.label: 'Paragraph Class 2'
     options.p-class-3.label: 'Paragraph Class 3'
     options.table-class-1.label: 'Table Class 1'
     options.table-class-2.label: 'Table Class 2'

Custom Attributes

  1. Attribute title, the pattern is attributes.<name>.label. Examples:
     attributes.hide.label: 'Hide'
     attributes.max-length.label: 'Maximal Length'
     attributes.language.label: 'Language'
  2. Options labels (only for select type attributes), its key pattern is options.<option>.label. Examples:
     options.javascript.label: 'JavaScript'
     options.php.label: 'PHP' 'Java'

Embed View Types

  1. View type label, the pattern is embed.view..<view-identifier>. Examples:
     embed.view.list: 'List'
     embed.view.block: 'Block'
     embed.view.custom-1: 'Custom 1'
     embed.view.custom-2: 'Custom 2'

Updating the Translations

Please note, every time after custom attributes translations are changed you need to dump them and run encore:

php bin/console bazinga:js-translation:dump web/assets --merge-domains
yarn encore dev

So now the remaining part would be to handle the custom classes and attributes on the front-end.


Custom Classes

There is nothing special about the rendering of custom classes on the front-end. They are set as a class attribute on the corresponding HTML elements.

Custom Attributes

Custom attributes are rendered as data attributes with an ezattribute- prefix by default. So if for some element max-length is set to 10, on the front-end it will be rendered as data-ezattribute-max-length="10" attribute. It works in most cases, but there are few ways to customize it.

XSL Stylesheets

One of the possible ways to implement advanced rendering for custom attributes is to use custom XSL stylesheets. This option is the best for performance, but it requires some extensive knowledge of XSL. Also, you need to be familiar with eZ Platform Rich Text schema. In this case, Rich Text content is modified at the stage when it is transformed from the format it is stored into the database to HTML5.

Example implementation:

  1. Define custom XSL Stylesheet:
     <?xml version="1.0" encoding="UTF-8"?>
       <xsl:output indent="yes" encoding="UTF-8"/>
       <xsl:template match="docbook:tr[docbook:ezattribute[docbook:ezvalue[@key='hide' and text()='true']]]"/>
  2. Notify eZ Platform about the custom XSL Stylesheet via ezpublish.system.default.fieldtypes.ezrichtext.output_custom_tags configuration parameter.

Rich Text Converter

Alternatively, you can use Rich Text Converters to implement advanced rendering for custom attributes. In this case, Rich Text content is manipulated in PHP, which makes easier to develop and debug it. Basically you define a new service with a ezpublish.ezrichtext.converter.output.xhtml5 tag, which implements EzSystems\EzPlatformRichText\eZ\RichText\Converter interface. And that's all!

Example implementation:

  1. Create a new Rich Text Converter
  2. Define it as a service with ezpublish.ezrichtext.converter.output.xhtml5 tag

Embed View Types

After custom embed view type is set, add its settings into ezsettings.default.content_view_defaults hash. And that's all.


You can grab a working example of eZ Platform with ezplatform-custom-attributes from Please check out AppBundle there. It has examples of all possible configurations and customizations in the scope of custom classes and attributes.


There are no reasons why you can't start using ezplatform-custom-attributes right now, and then use the official Custom Attributes feature due to be released in eZ Platform 3.

  • First of all, we want to highlight that ezplatform-custom-attributes does not modify the Rich Text schema. This means you don't need to make any changes to your data during your eZ Platform 3 upgrade. And you don't need to run any migration scripts.

  • Custom classes and attributes rendering is done by using built-in eZ Platform functionality. So if you implement it now, it should stay the same in eZ Platform 3.

  • The only thing that's going to be changed in eZ Platform 3 is the admin UI. An that point you can just disable this bundle and the new UI will be picked up.

  • The only part might need to be changed during eZ Platform 3 migrations is custom classes and attributes configurations. That's going to depend on the configuration format for custom classes and Attributes in eZ Platform 3.

So please have a try ezplatform-custom-attributes. We would love to hear your feedback. PRs and comments are very welcome!