Wysiwyg button with form #2

Welcome to the second article in my tutorial about building a wysiwyg button for drupal 7 which enables use to inserting tokens.

This will be a four step tutorial

  1. Step one will be building the module and a simple wysiwyg button
  2. Step two will cover a simple wysiwyg button
  3. Step three will expand the button with a multi field form
  4. Step four will make this form dynamic with ajax callbacks for removing and adding fields

For this part we will build a simple wysiwyg button which inserts the basic struckture of our token.

This code is highly inspired by this article on http://deglos.com

To begin with we need to tell drupal that we have a plugin for wysiwyg in our module. We do this my invoking the hook_wysiwyg_include_directory.

/**
 * implements hook_wysiwyg_include_directory
 */
function example_wysiwyg_include_directory($type) {
  return $type;
}

now we need to build the plugin structure, so i our module we will create a new folder called plugins. In this folder we need an .inc file with the same name as our plugin as well as a folder with the same name. In the folder we then need to create an images folder and place an icon image file there. I created a icon.png for this. besides the images folder we need to create two files, a js and a css file with the same names as the plugin.

So if we give our plugin the name tokenInsert the file structure should be

module_name/plugins/tokenInsert.inc
module_name/plugins/tokenInsert/tokenInsert.js
module_name/plugins/tokenInsert/tokenInsert.css
module_name/plugins/tokenInsert/images/icon.png

Okay now for the code in the files.

In the tokenInsert.inc file we will provide wysiwyg with information about our plugin by invoking the hook_wysiwyg_plugin

/**
 * Implementation of hook_wysiwyg_plugin().
 */
function example_tokenInsert_plugin() {
  $plugins['tokenInsert'] = array(
    'title' => t('Insert object'),
    'icon file' => 'icon.png',
    'icon title' => t('Insert objects'),
    'settings' => array(),
  );
  return $plugins;
}

that is it for this file.

The javascript file will provide the functionality for wysiwyg.

// $Id$
(function ($) {
 
Drupal.wysiwyg.plugins['example'] = {
 
  /**
   * Return whether the passed node belongs to this plugin (note that "node" in this context is a JQuery node, not a Drupal node).
   *
   * We identify code managed by this example plugin by giving it the HTML class
   * 'wysiwyg-plugin-example'.
   */
  isNode: function(node) {
    res = $(node).is('img.wysiwyg-plugin-example');
    return ($(node).is('img.wysiwyg-plugin-example'));
  },
 
  /**
   * Invoke is called when the toolbar button is clicked.
   */
  invoke: function(data, settings, instanceId) {
     // Typically, an icon might be added to the WYSIWYG, which HTML gets added
     // to the plain-text version.
     if (data.format == 'html') {
       var content = this._getPlaceholder(settings);
     }
     else {
       var content = '<!--wysiwyg-plugin-example-->';
     }
     if (typeof content != 'undefined') {
       Drupal.wysiwyg.instances[instanceId].insert(content);
     }
   },
 
  /**
   * Replace all <!--wysiwyg-plugin-example--> tags with the icon.
   */
  attach: function(content, settings, instanceId) {
    content = content.replace(/<!--wysiwyg-plugin-example-->/g, this._getPlaceholder(settings));
    return content;
  },
 
  /**
   * Replace the icons with <!--wysiwyg_example_plugin--> tags in content upon detaching editor.
   */
  detach: function(content, settings, instanceId) {
    var $content = $('<div>' + content + '</div>');
    $.each($('img.wysiwyg-plugin-example', $content), function (i, elem) {
      elem.parentNode.insertBefore(document.createComment('wysiwyg-plugin-example'), elem);
      elem.parentNode.removeChild(elem);
    });
    return $content.html();
  },
 
  /**
   * Helper function to return a HTML placeholder.
   *
   * Here we provide an image to visually represent the hidden HTML in the Wysiwyg editor.
   */
  _getPlaceholder: function (settings) {
    return '<img src="' + settings.path + '/images/icon.png" alt="&lt;--wysiwyg-plugin-example-&gt;" title="&lt;--wysiwyg-plugin-example--&gt;" class="wysiwyg-plugin-example drupal-content" />';
  }
};
 
})(jQuery);

The css file should contain styling specific for this plugin and what it renders, make sure to keep it aas general as possible so it is easy to overwrite.

That is it for our initial button.

Now we need to expand it with a multifield form to allow us to insert token elements based on user input.