From 273e577b28c2c46a2049d224adf6691c594d6a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Wed, 29 Jul 2026 16:34:32 +0200 Subject: [PATCH 1/4] Label/Description for custom tags --- .../factbox/config/packages/custom_tags.yaml | 34 ++++---- .../config/packages/jms_translation.yaml | 8 ++ .../custom_tags/factbox/config/services.yaml | 20 +++++ .../ezrichtext/custom_tags/factbox.html.twig | 2 + .../factbox/translations/custom_tags.en.yaml | 3 + .../rich_text/extend_online_editor.md | 79 ++++++++++++++++--- 6 files changed, 123 insertions(+), 23 deletions(-) create mode 100644 code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml create mode 100644 code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml diff --git a/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml b/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml index 5498c9327ab..f489ee33868 100644 --- a/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml +++ b/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml @@ -1,25 +1,31 @@ -ibexa: - system: - admin_group: - fieldtypes: - ezrichtext: - custom_tags: [factbox] - toolbar: - custom_tags_group: - buttons: - factbox: - priority: 5 ibexa_fieldtype_richtext: custom_tags: factbox: template: '@ibexadesign/field_type/ezrichtext/custom_tags/factbox.html.twig' - icon: '/bundles/ibexaicons/img/all-icons.svg#information' + icon: '/bundles/ibexaicons/img/all-icons.svg#information' # Optional + is_inline: false # Optional + label: 'Factbox custom tag' # Optional + description: 'Highlight a piece of information in a box' # Optional attributes: name: type: string - required: true + required: true # Optional + label: 'My name attribute' # Optional style: type: choice - required: true + required: true # Optional default_value: light choices: [light, dark] + label: 'My style attribute' # Optional + +ibexa: + system: + admin_group: + fieldtypes: + ezrichtext: + custom_tags: [factbox] + toolbar: + custom_tags_group: + buttons: + factbox: + priority: 5 diff --git a/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml b/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml new file mode 100644 index 00000000000..dd80df7be97 --- /dev/null +++ b/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml @@ -0,0 +1,8 @@ +jms_translation: + configs: + app_translation_config: + dirs: ['%kernel.project_dir%/src'] + output_dir: '%kernel.project_dir%/translations' + extractors: + - 'app.translation_extractor.factbox' + - 'app.translation_extractor.factbox_choice' diff --git a/code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml b/code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml new file mode 100644 index 00000000000..8f0617624a7 --- /dev/null +++ b/code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml @@ -0,0 +1,20 @@ +services: + app.extractor.custom_tag: + class: Ibexa\FieldTypeRichText\Translation\Extractor\CustomTagExtractor + arguments: + $customTags: '%ibexa.field_type.richtext.custom_tags%' + $domain: '%ibexa.field_type.richtext.custom_tags.translation_domain%' + $allowlist: ['factbox'] + tags: + - name: jms_translation.extractor + alias: app.translation_extractor.factbox + + app.extractor.custom_tag_choice: + class: Ibexa\FieldTypeRichText\Translation\Extractor\ChoiceAttributeExtractor + arguments: + $customTags: '%ibexa.field_type.richtext.custom_tags%' + $domain: '%ibexa.field_type.richtext.custom_tags.translation_domain%' + $allowlist: ['factbox'] + tags: + - name: jms_translation.extractor + alias: app.translation_extractor.factbox_choice diff --git a/code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ezrichtext/custom_tags/factbox.html.twig b/code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ezrichtext/custom_tags/factbox.html.twig index 6ffaabc1d13..7a8170e35f2 100644 --- a/code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ezrichtext/custom_tags/factbox.html.twig +++ b/code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ezrichtext/custom_tags/factbox.html.twig @@ -1,3 +1,5 @@ +{{ encore_entry_link_tags('factbox') }} +

{{ params.name }}

