Adding plugin to Drupal 6.x WYSIWYG (using TinyMCE) module... Having problems

Hey everybody. I’m trying to create a somewhat simple plugin / button for the WYSIWYG module in Drupal 6.x (using TinyMCE for its library). All this button is supposed to do is insert 3 space characters (  ) at the mouse cursor location–it’s an English professor’s website–but the problem I’m running into with this happens when I add content and go to preview my page / story / whatever; this plugin replaces the insertions with the literal string “undefined”. In other words, “undefined” shows up in place of wherever I used the button after previewing my content.

I’m assuming I inadvertently forgot to handle some kind of condition, but the problem is that I don’t know the TinyMCE API well enough (let alone, Drupal’s API) to know what condition to code for nor can I admit to being some sort of jQuery or JavaScript authority (I do have experience in it, though). For whatever it’s worth, I’ve modeled this entire plugin after the pre-built example plugin named “break” (it comes bundled with the WYSIWYG module download).

Any help with this is appreciated. Below is the JavaScript code responsible for causing the problems:

(function ($) {

Drupal.wysiwyg.plugins['threespace'] = {

  /**
   * Return whether the passed node belongs to this plugin.
   */
  isNode: function(node) {
    return ($(node).is('img.wysiwyg-threespace'));
  },

  /**
   * Execute the button.
   */
  invoke: function(data, settings, instanceId) {
    if (data.format == 'html') {
      // Prevent duplicating a threespace.
      if ($(data.node).is('img.wysiwyg-threespace')) {
        return;
      }
      var content = this._getPlaceholder(settings);
    }
    else {
      // Prevent duplicating a threespace.
      // @todo data.content is the selection only; needs access to complete content.
      if (data.content.match(/

/)) {
        return;
      }
      var content = '   ';
    }
    if (typeof content != 'undefined') {
      Drupal.wysiwyg.instances[instanceId].insert(content);
    }
  },

  /**
   * Replace all  tags with images.
   */
  attach: function(content, settings, instanceId) {
    content = content.replace(this._getPlaceholder(settings));
    return content;
  },

  /**
   * Helper function to return a HTML placeholder.
   */
  _getPlaceholder: function (settings) {
    return '   ';
  }
};

})(jQuery);

(I don’t expect any of you to do any leg work here, but if you could just shine some light or provide some avenues to explore, that would be a great help.)

No worries,…

What I’ve done is created a helper module so that you can add or remove the ‘3-spaces’ button from the buttons and plugins UI in the WYSIWYG admin pages (Wysiwyg profiles -> Edit). That way you don’t have to hack the WYSIWYG module or TinyMCE and then keep on hacking after each maintenance update.

So I got carried away and built the module and a working plugin :blush:

I have created a ‘threespaces’ plugin that gets placed in your TinyMCE plugins directory (/sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/). I used the nonbreaking plugin as my model and added two more spaces. I also created an adhoc button that you can replace with your own. It’s just the number 3 on a transparent gif right now.

Upload the plugin and then upload and activate the module. Then go to your WYSIWYG profiles admin section, edit the TinyMCE profile and add the 3-Spaces button. It will then show up as the last button on your toolbar.

The module and plugin are zipped and attached to this post.

EDIT: It was pretty simple to put together so feel free to do whatever you like with the code and put your own domain name in place of mine to make it your own. It was a fun exercise :smiley:

EDIT: There’s an error in my module code above in the plugins array… The array name can’t be hyphenated so it should be as follows:


<?php
// $Id$
/**
 * @file
 * Makes the 3-spaces button available as plugin a for client-side editors integrated via
 * Wysiwyg API.
 */
 

/**
 * Implementation of hook_wysiwyg_plugin().
 */
function wysiwyg_tinymce_three_spaces_wysiwyg_plugin($editor) {
  switch ($editor) {
    case 'tinymce':
      $plugins = array(
        'ThreeSpaces' => array( 
          'path' => $editor['library path'] . '/plugins/threespaces', 
          'buttons' => array('threespaces' => t('3-Spaces')), 
          'internal' => TRUE, 
          'load' => TRUE,
        ),
      );
    }
    return $plugins;
}

So far the helper module will allow you to add the 3-Space plugin to your WYSIWYG UI but it’s going to be more work to make the plugin work within TinyMCE.

Andrew, unless I’m not understanding what you’re trying to do here, the problem isn’t getting Drupal to recognize the button. The problem is getting the button itself to insert the space characters and KEEP them there even if one decides to preview the content they’re editing.

I can get Drupal to realize that the button is there with no problems at all. I can even make the button insert the 3 spaces without flaw. The problem, though, is keeping the spacing there after previewing or editing the content. In my mind, it seems as if there’s something screwy going on with a trim() routine or else something to do with forgetting to code for some “undefined” exception or whatever.

…or was I misunderstanding what you were trying to solve? In any event, I do appreciate your feedback. :slight_smile:

Well I’m no authority on Drupal module development but I have written a few helper modules and WYSIWYG/TinyMCE make it pretty simple to write a plugin. You probably just need to tell WYSIWYG that the 3-space function exists. You do that by writing a little module.

You will need to create at bare minimum two files for your helper module:

  • wysiwyg_tinymce_three_spaces.info
  • wysiwyg_tinymce_three_spaces.module

Your info file could be as simple as:


