Skip to main content

Insight | Dec 22, 2016

Creating a CKEditor plugin with Drupal 7 using WYSIWYG

By Josh Fremer

 

Sometimes the markup provided by CKEditor is insufficient for your CSS needs. In our case, we needed <table> elements to have a wrapper to satisfy our mobile stylesheet requirements.

To offer this functionality, we need to create a CKEditor plugin. This can be done with or without the WYSIWYG module. My project already has WYSIWYG installed, so I chose to implement hook_wysiwyg_plugin() (if you don't use WYSIWYG, you'll implement hook_ckeditor_plugin() to similar effect):

/**
 * Implements hook_wysiwyg_plugin().
 */
function mymodule_wysiwyg_plugin($editor, $version) {
  if ($editor != 'ckeditor') {
    return;
  }
  $plugins = array();
  $plugins['wraptables'] = array(
    'path' => drupal_get_path('module', 'mymodule') . '/plugins/wraptables',
    'filename' => 'plugin.js',
    'load' => TRUE,
    'extensions' => array('wraptables' => t('Wrap Tables')),
  );
  return $plugins;
}

 

 

This tells Drupal that there is a CKEditor plugin available and where to find the javascript for it. In my mymodule module directory, there is a subdirectory named plugins with a directory named wraptables. This contains the plugin.js file that defines the plugin behaviors:

 

 

(function($) {
  CKEDITOR.plugins.add('wraptables', {
    init: function(editor) {
      // React to the insertElement event.
      editor.on('insertElement', function(event) {
        // event.data is the element that's being inserted.  We only care about
        // table elements in this example.
        if (event.data.getName() != 'table') {
          return;
        }
        // Create a new div element to use as a wrapper.
        var div = new CKEDITOR.dom.element('div').addClass('table-scroll');
        // Append the original element to the new wrapper.
        event.data.appendTo(div);
        // Replace the original element with the wrapper.
        event.data = div;
      }, null, null, 1);
    }
  });
})(jQuery);

 

 

See the CKEditor documentation for all the things you can do with the CKEDITOR variable.

 

 

After implementing the above steps, you'll have a new plugin available. It will still need to be enabled for each profile at admin/config/content/wysiwyg/profile (if you're using the WYSIWYG module) or admin/config/content/ckeditor. This can also be done programmatically:

$profile = wysiwyg_profile_load('full_html');
$profile->settings['buttons']['wraptables'] = array('wraptables' => 1);
// I wasn't able to get entity_save() to work here.
db_merge('wysiwyg')
  ->key(array('format' => 'full_html'))
  ->fields(array(
    'settings' => serialize($profile->settings),
  ))
  ->execute();
 
wysiwyg_profile_cache_clear();

 

 

If you're using the CKEditor module instead of WYSIWYG, the above code will need to be modified. Use ckeditor_profile_load() instead and check the return value for the correct format.

 

 

These are all the steps you need to follow to create a basic plugin. If your extension involves adding a button to the CKEditor interface, I recommend taking a long look at ckeditor_linkchange, a fully-functioning Drupal module with extensive documentation.

Drop us a line

Have a project in mind?

Contacting Third and Grove may cause awesomeness. Side effects include a website too good to ignore. Proceed at your own risk.

Get a fresh perspective on your digital future. The best of TAG, straight to your inbox.

Subscribe to newsletter

By signing up for emails from Third and Grove, you agree to our Privacy Policy. We handle your info with care. Unsubscribe anytime.

Copyright © 2026 Third and Grove

Reduced motion disabled