Adding a select box to WordPress tinyMCE editor

April 5, 2011 11:30 pm 23 comments

The process of adding a button to the wordpress editor is straight enough if you follow the instructions that there is in the WordPress Codex and in the the tinyMCE editor documentation. The first one explain how to hook into WordPress to define the name of your tinyMCE plugin and the path to the javascript that the editor calls. The second one define how to build that javascript.

Adding custom buttons to your editor is very useful when you are installing WordPress for a client and he asks about some functionality inside the posts, that would be very easy if the client knew something about HTML, like add a class to a div. If you put a button that create a div with that class you don’t have to explain any HTML to him, you just have to tell him “push the button”, anyway he won’t do it and he will call you asking “how can I….?” – Push the damn button!

But when I searched for adding a select box it wasn’t easy to find the info in the tinyMCE documentation, so I decide to write a tutorial to never forget it.

The plugin that we are going to create will let us insert the shortcodes that we have available in our wordpress easily. I always forget the shortcodes I have so, for me, it is really useful. Its behavior will be really simple:

  • Selecting a shortcode from the select box will wrap any text that is selected in the editor with the shortcode tags: [tag]Selected text[/tag]
  • If there is not selected text a empty tag will be inserted [tag]

Well, are you hungry of code? here you have the main wordpress plugin file, we will name it Shortcodes editor selector, and you can dowload it :

Download Shortcodes editor selector

shortcodeseditorselector.php

I copied the code from the codex page and I modified some things to adapt it to my necessities. The first thing I’ve changed is create a class that contains all the functions and attributes, this is the best thing to avoid conflicts with others plugins.

I have added a comment about how to change the toolbar button row where the selectbox will be.

To add a button to the tinyMCE toolbar we need to complete two steps:

  • Register the tinyMCE plugin, a javascript that contains the behavior of the button. We get this with the registerTmcePlugin method that hooks into ‘mce_external_plugins’. Here the path to the javascript has been changed from the example in WordPress Codex, because we want our plugin to have all the files inside its folder, and the example tell us to put it inside the tiny_mce folder. Using the plugin_url() function it is easy to get to our plugin folder.
  • Register the control into the tinyMCE. In WordPress the hooks are called ‘mce_buttons’ and ’mce_buttons_n’ where n is the tinyMCE toolbar we want to add our control, and I say control because it don’t have to be always a button although the hook name seems to say that it do. We want to add a selectbox but we still have to hook into ‘mce_buttons’.

Once we have our WordPress plugin ready, we need to create the tinyMCE plugin, that tell the editor to draw a select box with the shortcodes. That plugin should be a javascript file, but we need the javascript to include the shortcodes list that only can be retrived using the WordPress PHP functions, so what we are going to do is register a PHP file as the tinyMCE plugin (using the ‘mce_external_plugins’ hook) that write javascript code, this way the editor get a valid javascript file (it doesn’t care about the .php extension) and our server will execute the PHP commands inside it.

Here is its code, copied and subtly modified from the tinyMCE docs:

editor_plugin.js.php

In our script file, the first thing to do is initialize the WordPress admin framework, that will let us to use all the wordpress admin functions and variables and we get it with the first 3 lines of code

The next step is make the script accessible only to logged users, just for security.

Now that we have the access to everything we are going to get the shortcodes list, that WordPress stores in the global variable $shortcode_tags, and we are going to sort it alphabetically, making it more user friendly. This variable is an associative array where each element is a shortcode. The key of the element is the tag name that we use in the editor, and the value is an object that represents the function necessary to convert the shortcode in the expected result. We only need the keys, the part we need to write in the editor.

The rest of the file is the example from the documentation where the plugin name has been changed to ours and we added the code to set up our list. The select boxes for the tinyMCE are called listBox and they are easy to instantiate from inside the createControl method in a plugin. The function responsible of writing the shortcode are binded to the onselect event of the select box, this way we just have to click on the option we want to write it in the editor.

With tinyMCE.activeEditor.selection.setContent and tinyMCE.activeEditor.selection.getContent we get access to the text selected if there is any or otherwise the current position of the cursor.

To set the options for the select box, a little php will help us.

Finally, don’t forget to add the plugin to the tinyMCE plugin manager if you want it to appear in your editor.

If you have get this bottom in the tutorial, I am sure you want to try the plugin. Create a folder named shortcodes-editor-selector in your /wp-content/plugins/ and copy both files there, then log in your WordPress, activate the plugin and you will see the select box in your editor.

 

javi

Let’s push your website a bit further

My name is Javier Márquez and I have more than 10 years of web programming and web designing experience, so, if you have a difficult development to complete, maybe you can stop by and see what I can do for you.

