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.