Customizing WYSIWYGs beyond module settings

A large majority of features found in WYSIWYG editors are overkill for end users. With the WYSIWYG module you do have control over the display of buttons to perform functions, but that's about all you get as far as customization. Our clients liked CKEditor as the WYSIWYG editor to use, but wanted some functionality changed which was not available to us in the WYSIWYG module.

Three of the major changes requested were:

  1. Automatically enable the built in spell checker when the wysiwyg is loaded
  2. Remove the "Advanced" and "Link" tab on image properties dialogue
  3. Rename some form labels and remove some form elements entirely from the image properties dialogue

I'll be talking specifically about how this was achieved in CKEditor. Let's start by seeing how to achieve these changes in CKEditor itself then we'll figure out how to incorporate the changes into Drupal.

The CKEditor documentation showed that enabling the spell checker was actually a configuration change normally part of "core/config.js" http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.scay.... Altering the display of tabs and changing form labels was a little more involved though requiring some custom javascript as outlined here
http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Dialog_Customization with additional documentation found in the ckeditor _samples directory in a filed called api_dialog.html

Ok, so now we know how to make the changes in CKEditor, but how do we do this with the WYSIWYG module? Thankfully WYSIWYG provides us with an all important module hook where we can make all our changes hook_wysiwyg_editor_settings_alter. Assuming I've created a custom module called ckeditor_tweaks my hook implementation would look like this.

<?php
function ckeditor_tweaks_wysiwyg_editor_settings_alter(&$settings, $context) {
 
//Check if the editor is ckeditor
 
if ($context['profile']->editor == 'ckeditor') {
       
//Enable the spell checker by default
   
$settings['scayt_autoStartup'] = true;
  }
}
?>

The hook takes two parameters, the $settings variable which is called by reference and the $context variable which contains information about the specific instantiation of each editor that's loaded. So first we check the context to ensure we are loading ckeditor, then we alter the $settings variable to add the configuration parameter we found in the ckeditor api. Pretty easy eh!

Now we'll try and tackle #2 on our list. Removing the "Advanced" and "Links" tab on the image properties. First lets create our Javascript in a file called ckeditor_tweaks.js in our module directory.

CKEDITOR.on('dialogDefinition', function( ev ) {
var dialogName = ev.data.name; 
var dialogDefinition = ev.data.definition;
  
switch (dialogName) {

case 'image': //Image Properties dialog
   
    // Remove the Advanced and Link tabs   
dialogDefinition.removeContents('advanced');
dialogDefinition.removeContents('Link');

break;
}
});

The above javascript modifies the CKEditor dialogDefinition by removing the "advanced" and "Link" elements from the Image dialog box. A good way of finding the names of these items is by actually routing around and inspecting the CKEDITOR object in your browser using Firebug or any other javascript debugger available to you.

So now that we know how to remove these elements, how do we inject this javascript? We can simply include it via drupal_add_js in the same WYSIWYG hook we used before.

<?php
function ckeditor_tweaks_wysiwyg_editor_settings_alter(&$settings, $context) {
 
//Check if the editor is ckeditor
 
if ($context['profile']->editor == 'ckeditor') {
       
//Enable the spell checker by default
   
$settings['scayt_autoStartup'] = true;
   
// Add our custom javascript to the page load
   
drupal_add_js(drupal_get_path('module','mymodule') . '/ckeditor_tweaks.js', 'module', 'header', $defer = FALSE, $cache = TRUE, $preprocess = TRUE);
  }
}
?>

The javascript is ensured to only be loaded whenever the editor is initialized. The last thing we need to do now is modify text labels for some form items and remove other form items entirely. So we'll update our ckeditor_tweaks.js file.

CKEDITOR.on('dialogDefinition', function( ev )
{

var dialogName = ev.data.name; 
var dialogDefinition = ev.data.definition;
  
switch (dialogName) {

case 'image': //Image Properties dialog

  // Get the contents of the image info window
    var infoTab = dialogDefinition.getContents( 'info' );
   
    // Change the label text for Alt"
    field = infoTab.get('txtAlt');
    field['label'] = "Image caption";
    // Change the label text for Border"
    field = infoTab.get('txtBorder');
    field['label'] = "Border size";
    // Change the label text for HSpace"
    field = infoTab.get('txtHSpace');
    field['label'] = "Left/Right space";
    // Change the label text for VSpace"
    field = infoTab.get('txtVSpace');
    field['label'] = "Up/Down space";
   
    // Remove the alignment dropdown
    infoTab.remove('cmbAlign');
   
    // Remove the Advanced and Link tabs   
dialogDefinition.removeContents('advanced');
dialogDefinition.removeContents('Link');

break;
  }
});

The new javascript first gets the contents of the dialog into the variable infoTab. From there we go through one by one loading the different fields we want and altering their "label" property. I found out the names for the fields "txtAlt", "txtBorder", etc by browsing through the CKEDITOR object in firebug. The .remove method is used to completely remove a field. In this case the "cmbAlign" field refers to the select box allowing the user to choose which alignment they want for the image.

So that's it. A customized WYSIWYG editor that has no modifications to the core module and is upgrade safe. If you'd like to get a copy of the module to play with you can find it on github. https://github.com/freeform/ckeditor_tweaks. Any comments, questions, tweaks, or better alternatives are welcome.

Comments

Thank you.

Thank you for the very helpful walk through. Spell check on by default, wonderful.

Cool!

Thanks for sharing!

Alternative Text IS NOT Image Caption...

It may be used for that purpose too (by some templating in the back-end), but this field's main purpose is and should remain to provide an alternative short description for the visual impaired.

Renaming the field to Caption is very confusing for the average WYSIWYG user. With this field they should focus on optimizing its text for alternative uses, not for use as caption.

ALT != TITLE !!!!

ALT != TITLE !!!!

Post new comment

By submitting this form, you accept the Mollom privacy policy.