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..879ff7b8a09
--- /dev/null
+++ b/code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml
@@ -0,0 +1,9 @@
+jms_translation:
+ configs:
+ 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/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/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 75b8f04c868..aae8d232ef2 100644
--- a/docs/content_management/rich_text/extend_online_editor.md
+++ b/docs/content_management/rich_text/extend_online_editor.md
@@ -26,38 +26,121 @@ 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`.
+
+- `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).
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') =]]
```
-!!! tip
+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 %}
+```
- If an attribute isn't required, check if it's defined by adding a check
- in the template, for example:
+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.
- ```html+twig
- {% if params.your_attribute is defined %}
- ...
- {% endif %}
- ```
+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;
+}
+
+.ibexa-factbox--dark {
+ background-color: #202020;
+ color: #f5f5f5;
+}
+```
+
+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.
+
+#### Option 1: Manually add translations
-Add labels for the new tag by providing translations in `translations/custom_tags.en.yaml`:
+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 `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') =]]
+```
+
+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="6 8-9"
+[[= 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 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
+
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.