Updated: February 2nd, 2011

WordPress has a great way of letting you use simple text tags called shortcodes to provide a whole bunch of functionality, including custom PHP code. In this article, I'm assuming that you already know what shortcodes do and how they operate (if you don't, head over here: Shortcode_API).

One glaring omission in the way shortcodes are set up by default is that they only get triggered in the content of your post, leaving the sidebar and comments out. I'm sure this is done for security, so that your readers can't screw something up by posting shortcodes they're not supposed to – after all, shortcodes are PHP snippets on the backend.

However, let's assume you really know what you're doing and you want, for example, to allow certain shortcodes in the comments and all shortcodes in the sidebar. It's your site and you should be able to do whatever you want with it. For instance, I wanted to provide a way to include QR codes using a [qr] shortcode syntax that I'd written both in the sidebar and in the comments, except in the comments that was the only shortcode I wanted to allow my readers to use.

Since these cases can get complicated, let's start simple and then progressively get deeper.

Allow all shortcodes in the sidebar

Assuming you want to enable shortcodes in the PHP Code Widget widgets (I believe this is the most common way to add PHP support to the sidebar), use this code:

1
add_filter('widget_execphp', 'do_shortcode');

If you have some other widgets in mind, you have to find out the right filter and use it just like above.

Allow only whitelisted shortcodes in the comments

Since I don't want all shortcodes to fire here, things get slightly trickier.

1
2
3
4
5
6
7
8
9
10
11
12
function init_common_shortcodes() {
  add_shortcode('qr', 'my_shortcode_qr');
}
 
function init_comment_shortcodes() {
  remove_all_shortcodes();
  init_common_shortcodes();
  add_filter('comment_text', 'do_shortcode');
}
 
init_common_shortcodes();
add_filter('comments_template', 'init_comment_shortcodes');

The code above will remove all shortcodes when it gets to comments and reinitialize only the whitelisted one called "[qr]", which is exactly what I wanted.

Note: If your code somehow uses shortcodes after the comments (such as a sidebar or a custom post query), you will need the trick in the next section.

Allow all shortcodes in the sidebar AND only whitelisted ones in the comments

At this point, things get slightly tricky because if I combine the previous 2 solutions into 1, by the time WordPress gets to the sidebar, it'll be left without any shortcodes at all – they've been removed by the code dealing with comments. Therefore, I need to save the shortcodes before dealing with comments and then restore them after the comments and before the sidebar.

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
function my_remove_all_shortcodes() {
  global $shortcode_tags;
  global $temp_shortcode_tags;
  $temp_shortcode_tags = $shortcode_tags;
  remove_all_shortcodes();
}
 
function my_restore_all_shortcodes() {
  global $shortcode_tags;
  global $temp_shortcode_tags;
  if(!empty($temp_shortcode_tags)) {
    $shortcode_tags = $temp_shortcode_tags;
  }
}
 
function init_common_shortcodes() {
  add_shortcode('qr', 'my_shortcode_qr');
}
 
function init_comment_shortcodes() {
  my_remove_all_shortcodes();
  init_common_shortcodes();
  add_filter('comment_text', 'do_shortcode');
}
 
add_filter('comments_template', 'init_comment_shortcodes');
add_filter('dynamic_sidebar', 'my_restore_all_shortcodes');
add_filter('widget_execphp', 'do_shortcode');
init_common_shortcodes();

Here is what the code does:

  1. Initialize custom shortcodes that I want to add all over the place.
  2. When WP gets to the comment block, it removes all shortcodes (again, for security) and re-initializes only the ones I want, but this time remembers them so that they can be restored later.
  3. After the comments, when WP gets to the dynamic sidebar, it restores all the shortcodes and applies them to each PHP Code Widget.

And there you have it. Of course, the code may need tweaking for your own scenario but the ideas are all there. If you spot an error or know of an easier/better way, please let me know.

● ● ●
Artem Russakovskii is a San Francisco programmer and blogger. Follow Artem on Twitter (@ArtemR) or subscribe to the RSS feed.

In the meantime, if you found this article useful, feel free to buy me a cup of coffee below.