You are here: Home » Extending WordPress » DIY WordPress: Unraveling Quicktags for WordPress Plugins

DIY WordPress: Unraveling Quicktags for WordPress Plugins

by Dave Doolin on December 10, 2009 · 6 comments

(Reading time: 10 – 16 minutes)

Digging deep into WordPress is always a mixed bag of frustration and delight. Frustration at apparently arbitrary complexity, delight when you figure out something isn’t nearly as hard as it seemed (even if it still makes no sense).

Long time readers know I’ve been working a few days per month on a recipe display plugin for WordPress. The hRecipe plugin allows you to enter your recipe line by line, then formats your recipe according to how you would like it styled. The bonus is that the styling adheres to the hRecipe microformat specification, which will provide a distinct advantage for long term SEO results.

I’ve been delighted with the results, which include a front page link from wordpress.org. But the frustrations have been, well, frustrating. Chief among frustrations is battling through turgid, poorly written or inapplicable documentation, especially concerning the data entry module built into the WordPress editor.

Digital archeology

WordPress is fairly well documented for common used features. Start scratching around at older code, you’ll find out pretty fast you’re almost on your own. For older features, there’s often not much out there, and what is out there is not always accurate. So you have to figure it out for yourself.

The hRecipe plugin is based on the now-very-old WordPress hReview plugin, which let’s you compose and display microformatted reviews. Over the course of 5 revisions, I’ve improved the code base a lot. The hRecipe code has been extended for many new fields. The plugin has been modified to use class-based plugin structure. And various functions have been stripped out to use as demonstration code. But there’s bits and pieces leaving me scratching my head, specifically, the editor. Time to dig deeper.

For me, the fastest way to understand how a WordPress plugin works is to isolate all the moving parts, and study each part of the plugin carefully, then create a small demonstration. For the hRecipe plugin, this demonstration code is useful

  1. for learning how each part of hRecipe actually works,
  2. for debugging hRecipe,
  3. as a source of material for future plugins, and
  4. as the basis for a small product suite offered to customer interested in learning do-it-yourself WordPress.

Each is reason enough, the list makes demo development a no-brainer.

About right here, you should be scanning down the page and feeling one of two extreme emotions. You’re either elated that I’m about to reveal some WordPress black magic… or you’re horrified by black magic.

That’s cool.

This blog post isn’t for everyone, technically, it’s a bit rich.

Feel free to jump to the end, I won’t mind.

If you’re ready to rock, let’s roll…

Extending WordPress editor

One of the toughest parts of the hRecipe (nee hReview code) is handling the WordPress post and page editor integration. This is the code that allows you to launch from the post or page editor, and enter in all the hRecipe data in a user-friendly way.

There’s two paths for hRecipe data entry:

  1. Using the HTML editor, which require handling Quicktags, and
  2. using the visual editor, which requires extending TinyMCE component with it’s own plugin.

The coding is subtle, devious and tricky because the editing component is written in Javascript, while WordPress is written in PHP. Actually, it’s not that bad, you just have to keep track of which programming language you’re using, and where.

Let’s start with WordPress Quicktags. Teaching you how to handle the TinyMCE plugin would add another 1500 words to this article, we’ll take a look at that some other time.

WordPress Quicktags

WordPress Quicktags are the buttons on the editor toolbar when you are editing from within the HTML editor in the WordPress New or Edit Post interface.

Screenshot? Sure…

WordPress Edit Posts Quicktags display

WordPress Edit Posts Quicktags display

It turns out there’s a couple of ways to do this.

One way is to hack the WordPress core files. This is super fast for creating a quicktag, but you will have to add files or functions elsewhere to handle it’s calling code. Fast and easy, but hacking on core always results in a maintenance hassle.

Another way is to add the quicktag to the existing editor button array before the quicktags bar is emitted after page assembly. The trick here is to ensure that WordPress can find your callback. You want your quicktag to work after the user presses it.

The way we’re going to it here is to add the quicktag to the page after WordPress assembles and emits the editor’s HTML code. This way results in a tidy, easily maintainable code for your plugin, that won’t step on anyone else’s code.

In summary, it seems simple enough: just add a button to the editor, then hook it up to some action, for example, inserting a recipe.

Let’s write a piece of demo code.

1
2
3
4
5
6
7
8
9
10
11
12
    var tinymce_qttoolbar = document.getElementById("ed_toolbar");  
 
    if (tinymce_qttoolbar) {
        var tnewbutton = document.createElement("input");
        tnewbutton.type = "button";
        tnewbutton.id = 'ed_tinymce';
        tnewbutton.className = 'ed_button';
        tnewbutton.value = 'DemoTinyMCE';
        tnewbutton.onclick = edInsertDemoTinyMCECode;
        tnewbutton.title = 'TinyMCEDemo';
        tinymce_qttoolbar.appendChild(tnewbutton);
    }