; $Id$
name = Wysiwyg TinyMCE 3-Spaces (Bridge)
description = Provides WYSIWYG/TinyMCE the ability to include a button to add 3 non-breaking spaces
package = User interface
core = 6.x
dependencies[] = wysiwyg
version = "6.x-1.0"

Your module file will provide the ability to turn the plugin on/off from the WYSIWYG editor profile and it’s a bit more complicated:


<?php
// $Id$
/**
 * @file
 * Makes the 3-spaces button available as plugin a for client-side editors integrated via
 * Wysiwyg API.
 */
 

/**
 * Implementation of hook_wysiwyg_plugin().
 */
function wysiwyg_tinymce_three_spaces_wysiwyg_plugin($editor) {
  switch ($editor) {
    case 'tinymce':
      $plugins = array(
        'Three-Spaces' => array( 
          'path' => $editor['library path'] . '/plugins/threespaces', 
          'buttons' => array('threespaces' => t('3-Spaces')), 
          'internal' => TRUE, 
          'load' => TRUE,
        ),
      );
    }
    return $plugins;
}

Put both of those files in a directory called wysiwyg_tinymce_three_spaces and upload to your /sites/all/modules directory. That is your bridge module. I haven’t tested this but it should work… I’ve got a meeting to run to so I’ll look at it later to confirm.

Now you need to put the code for your plugin in the plugins directory of your TinyMCE module. The full path is usually: /sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/threespaces

  • I have called the plugin you are creating “threespaces” so make sure that if you have another name that you change it in the module code.

I would model my three_spaces plugin after the nonbreaking plugin inside: /sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/nonbreaking

That should do it.

So Wolf_22… Did any of that make sense?

Andrew

Sorry for the radio silence, Andrew. Been on vacation…

I’ll try this out sometime tonight as I’m at work right now. :slight_smile:

(But yes, it made sense for the most part. In my opinion, one shouldn’t have to create a bridge plugin to make another plugin work, especially when the plugin itself is already being acknowledged by Drupal to begin with. If I figure out a way to make what I have work, I’ll post it on here to show you.)

No problem about the radio silence. I hope you’ve had a good vacation. I’m still on summer hours here and taking advantage of the great weather myself.

The reason I went about this in this way is because it is what I’ve come to know as the “Drupal way” of site/module customization. The guys who created the WYSIWYG module provided hooks in several places. One place is how they have set up /sites/all/libraries as the place to put your user interfaces (FCKEditor, TinyMCE, etc…). The other is how you add plugins to that user interface.

If you directly customize WYSIWYG or TinyMCE to include a plugin, the next time somebody updates WYSIWYG or TinyMCE, they will wipe out the connection to your plugin. Using a bridge or helper module ensures that will not happen. It also makes it pretty easy to build your plugin because everything is standardized.

Cheers,
Andrew

Thanks again, Andrew. Your explanation helped a bit and I’ll give this puppy a try tonight. I think we were both on the same page really, but your approach seems to be a bit more demarcated than mine as you’re right: it’s more likely to happen that WYSIWYG will experience an update that will break their intended API versus that of Drupal’s. Good catch. :wink:

No problem at all. Let me know how it works out. Helper/Bridge modules are my Drupal 1-trick pony :tup:

Worked like a charm, Andrew. :slight_smile:

The funny thing is that our ways weren’t that dissimilar with the only exception being (besides the fact that yours works!) that you decided to create that “helper” module. Otherwise, like yours, I too was trying to mold after a pre-built function (at first) from within the TinyMCE directory… I could never seem to find any spot-on tutorials for that way, though–which led me down the path of doing it through the WYSIWYG directory approach.

So in your mind, this approach is less likely to be wiped out in the case of a release / upgrade? …but the main plugin component in all this is still in the TinyMCE directory…? Does TinyMCE not override that directory with releases?

Thanks again, Andrew, and if you could shine some light on those questions, that would be awesome.

Great, glad to hear it!

You bring up a good point about changing TinyMCE and possibly wiping out the plugins directory. I suppose it depends on the FTP client that you use but I just uploaded another copy of TinyMCE over my existing one using FireFTP and it left my threespaces plugin intact. If you update WYSIWYG, your plugin and helper module will definitely be safe, which is the reason I chose to build the helper module.

If you’re overly concerned about the FTP issue, you could change the path and location of the threespaces plugin and move it to another spot like /sites/all/libraries/plugins by changing line 18 in the module from:


'path' => $editor['library path'] . '/plugins/threespaces', 

to:


'path' => '/sites/all/libraries/plugins/threespaces', 

I haven’t tried that but it should do the trick.

Andrew

Hi all,

Sorry to bring this post up.

I found this one by accident and it is exactly what I need!
Thet problem is that I cant figure out how to show the plugin in the list.
I uploaded it to the folder you gave but no result.

Can somebody please assist me in this?

Here’s the Cole’s notes:

  • Have you got WYSIWYG and TinyMCE working? That’s the first step.
  • Then you need to upload the ‘threespaces’ plugin in your TinyMCE plugins directory (/sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/).
  • Upload and activate the ‘wysiwyg_tinymce_three_spaces’ module.
  • Then go to your WYSIWYG profiles admin section, edit the TinyMCE profile and tick the checkbox to add the 3-Spaces button. It will then show up as the last button on your toolbar.