Justin Tadlock

Disallow specific shortcodes in post content

I’m no fan of WordPress themes adding shortcodes. I’ve been pretty adamant about it in the past. But, all rules have exceptions, right?

So, you’re telling me that you — the guy who’s been drilling it into my head to not add theme shortcodes — that it might now be okay?

Well, yes. Technically, I’ve always been okay with themes adding shortcodes as long as those shortcodes are not intended to be used in the post content.

Shortcodes can be used for any number of purposes. Generally speaking, developers create shortcodes to be used in the post content. For this reason alone, shortcodes belong in a plugin. However, if you’re creating a shortcode to be used in other places where data portability is not an issue, go wild.

Here’s a few examples of what I consider exceptions to the rule:

  • Shortcodes for use in theme templates.
  • Shortcodes for use in theme settings, such as the footer text.
  • Shortcodes for use in widgets (this is probably a bit of a gray area to some).

The problem is that users can still use these shortcodes in the post content even if it wasn’t your intention to allow them to do so. This discussion came up in the comments on the proposed WordPress 3.5 theme guideline revisions. This tutorial will show you how to avoid that scenario.

Adding shortcodes

I’m going to assume you’re already familiar with the process of adding shortcodes using WordPress’ add_shortcode() function, so I won’t cover that.

The following is an example of a few theme-defined shortcodes and how they should be set up.

add_action( 'init', 'my_add_shortcodes' );

function my_add_shortcodes() {

    add_shortcode( 'shortcode_1', 'my_shortcode_1' );
    add_shortcode( 'shortcode_2', 'my_shortcode_2' );
    add_shortcode( 'shortcode_3', 'my_shortcode_3' );
}

This is just to give you a base to work with for the remainder of this tutorial. You can set up your own shortcodes however you like.

Not allowing theme shortcodes in the post content

We don’t want our shortcodes to be used at all in the post content. The best option here is to simply remove them when the the_content filter hook is called. WordPress makes this extremely easy with the remove_shortcode() function.

The following code will remove the three shortcodes we added earlier.

add_filter( 'the_content', 'my_post_content_remove_shortcodes', 0 );

function my_post_content_remove_shortcodes( $content ) {

    /* Create an array of all the shortcode tags. */
    $shortcode_tags = array(
        'shortcode_1',
        'shortcode_2',
        'shortcode_3'
    );

    /* Loop through the shortcodes and remove them. */
    foreach ( $shortcode_tags as $shortcode_tag )
        remove_shortcode( $shortcode_tag );

    /* Return the post content. */
    return $content;
}

Wait! Won’t that permanently remove the shortcodes? Yes, it will. Therefore, you must add them back so they can be used outside of the_content. The following code does just that.

add_filter( 'the_content', 'my_post_content_add_shortcodes', 99 );

function my_post_content_add_shortcodes( $content ) {

    /* Add the original shortcodes back. */
    my_add_shortcodes();

    /* Return the post content. */
    return $content;
}

Thoughts? Other solutions?

I agree that this seems like a bit of a hack, but it’s the best option I’ve found thus far and doesn’t take much code. I’m open to suggestions on better methods.

The great news is that you don’t have to worry about your users messing up their content by using shortcodes that you didn’t intend for use in the post content. They’ll know upon any attempts to do so that it simply won’t work.