I labeled everything “tinymce” and “DemoTinyMCE” because this example is extracted from the working TinyMCE demonstration plugin that follows. Note that this is Javascript, not PHP code. (That really matters.)

Read the listing carefully. The part that makes the magic happen is the onclick call to edInsertDemoTinyMCECode. I haven’t shown this function here, it’s not necessary for understanding basic quicktag operation.

You’ll need to wrap this snippet in the correct <script> tags as shown below, and you need to invoke it correctly. When you invoke it correctly, you’ll see it in the DOM about like this:

Quicktags location in the New Post document model

Quicktags location in the New Post document model

Note all the attributes you set in the Javascript code above are listed out as part of the input element for ed_tinymce. (Ask questions in the comments if this isn’t clear.)

Here’s what that means:

  1. Input child elements of ed_toolbar ID control the quicktags buttons on the toolbar.
  2. The quicktags ID is the block containing the entire quicktags toolbar.
  3. The ed_toolbar ID is a block wrapping the necessary Javascript elements for making the quicktags operational.

Here’s the main thing you need to understand to get it working correctly: when WordPress makes a pass over your Javascript code, it may or may not be ready to use that code. Sometimes, it stashes a reference to the Javascript code and calls it later.

That’s all well and good when everything works.

Sometimes…

Quicktags goes pear-shaped

If you don’t invoke the Quicktags Javascript correctly, it won’t work. When it doesn’t work, your Quicktags button doesn’t show up on the editor toolbar. Fixing this requires understanding a little more about WordPress.

Specifically, we need to find a repeatable scenario showing how:

  1. Quicktags doesn’t work when called incorrectly, and
  2. does work when called correctly.

Let’s write a demo of the demo, a single file plugin adding a dummy Quicktag to put a Javascript alert in our code. Here’s the listing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
 
/*
 Plugin Name: Demo Plugin Ed Toolbar
 Author: Dave Doolin
 Author URI: http://website-in-a-weekend.net/
 */
 
function ed_toolbar_init() {
 
?>
<script type="text/javascript">
//<![CDATA[
 
  var ed_toolbar = document.getElementById("ed_toolbar");    
 
  if (ed_toolbar == null)  {
     alert("INIT: ed_toolbar is null");
  }  else {
     alert("INIT: ed_toolbar is NOT null");  
  }
 
    //]]>
</script>
<?php
}
 
function ed_toolbar_demo() {
?>
 
<script type="text/javascript">
    //<![CDATA[
 
   var ed_toolbar = document.getElementById("ed_toolbar");
 
   if (ed_toolbar == null)  {
     alert("DEMO: ed_toolbar is null");
  }  else {
     alert("DEMO: ed_toolbar is NOT null");  
  }
 
    //]]>
</script>
<?php
}
 
add_action('init','ed_toolbar_init');
add_filter('admin_footer', 'ed_toolbar_demo');
 
?>

You should type all this yourself. It’s the fastest way I know to get a grip on how source code works. Wess Cope thinks so too. But, if you want, download WordPress quicktags ed_toolbar source.

The plugin works in two steps:

  1. When the plugin is loaded it calls ed_toolbar_init and add the ed_toolbar_demo function to an array of functions called when the admin_footer code is fired. The ed_toolbar_init function attempts to obtain a handle to the Quicktags toolbar and fails. The Javascript alert box tells us this handy fact.
  2. When you next cause the admin_footer filter to operate, the little plugin once again attempts to obtain a handle to the Quicktags toolbar, but succeeds this time as the Javascript alert box informs us.

Note: Don’t leave this plugin running on an operational WordPress website. Check it out on your localhost installation or a test blog. Delete it once you understand how it works.

Screenshot, code, that’s all well and good, but I hear you muttering “Show me the money…” Ok, money shot coming right up.

Live action plugins

Explanation is good, demonstration is better. Here’s a quick (2.5 minute) video showing exactly what’s going on with the Quicktags:

YouTube Preview Image

Simple, right?

Excellent!

Fast Quicktags plugin recap

If you didn’t get all that on your first read (trust me, I wouldn’t have), here’s a quick summary for rereading:

  1. Create your plugin initialization function as usual, adding to the action queue for WordPress init tag.
  2. Write a Javascript function to create the quicktag and insert it into the correct div block for the editor.
  3. Wrap your quicktags Javascript function with a PHP wrapper function.
  4. Add the wrapper function to the admin_footer filter list.

