array( 'type' => 'external', 'title' => t('My plugin title'), 'description' => t('My plugin title'), // Regular callback URL for external TinyMCE plugins. 'path' => drupal_get_path('module', 'mymodule') .'/myplugin', // Wysiwyg wrapper plugin AJAX callback. 'callback' => url('myplugin/browse'), 'icon' => drupal_get_path('module', 'mymodule') .'/myplugin/myplugin.png', 'extended_valid_elements' => array('tag[attribute1|attribute2=default_value]'), // Might need to be set later on; after retrieving customized editor // layout. 'theme_advanced_buttons1' => array(t('Button title (optional)') => 'myplugin'), ), ); } } /** * Implementation of hook_wysiwyg_plugin(). * * Implements a generic wrapper plugin for Drupal (module-based) editor plugins. * * Considerations: * - By comparing the javascript of available editor plugins, most of them are * based on img_assist. * - An editor plugin basically consists of a title, icon (button), description * (localized) and menu path returning the actual Drupal module. This * meta-information is available via hook_wysiwyg_plugin(). * - Each editor implements its own plugin API, but the JS-PHP-JS communication * is always the same. * - Since Drupal 5, jQuery is always available and allows to perform AJAX/HTTP * requests at any time. * - Each editor plugin returns HTML via Javascript to the editor. * - Do we really require each Drupal editor plugin to write their own * javascript or are we able to supply Drupal editor plugins to all editors * through a wrapper module? * - We can transform a regular editor plugin template into a wrapper plugin or * we can use a Drupal menu path to serve a editor plugin template which * (optionally) already has additional plugin code injected. */ function wysiwyg_wysiwyg_plugin($editor) { switch ($editor) { case 'tinymce': // Define generic plugin properties. $path = drupal_get_path('module', 'wysiwyg') .'/wrapper/tinymce' // Load all Drupal editor plugins into an array. $plugins = module_invoke_all('wysiwyg_plugin', $editor); // Define all Drupal editor plugins by looping through the array, // omitting all non-'external' plugins; assigning type, title, icon, // custom editor settings and most important: // wrapper plugin path followed by callback path (if JS: use query string). return $plugins; } } /** * Return an array of editor plugins. * * @param string $op * A performed action: * - 'list': Plugins are about to be listed or registered. * - 'load': Plugins are about to be loaded. * @param string $editor * An (lowercase) editor name to retrieve plugins for. * * @see hook_wysiwyg_plugin() * * @todo Implement TinyMCE-specific code as hook into wysiwyg_tinymce.inc. */ function wysiwyg_get_plugins($op, $editor) { static $plugins; if (!isset($plugins)) { $plugins = module_invoke_all('wysiwyg_plugin', $editor); } switch ($editor) { case 'tinymce': if ($op == 'list') { // Do not alter cached array. $plugin_list = $plugins; foreach ($plugin_list as $name => $plugin) { if ($plugin['type'] == 'external') { $plugin_list[$name] = _wysiwyg_plugin_name('add', $name); } } return $plugin_list; } else if ($op == 'load') { static $plugins_added; if (!isset($plugins_added)) { $plugins_added = TRUE; $init_plugins = ''; foreach ($plugins as $name => $plugin) { // Ensure there is no leading hiven in external plugin names. $name = _wysiwyg_plugin_name('remove', $name); $init_plugins .= "tinyMCE.loadPlugin('$name', '". base_path() . $plugin['path'] ."');\n"; } if (!empty($init_plugins)) { drupal_add_js($init_plugins, 'inline'); } } } break; } } /** * Add or remove leading hiven to/of (external) plugin names. * * Externally loaded TinyMCE plugins need to be prefixed with a hiven. TinyMCE * will not try to add and load external plugins from the default plugins * folder. * * @param string $op * Operation to perform, 'add' or 'remove'. * @param string $editor * An editor name. * @param string $name * A plugin name. * * @todo Implement TinyMCE-specific code as hook into wysiwyg_tinymce.inc. */ function _wysiwyg_plugin_name($op, $editor, $name) { switch ($editor) { case 'tinymce': if ($op == 'add') { if (strpos($name, '-') !== 0) { return '-'. $name; } return $name; } else { if (strpos($name, '-') === 0) { return substr($name, 1); } return $name; } break; } }