Installation:
composer require ibexa/fieldtype-richtext
Requires Ibexa DXP as a dependency.
Field Type Registration:
Register the ibexa_richtext field type in your ContentType definition (e.g., config/content_types/my_content_type.yaml):
fieldDefinitions:
my_richtext_field:
type: ibexa_richtext
config:
toolbar: ["bold", "italic", "link", "image"]
First Use Case:
ibexa_richtext field.$content = $contentService->loadContent($contentId);
$value = $content->getFieldValue('my_richtext_field');
$xmlData = $value->xml; // Raw XML content
Field Configuration:
config:
config:
toolbar: ["bold", "italic", "link", "image", "table"]
allowedTags: ["p", "h1", "h2", "a", "img", "table"]
customTags: ["alert", "highlight"]
// config/ibexa/fieldtypes/richtext/ezpublish.rng
<define name="my_custom_tag">
<element name="alert">
<attribute name="type">
<choice>info</choice>
<choice>warning</choice>
</attribute>
<text/>
</element>
</define>
Data Handling:
$fieldValue = new FieldValue();
$fieldValue->value = $xmlContent;
$content->setFieldValue('my_richtext_field', $fieldValue);
$contentService->saveContent($content);
use Ibexa\Contracts\FieldType\RichText\Value;
$value = $content->getFieldValue('my_richtext_field');
$html = (new Value())->html($value->value); // Renders HTML
Custom Plugins:
// resources/js/richtext-plugins.js
CKEDITOR.plugins.add('myPlugin', {
init: function(editor) {
editor.addCommand('myCommand', {
exec: function() {
editor.insertHtml('<div class="my-custom-class">Custom Content</div>');
}
});
editor.ui.addButton('MyButton', {
label: 'My Plugin',
command: 'myCommand'
});
}
});
config/ibexa/fieldtypes/richtext/config.yml:
plugins:
myPlugin:
path: /bundles/yourbundle/js/richtext-plugins.js
Validation:
$validator = new \Ibexa\RichText\Validator\CustomTagsValidator();
$isValid = $validator->validate($xmlContent);
SiteAccess-Specific Config:
SiteAccess:
# config/siteaccess/my_siteaccess/fieldtypes/richtext.yml
toolbar: ["bold", "italic"] # Overrides global config
XML Storage:
Value::html() to render it safely.Editor Initialization:
Encore for asset management:
// webpack.config.js
Encore
.enableSingleRuntimeChunk()
.addEntry('richtext', './resources/js/richtext.js')
.copyFiles({
from: './resources/public/ckeditor',
to: 'build/ckeditor/[name].[ext]'
});
php bin/console cache:clear
Custom Tag Quirks:
<alert>) must be defined in the RNG schema and registered in the editor config.<highlight></highlight>) may render incorrectly; ensure non-empty content or use minOccurs="0" in the schema.Link Handling:
SiteAccess selection. Use the Link plugin with:
config:
link:
siteAccesses: [site1, site2] # Restrict to specific SiteAccesses
Performance:
Debugging:
config.yml.libxml_use_internal_errors(true) to debug RNG schema errors:
$doc = new DOMDocument();
$doc->loadXML($xmlContent);
libxml_use_internal_errors(true);
$doc->schemaValidate('path/to/ezpublish.rng');
$errors = libxml_get_errors();
Reusable Configs:
extends in YAML:
fieldDefinitions:
body:
type: ibexa_richtext
config:
extends: "@ibexa/fieldtypes/richtext/config/base.yml"
toolbar: ["bold", "italic", "link"]
Custom CSS:
config:
stylesheets:
- { uri: "/bundles/yourbundle/css/richtext-styles.css" }
Fallback Config:
config:
fallback: "@ibexa/fieldtypes/richtext/config/default.yml"
Testing:
FieldTypeTest base class:
public function testCustomTagRendering() {
$value = new FieldValue();
$value->value = '<alert type="warning">Test</alert>';
$html = (new Value())->html($value->value);
$this->assertStringContainsString('class="alert warning"', $html);
}
Migration Notes:
How can I help you explore Laravel packages today?