Multiple CKEditor configurations for Sulu CMS - Provides different editor configurations within the same Sulu installation using YAML configuration without JavaScript rebuilds.
The Sulu Multi CKEditor Bundle addresses Sulu's limitation of having a single global CKEditor configuration by providing YAML-based editor configurations. This allows you to define multiple editor configurations that are dynamically applied without rebuilding JavaScript assets.
- 🔧 YAML Configuration: Define editor configs in YAML without rebuilding JS
- 🎨 Multiple Configurations: Unlimited editor configurations per project
- 🏷️ Tag-Based Control: Fine-grained HTML tag control (p, h1-h6, table, etc.)
- ⚡ No JS Rebuild: Change configurations without recompiling assets
- 🔮 Future-Proof: Designed for multiple editors (CKEditor, TipTap)
- 📝 Content Type Support: Use
configurable_text_editorin templates - 🎯 Toolbar Customization: Full toolbar configuration control
- 🔗 Sulu Integration: Follows Sulu's configuration patterns
- 🔗 Link Support: Internal and external link functionality
- 📝 Rich Features: Headings, tables, lists, formatting, and more
- PHP: ^8.1
- Sulu CMS: ^2.5 || ^3.0
- Symfony: ^6.4 || ^7.0
- Node.js: ^18 (for asset compilation)
composer require akawaka/sulu-multi-ckeditor-bundleAdd the bundle to your config/bundles.php:
<?php
return [
// ... other bundles
Akawaka\SuluMultiCKEditorBundle\MultiEditorBundle::class => ['all' => true],
];Create config/packages/akawaka_sulu_multi_text_editor.yaml:
akawaka_sulu_multi_text_editor:
configs:
# Default configuration
default:
editor: ckeditor
tags:
p: true
a: true
sulu_link: true
ul: true
ol: true
h2: true
h3: true
h4: true
table: true
strong: true
em: true
toolbar:
- 'heading'
- '|'
- 'bold'
- 'italic'
- 'externalLink'
- 'internalLink'
- '|'
- 'bulletedlist'
- 'numberedlist'
- '|'
- 'insertTable'
# Minimal configuration
minimal:
editor: ckeditor
tags:
p: true
a: true
strong: true
em: true
toolbar:
- 'bold'
- 'italic'
- 'externalLink'
- 'internalLink'
- 'numberedlist'
# Rich configuration
rich:
editor: ckeditor
tags:
p: true
a: true
sulu_link: true
ul: true
ol: true
h1: true
h2: true
h3: true
h4: true
h5: true
h6: false
table: true
code: true
blockquote: true
strong: true
em: true
u: true
s: true
sub: true
sup: true
br: true
hr: true
toolbar:
- 'heading'
- '|'
- 'fontSize'
- 'fontColor'
- '|'
- 'bold'
- 'italic'
- 'underline'
- 'strikethrough'
- 'subscript'
- 'superscript'
- '|'
- 'externalLink'
- 'internalLink'
- '|'
- 'bulletedlist'
- 'numberedlist'
- '|'
- 'insertTable'
- 'blockQuote'
- 'codeBlock'
- 'horizontalLine'Add the bundle's JS package to your assets/admin/package.json:
{
"dependencies": {
"sulu-multi-ckeditor-bundle": "file:../../vendor/akawaka/sulu-multi-ckeditor-bundle/assets/admin"
}
}Then import it in your assets/admin/app.js:
import 'sulu-multi-ckeditor-bundle';Install the dependency and rebuild the admin assets:
npm install
php bin/console sulu:admin:update-buildSee Sulu documentation for details on
sulu:admin:update-build.
php bin/console cache:clearThe tests/Application directory is only for bundle development and testing. End users should follow the installation steps above.
# Complete development installation
make install
# Start services
make start
# Access application
# Website: http://localhost:8080
# Admin: http://localhost:8080/admin (admin/admin)Use the configurable_text_editor type in your Sulu templates:
<!-- Minimal editor: bold, italic, links, lists -->
<property name="intro" type="configurable_text_editor">
<meta>
<title lang="en">Introduction</title>
</meta>
<params>
<param name="config" value="minimal"/>
</params>
</property>
<!-- Default editor: standard features -->
<property name="content" type="configurable_text_editor">
<meta>
<title lang="en">Content</title>
</meta>
<params>
<param name="config" value="default"/>
</params>
</property>
<!-- Rich editor: all features -->
<property name="description" type="configurable_text_editor">
<meta>
<title lang="en">Description</title>
</meta>
<params>
<param name="config" value="rich"/>
</params>
</property>
<!-- With stripped paragraph tags -->
<property name="summary" type="configurable_text_editor">
<meta>
<title lang="en">Summary</title>
</meta>
<params>
<param name="config" value="minimal"/>
<param name="strip_p_tags" value="true"/>
</params>
</property>Control which HTML tags are allowed in each configuration:
| Tag | Description | Default |
|---|---|---|
p |
Paragraph tags | ✅ |
a |
Links | ✅ |
sulu_link |
Sulu internal links | ✅ |
ul, ol |
Lists | ✅ |
h1 |
Heading 1 | ❌ |
h2-h6 |
Headings 2-6 | ✅ |
table |
Tables | ✅ |
code |
Code blocks | ✅ |
blockquote |
Block quotes | ✅ |
strong, em |
Bold, italic | ✅ |
u, s |
Underline, strikethrough | ❌ |
sub, sup |
Subscript, superscript | ❌ |
br |
Line breaks | ✅ |
hr |
Horizontal rules | ❌ |
Common CKEditor 5 toolbar items:
- Text Formatting:
heading,fontSize,fontColor,fontBackgroundColor - Basic Styles:
bold,italic,underline,strikethrough - Advanced Styles:
subscript,superscript,code - Links:
externalLink,internalLink(Sulu-specific) - Lists:
bulletedlist,numberedlist(note: lowercase) - Alignment:
outdent,indent,alignment - Content:
insertTable,blockQuote,codeBlock - Utilities:
horizontalLine,undo,redo
Important: Use externalLink and internalLink for Sulu integration, not the generic link.
# Complete installation
make install
# Start services
make start
# Access application
# Website: http://localhost:8080
# Admin: http://localhost:8080/admin (admin/admin)# Environment
make start # Start Docker services
make stop # Stop services
make restart # Restart services
make shell # Access PHP container
# Development
make build # Build frontend assets
make watch # Watch assets for changes
make logs # Show container logs
# Database
make db-reset # Reset database
make admin # Create admin user
# Quality Assurance
make validate # Validate composer.json
make phpstan # Run static analysis
make cs-fix # Fix code style
make ci # Run all QA tasks- YAML Config → Parsed by
Configuration.php - Bundle Extension → Processes and stores config
- Admin Class → Exposes config to JavaScript via
getConfig() - JS Initializer → Receives config via
addUpdateConfigHook - Editor Component → Uses config to configure CKEditor5
src/
├── Admin/
│ └── MultiEditorAdmin.php # Config exposure to JS
├── Content/Type/
│ └── MultiTextEditorType.php # Content type implementation
├── DependencyInjection/
│ ├── Configuration.php # YAML schema
│ └── MultiEditorExtension.php # Config processing
├── Resources/
│ ├── config/services.yaml # Service definitions
│ ├── js/index.js # JS config management
│ └── views/content-types/
│ └── multi-text-editor.html.twig # Twig template
└── MultiEditorBundle.php # Bundle class
assets/admin/ # npm package (sulu-multi-ckeditor-bundle)
├── index.js # Package entry point (auto-registers everything)
├── config.js # Editor config state management
├── package.json # Package metadata
├── adapters/CKEditor5Configurable.js # Template parameter extraction
├── components/CKEditor5Configurable.js # CKEditor5 component
└── fields/ConfigurableTextEditor.js # Field type registration
tests/Application/ # For bundle development only
└── assets/admin/ # Development/testing assets
Create new configurations in your YAML:
akawaka_sulu_multi_text_editor:
configs:
blog_post:
editor: ckeditor
tags:
p: true
h2: true
h3: true
strong: true
em: true
blockquote: true
code: true
toolbar:
- 'heading'
- '|'
- 'bold'
- 'italic'
- '|'
- 'blockQuote'
- 'code'Use in templates:
<property name="content" type="configurable_text_editor">
<params>
<param name="config" value="blog_post"/>
</params>
</property>The system is designed for multiple editors:
akawaka_sulu_multi_text_editor:
configs:
tiptap_config:
editor: tiptap # Future support
tags:
# Same tag structureRun the test script to verify installation:
./test_multi_editor.shThis verifies:
- ✅ Docker environment setup
- ✅ Bundle registration
- ✅ Content type availability
- ✅ Asset compilation
- ✅ Configuration system
# Clear cache and rebuild
make restart
docker-compose exec php php tests/Application/bin/console cache:clear
docker-compose exec php php -d memory_limit=-1 tests/Application/bin/console sulu:build devAll PHP commands must use unlimited memory:
# ✅ Correct
docker-compose exec php php -d memory_limit=-1 tests/Application/bin/console <command>
# ❌ Wrong - will cause memory exhaustion
docker-compose exec php php tests/Application/bin/console <command>Heading selection not working:
- Verify
headingis in toolbar configuration - Check that heading tags (h1-h6) are enabled in
tags
Links not working:
- Use
externalLinkandinternalLinkinstead oflink - Ensure
aand/orsulu_linktags are enabled
Lists not working:
- Use
bulletedlistandnumberedlist(lowercase) in toolbar - Enable
ulandoltags in configuration
- Check browser console for errors
- Verify config name matches YAML configuration
- Rebuild assets:
make build - Clear cache:
make restart
- Configuration Guide - Detailed configuration documentation
- Template Examples - Example template usage
- Configuration Examples - YAML configuration examples
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions, issues and feature requests are welcome!
Feel free to check the issues page.