Use this list as you go back through the article, to ensure you understand every step.

Questions are welcome!

If I got anything wrong, let me know, I’ll fix it.

Head start references

I didn’t figure this out all on my own, I had a little help from the Web, and I sure needed it. Here’s a couple of links I found useful:

  • I found Adding Quicktags To WordPress And To The TinyMCE Editor For WP Plugin Authors In Many Easy Steps after I had about half this article written. The author covers both quicktags and TinyMCe, which was my initial intent. After this article hit 1500 words (over 1850 now), I moved all the TinyMCE explanations to a new article to tighten the focus on WordPress quicktags in this article.
  • Please read the first part of WordPress Wednesday: Amazon QuickTags Plugin, where the author explains how is fast hack of the quicktags.js file in WordPress core resulted in a maintenance nightmare as WordPress core was upgraded over time. Hacking core is a perfectly acceptable way to extend WordPress… but without some serious software engineering tools, you’ll be in the same bind pretty fast. That being said, understanding how the code works in core is always helpful for understanding how to extend that code with a plugin.

Note: I did not find all of these on the front page of Google Search results. I dug through the top 5 SERPs and these were the most helpful links I found.

Please visit these websites and leave encouraging comments. Programming really is a labor of love, and your appreciation will keep the love (and the free code) flowing.

And let me know if you find other relevant links for adding quicktags using plugins.

WordPress Plugin Tutorials

Building WordPress plugins is as easy way to teach yourself how to program. When you already know how to program, having runnable code at your fingertips takes a vast amount of time off the learning curve.

If you’re interested slicing your WordPress learning curve to little bitty pieces, check out the Website In A Weekend WordPress tutorial plugin suite. Each tutorial plugin in the suite is very small, typically one or two files, and performs only one task.

In the future, I’ll be offering the entire suite of tutorial plugins, bundled with extensive – and accurate – documentation, for a small cost. For now, download them at will!

Lagniappe

I’ve been into electronica pretty heavily last couple of years, but I’m a long time of both Jeff Beck and Immy. So here’s a little something for smooth jazz fans. Enjoy! (And don’t miss Immy, she’s touring right now.)


For those that care about such things, this is blog post #200 on Website In A Weekend.





Would you like more? Send me a letter...
"Hi Dave,
Website In A Weekend seems pretty cool. I'm serious about this WordPress and web stuff, and I'd like to keep up with it. My name is and my email address is . I'm comfortable with email newsletters. I know you will protect my privacy, and that I can unsubscribe at any time. "

{ 6 comments }

Deacon December 10, 2009 at 11:28 am

Yeah, you’ve left me in your dust in terms of familiarity with Wordpress.
I can tell this is rich, but it is way over my head. I haven’t dabbled in this yet at all.
Deacon´s last blog ..How to be a Part Time Artist (or anything else!) My ComLuv Profile

Dr Wordpress! December 10, 2009 at 11:52 am

@Deacon – not so… I don’t know doodly about the loop. Yet.
Dr Wordpress!´s last blog ..Playing The Host: A Quick Intro to Wordpress MU My ComLuv Profile

Extreme John December 12, 2009 at 1:17 pm

Ummmm wow… This is out of my league in a big way. This is going in the read this later folder so I can absorb it when im not drinking :)
Extreme John´s last blog ..14 Ways to Get More Blog Engage Votes My ComLuv Profile

Dr Wordpress! December 13, 2009 at 4:09 pm

@EJ – Writing these kinds of articles is part of why I have a hard time keeping up with twitter, commenting, all the other stuff I’m sposed to do as a “responsible blogger!”

Thanks for reading. I have many more of these articles both in draft and in my head, waiting to get the time and energy to ensure they are written correctly before I pull the “Publish” trigger.
Dr Wordpress!´s last blog ..Playing The Host: A Quick Intro to Wordpress MU My ComLuv Profile

Benxamin February 4, 2010 at 8:05 pm

So, I thought I’d just add another option to the LINK tag so that I could set a target, relation and maybe even add a title. But NO. Once you get into the quicktags.js you realize it’s a bit of a mess trying to reverse engineer it.
I started hacking the core, and still couldn’t get a friggin’ alert box to pop.

Thanks for showing us the right way and keeping it orderly!

Dr Wordpress! February 4, 2010 at 8:11 pm

And you’re writing a little note about this, right? So that I can link to it when you publish, right?

Awesome!
Dr Wordpress!´s last blog ..Refreshing Your Pillar Content By Recycling Blog Posts My ComLuv Profile

Comments on this entry are closed.

Previous post:

Next post: