Skip to content

use custom ckeditor5 build

sluc23 requested to merge sluc23/ckeditor5:dev-CustomBuild into master

Current release hardcodes two variants of ckeditor5 toolbar, and it's not possible to customize it with our own. CKEditor5 has a harder way to customize the toolbar, based on builds, node.js dependencies, etc.. plus this extension is not ready to use a different build than the 2 that are included.

I'm adding the simplest approach i've came up with the minimal changes, to be able to use my custom ckeditor5 build with ELFinder (basically we wanted to add more font-related buttons and View Source plugin).
The ckeditor5 custom toolbar is based in a new JS variable called CRM.config.CKEditor5CustomConfig

Steps to use custom build from a custom extension:

  1. Add new CKEditor selector option value from your custom extension :
  // CRM/myExtension/Upgrader.php

  public function upgrade_1000() {
      'option_group_id' => 'wysiwyg_editor',
      'label' => 'MyCustom CKEditor5 ',
      'name' => 'CKEditor5-custom',
    return TRUE;
  1. Create your own build from
  2. Download and place the build/js/ckeditor.js file inside your custom extension's folder (and translations if needed)
  3. Add this code to hook_civicrm_coreResourceList in your custom extension:
function myextension_civicrm_coreResourceList(&$items, $region) {
  if ($region === 'html-header') {
    if (Civi::settings()->get('editor_id') === 'CKEditor5-custom') {
      $locale = CRM_Core_I18n::getLocale();
      $lang = substr($locale, 0, 2);

      $items[] = [
        'config' => [
           // In case translations are different in my build, if not the ckeditor5 extension files can be used by default
          'CKEditor5Language' => ($lang != 'en' ? CRM_Core_Resources::singleton()->getUrl('myextension', 'packages/ckeditor5/build/translations/' . $lang . '.js') : ''),
          // path to custom ckeditor5 build js
          'CKEditor5Location' => CRM_Core_Resources::singleton()->getUrl('myextension', 'packages/ckeditor5/build/ckeditor.js'),
          'wysisygScriptLocation' => CRM_Core_Resources::singleton()->getUrl('ckeditor5', 'js/wysiwyg/crm.ckeditor5.js'),
          'ELFinderLocation' => CRM_Core_Resources::singleton()->getUrl('ckeditor5', 'js/elFinder/js/elfinder.min.js'),
          // Custom Ckeditor5 configuration
          'CKEditor5CustomConfig' => [
            'toolbar' => [
              'shouldNotGroupWhenFull' => TRUE,
              'items' => [
            'language' => $lang ?? 'en',
            'image' => [
              'toolbar' => [
              'styles' => [
          'table' => [
            'contentToolbar' => [
          'licenseKey' => '',
      CRM_Core_Resources::singleton()->addStyleUrl(CRM_Core_Resources::singleton()->getUrl('ckeditor5', 'js/elFinder/css/elfinder.min.css'));
      CRM_Core_Resources::singleton()->addStyleUrl(CRM_Core_Resources::singleton()->getUrl('ckeditor5', 'css/ckeditor.css'));

@colemanw @eileen @bgm would be cool if you can take a look and check if this approach makes sense, or we should move forwards to a more complex solution (which will require more refactor). cheers!

Edited by sluc23

Merge request reports