diff --git a/code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml b/code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml index 8c503b5dcf7..91f9249cd1a 100644 --- a/code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml +++ b/code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml @@ -1,3 +1,6 @@ ezrichtext.custom_tags.factbox.label: 'Factbox' +ezrichtext.custom_tags.factbox.description: 'Highlight a piece of information in a box' ezrichtext.custom_tags.factbox.attributes.name.label: 'Name' ezrichtext.custom_tags.factbox.attributes.style.label: 'Style' +ezrichtext.custom_tags.factbox.attributes.style.choice.dark.label: 'Dark' +ezrichtext.custom_tags.factbox.attributes.style.choice.light.label: 'Light' diff --git a/docs/content_management/rich_text/extend_online_editor.md b/docs/content_management/rich_text/extend_online_editor.md index 75b8f04c868..4f822d24a90 100644 --- a/docs/content_management/rich_text/extend_online_editor.md +++ b/docs/content_management/rich_text/extend_online_editor.md @@ -41,23 +41,84 @@ Place the `factbox.html.twig` template in the [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ezrichtext/custom_tags/factbox.html.twig') =]] ``` -!!! tip +If an attribute isn't required, check if it's defined by adding a check +in the template, for example: - If an attribute isn't required, check if it's defined by adding a check - in the template, for example: +```html+twig +{% if params.your_attribute is defined %} + ... +{% endif %} +``` - ```html+twig - {% if params.your_attribute is defined %} - ... - {% endif %} - ``` +In this example, the `style` attribute is a `choice` attribute with `light` and `dark` as possible values. +The selected value is available as `params.style` in the template. +Use it to build an `ibexa-factbox--light` or `ibexa-factbox--dark` modifier class on the wrapping `div` element for styling. + +You can then define the corresponding CSS for each choice, for example by using [Webpack Encore and assets](assets.md). + +Create a `assets/scss/factbox.scss` file for styling the custom tag: + +``` css +.ibexa-factbox--light { + background-color: #f5f5f5; + color: #202020; +} -Add labels for the new tag by providing translations in `translations/custom_tags.en.yaml`: +.ibexa-factbox--dark { + background-color: #202020; + color: #f5f5f5; +} +``` + +### Provide translations for custom tags + +You can provide the label and description displayed for the custom tag and its attributes in the back office in one of two ways. + +#### Option 1: Manually add translations + +Add labels for the new tag by providing the translations manually in `translations/custom_tags.en.yaml`: ```yaml [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml') =]] ``` +This approach is quick, but doesn't work when your custom tag is defined in a bundle. +The configuration and the labels are defined in separate files, making it easier to miss updating them when the custom tag changes. + +#### Option 2: Extract translation source texts from configuration + +To provide the translations with the custom tag configuration, specify the `label` and `description` keys for the custom tag itself and a `add label` key to each attribute. + +```yaml hl_lines="7-8 13 19" +[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml') =]] +``` + +To make use of them, create a new service with `Ibexa\FieldTypeRichText\Translation\Extractor\CustomTagExtractor` as the class. + +If it has `choice` attributes, add an additional service with `Ibexa\FieldTypeRichText\Translation\Extractor\ChoiceAttributeExtractor` as the class. + +In both cases, add your custom tag's identifier to the `allowlist` argument: + +```yaml hl_lines="7 17" +[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml') =]] +``` + +Then, create your own translation extraction configuration, and specify the Symfony services created above as extractors: + +```yaml hl_lines="7-8" +[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml') =]] +``` + +Run the translation extraction: + +```bash +php bin/console translation:extract -c app_translation_config +``` + +This updates `translations/custom_tags.en.yaml` with the translations provided in the configuration itself, for any keys that don't already have a translation. + +### Use custom tag + Now you can use the tag. In the back office, create or edit a content item that has a RichText field type. In the Online Editor, click **Add**, and from the list of available tags select the FactBox tag icon. From 54678b901796df1a46c7744262b9fa6aaf60e48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Wed, 29 Jul 2026 18:47:29 +0200 Subject: [PATCH 2/4] Selfreview --- .../config/packages/jms_translation.yaml | 1 + .../custom_tags/factbox/webpack.config.js | 3 +++ .../rich_text/extend_online_editor.md | 26 +++++++++++++++---- 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js diff --git a/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml b/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml index dd80df7be97..879ff7b8a09 100644 --- a/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml +++ b/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml @@ -3,6 +3,7 @@ jms_translation: app_translation_config: dirs: ['%kernel.project_dir%/src'] output_dir: '%kernel.project_dir%/translations' + output_format: yaml extractors: - 'app.translation_extractor.factbox' - 'app.translation_extractor.factbox_choice' diff --git a/code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js b/code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js new file mode 100644 index 00000000000..2e3c25d081d --- /dev/null +++ b/code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js @@ -0,0 +1,3 @@ +Encore.addStyleEntry('factbox', [ + path.resolve(__dirname, './assets/scss/factbox.scss'), +]); diff --git a/docs/content_management/rich_text/extend_online_editor.md b/docs/content_management/rich_text/extend_online_editor.md index 4f822d24a90..aeac0b37695 100644 --- a/docs/content_management/rich_text/extend_online_editor.md +++ b/docs/content_management/rich_text/extend_online_editor.md @@ -26,6 +26,8 @@ Start preparing the tag by adding a configuration file: [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml') =]] ``` +The example enables the custom tag under the `admin_group` [SiteAccess group](siteaccess.md), which controls where editors can use it. +The custom tag renders in all SiteAccesses, including the front end. Custom tags can have as many attributes as needed. Supported attribute types are: `string`, `number`, `boolean`, `link`, and `choice`. @@ -34,8 +36,7 @@ Supported attribute types are: Provide your own SVG icon, or choose one from the [built-in icons included in `all-icons.svg`](icon_twig_functions.md#icons-reference). You must create your own file for the Twig template. -Place the `factbox.html.twig` template in the -`templates/themes//field_type/ezrichtext/custom_tags` directory: +Place the `factbox.html.twig` template in the `templates/themes//field_type/ezrichtext/custom_tags` directory: ```html+twig [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ezrichtext/custom_tags/factbox.html.twig') =]] @@ -70,6 +71,14 @@ Create a `assets/scss/factbox.scss` file for styling the custom tag: } ``` +Then, register the file in `webpack.config.js` as an asset entry called `factbox`: + +``` js +[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js') =]] +``` + +After you add the configuration, template, and asset files, clear the cache and run `yarn encore `. + ### Provide translations for custom tags You can provide the label and description displayed for the custom tag and its attributes in the back office in one of two ways. @@ -87,12 +96,17 @@ The configuration and the labels are defined in separate files, making it easier #### Option 2: Extract translation source texts from configuration -To provide the translations with the custom tag configuration, specify the `label` and `description` keys for the custom tag itself and a `add label` key to each attribute. +To provide the translations with the custom tag configuration, specify the `label` and `description` keys for the custom tag itself, and a `label` key for each attribute. ```yaml hl_lines="7-8 13 19" [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml') =]] ``` +If you omit `label` or `description`, the extraction uses the identifier of the custom tag or attribute as the source text. + +To provide translations for values of a `choice` attribute, `ChoiceAttributeExtractor` capitalizes the first letter of the value. +For example, `light` and `dark` options become `Light` and `Dark`. + To make use of them, create a new service with `Ibexa\FieldTypeRichText\Translation\Extractor\CustomTagExtractor` as the class. If it has `choice` attributes, add an additional service with `Ibexa\FieldTypeRichText\Translation\Extractor\ChoiceAttributeExtractor` as the class. @@ -105,7 +119,7 @@ In both cases, add your custom tag's identifier to the `allowlist` argument: Then, create your own translation extraction configuration, and specify the Symfony services created above as extractors: -```yaml hl_lines="7-8" +```yaml hl_lines="6 8-9" [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml') =]] ``` @@ -115,7 +129,9 @@ Run the translation extraction: php bin/console translation:extract -c app_translation_config ``` -This updates `translations/custom_tags.en.yaml` with the translations provided in the configuration itself, for any keys that don't already have a translation. +This updates `translations/custom_tags.en.yaml` with the source texts taken from the configuration. + +Run the extraction again whenever you change the labels, descriptions, or attributes of the custom tag. ### Use custom tag From a1e5da8f386237cc38c2308196eefb84951ea0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Thu, 30 Jul 2026 10:01:39 +0200 Subject: [PATCH 3/4] Formatting --- .../rich_text/extend_online_editor.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/content_management/rich_text/extend_online_editor.md b/docs/content_management/rich_text/extend_online_editor.md index aeac0b37695..b5397710d3a 100644 --- a/docs/content_management/rich_text/extend_online_editor.md +++ b/docs/content_management/rich_text/extend_online_editor.md @@ -28,9 +28,16 @@ Start preparing the tag by adding a configuration file: The example enables the custom tag under the `admin_group` [SiteAccess group](siteaccess.md), which controls where editors can use it. The custom tag renders in all SiteAccesses, including the front end. + Custom tags can have as many attributes as needed. Supported attribute types are: -`string`, `number`, `boolean`, `link`, and `choice`. + +- `string` +- `number` +- `boolean` +- `link` +- `choice` + `choice` requires that you provide a list of options in the `choices` key. Provide your own SVG icon, or choose one from the [built-in icons included in `all-icons.svg`](icon_twig_functions.md#icons-reference). @@ -42,8 +49,7 @@ Place the `factbox.html.twig` template in the `templates/themes//fie [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ezrichtext/custom_tags/factbox.html.twig') =]] ``` -If an attribute isn't required, check if it's defined by adding a check -in the template, for example: +If an attribute isn't required, check if it's defined by adding a check in the template, for example: ```html+twig {% if params.your_attribute is defined %} From 4c00de2eb20b1f5bcb53a482c554a2d850d40623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Noco=C5=84?= Date: Thu, 30 Jul 2026 10:02:55 +0200 Subject: [PATCH 4/4] Moved section --- .../rich_text/extend_online_editor.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/content_management/rich_text/extend_online_editor.md b/docs/content_management/rich_text/extend_online_editor.md index b5397710d3a..aae8d232ef2 100644 --- a/docs/content_management/rich_text/extend_online_editor.md +++ b/docs/content_management/rich_text/extend_online_editor.md @@ -108,11 +108,6 @@ To provide the translations with the custom tag configuration, specify the `labe [[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml') =]] ``` -If you omit `label` or `description`, the extraction uses the identifier of the custom tag or attribute as the source text. - -To provide translations for values of a `choice` attribute, `ChoiceAttributeExtractor` capitalizes the first letter of the value. -For example, `light` and `dark` options become `Light` and `Dark`. - To make use of them, create a new service with `Ibexa\FieldTypeRichText\Translation\Extractor\CustomTagExtractor` as the class. If it has `choice` attributes, add an additional service with `Ibexa\FieldTypeRichText\Translation\Extractor\ChoiceAttributeExtractor` as the class. @@ -137,6 +132,11 @@ php bin/console translation:extract -c app_translation_config This updates `translations/custom_tags.en.yaml` with the source texts taken from the configuration. +If you omit `label` or `description`, the extraction uses the identifier of the custom tag or attribute as the source text. + +To provide translations for values of a `choice` attribute, `ChoiceAttributeExtractor` capitalizes the first letter of the value. +For example, `light` and `dark` options become `Light` and `Dark`. + Run the extraction again whenever you change the labels, descriptions, or attributes of the custom tag. ### Use custom tag