23 Comments - Leave yours

  • Whoa! This blog looks just like my old one! It’s on a entirely different subject but it has pretty much the same layout and design. Great choice of colors!

    • marquex

      Ey Mee! You are my first commenter and I’m glad you like it! Is it possible to have a look at your blog?

  • Hi Marquex ,

    This is a wonderful plugin. I am surprised why there is not enough comments. This plugin takes away the hassle of memorizing and typing in the shortcode tags whenever we need to use it. All the tags are available in a nifty dropdown select box, all we need to do is select and click. How easier can it get.

    But I am sad to see that it is not supporting shortcodes with attributes. If only that too was possible, this would have been really ultimate. Please enable it.

    Keep up the good work..

    • marquex

      Ey Jinson, someday i will upload a better version to the wordpress plugin repository, this one is just a proof of concept.

      It would be nice to add the attributes too, but wordpress doesn’t record the attributes when registering a shortcode, so i didn’t find a way to add them.

  • Thanks marquex!
    I was wondering how to talk to TinyMCE using php. Didn’t know you could use a php file instead of javascript. That js.php extension is clever. I’m interested in adding the attributes too! I’ll look for your plugin at wordpress.org….

  • Wow, great tutorial man. I’d love to have you write a guest post sometime on my blog.

    • javimarque

      Thanks AJ! I’d be glad to write something for your blog if you can correct my poor English :)

  • Thanks for the tutorial. It worked great for me except that some shortcodes are longer than the containing list box.

    Any idea about how to adjust the width of the created listbox?

  • This is great! Glad I found this. One question though, where is the shortcode list being pulled from? I would like to pull shortcodes from a specific .php file. Would that be possible?

  • Is there any way to exclude a few shortcodes from the generated list?

  • thisplay

    great – excatly what i am looking for!
    Another good plugin i found for adding a shortcode dropdown is
    http://wordpress.org/extend/plugins/shortcode-ninja/

  • Jakub Kohout

    Hi,

    Do you know, how to add this functionality without plugin. What should I copy to my functions.php?

  • Thanks for this. Is it possible to have it display on the html editor toolbar as well?

  • I’m seeing an error with WordPress 3.3 on the post editor screen, at the bottom.
    array(1) { ["ShortcodeSelector"]=> string(88) “http://mysite/wp-content/plugins/shortcodes-editor-selector/editor_plugin.js.php” }

    • Andrew

      Great plugin but seeing the random text at the bottom of the post editor also. Any fix for this? thanks

      • javimarque

        This is just a tutorial, it’s not intended to be an actual plugin, so I don’t track its issues. Maybe something has changed in the new versions of WP that make that text appears. Or maybe is hello dolly plugin?

        • You forgot the var_dump in the code:
          if ( get_user_option(‘rich_editing’) == ‘true’)

          var_dump($plugin_array);

          return $plugin_array;

          just remove that

    • dameer

      The very first issue (it’s not “hello dolly” plugin at all!):


      class ShortcodesEditorSelector{
      // ... code
      // ..comment the following, it'll vardump the list of all registered shortcodes!
      if ( get_user_option('rich_editing') == 'true')
      var_dump($plugin_array);
      // ... code
      }

      Then in your “editor_plugin.js.php” file, the very first 2 lines should be replaced with:

      $this_file = str_replace( '\', '/', __FILE__ );
      $this_file = explode( 'wp-content', $this_file );
      $this_file = $this_file[ 0 ];

      require_once( $this_file . 'wp-load.php' );
      require_once( $this_file . 'wp-admin/includes/admin.php' );

      …that’s what I’ve noticed being wrong… other than that – it should be fine.

      If you wanna get rid of creating a plugin simply copy-paste class code to “functions.php” and change line #34 redaing:

      $plugin_array[$this->buttonName] = plugins_url() . '/shortcodes-editor-selector/editor_plugin.js.php';

      …to something like:


      $plugin_array[$this->buttonName] = get_bloginfo('template_directory') . '/editor_plugin.js.php';

      NOTE: “editor_plugin.js.php” should share the path with “functions.php”

      Hopefully it helps! Thanks javimarque for a great post.

  • Hi,

    I used this momentarily before it broke on WP version 3.4. However, I’ve modified it and made it into a popup rather than a dropdown list. The short-tag list is auto-generated, and can be inserted into the content area with a simple click. Also, it will wrap any pre-selected content with the shortcode.

    You can get it in my plugin, Ultimate Tinymce (just search on WP). I’d post the link, but I don’t want to get marked as spam here ;)

    Thanks to you for providing the basis for my code!

  • This is exactly what I needed for my theme. I modified the plugin to work within my theme and it’s displaying my shortcodes perfectly. Thanks!

Leave a reply


contact meAnything related to web development like javascript and CSS to create responsive designs, or PHP and node.js to make your website work properly, is my pleasure. If you have an interesting project in mind, I can help to make it real.