Don’t do_shortcode

Shortcodes are pretty cool, and the do_shortcode function is pretty neat as it can parse and execute shortcode callbacks from arbitrary strings, but that function invokes a fairly large regex every time it is called.

That regex looks for all registered shortcodes within a string. For each match, it runs a replacement with a callback function, which also take the time to parse the shortcode attributes, before finally calling the actual callback function that’s been registered with add_shortcode.

Regular expressions are pretty fast in PHP, especially for short strings, but do we really have to have WordPress do all that extra work, when all we really intended was to call our shortcode callback function?

echo do_shortcode( '[foo]' ); // Boo
echo foo_shortcode_callback(); // Yey!

I ran a quick search in the plugins directory, using the following regex:

do_shortcode\(\s*['"]\[

Not the best crafted regex, but it’s supposed to look for calls to do_shortcode followed by a string literal starting with an opening square bracket. Obviously it might get a few false positives for special cases, but it also misses quite a few matches where the shortcode string is put into a variable first.

I found over 600 entries in over 270 plugins, including some of my own. Guilty! So the lesson I learned today is: don’t use do_shortcode when you can use your callback function directly, which is much more efficient.

Don’t Hide the Fact That You’re Using WordPress

There are quite a few blog posts, plugins and hacks suggesting to hide the WordPress version number, or hide the overall fact that you’re using WordPress. Don’t do it — it’s pretty useless.

There are hundreds if not thousands of ways to not only find out the fact that you’re using WordPress, but also find out the exact version number, regardless of any plugins or hacks changing or hiding the “generator” meta tag, the readme file and so on. A great post by my brother Gennady illustrates that.

Security

Most of these “hide my WP” solutions tend to market themselves from a security standpoint, especially with the recent botnet attack on WordPress sites. The truth is that these attacks don’t really care which version of WordPress you’re running. In fact, they don’t even care whether you’re running WordPress at all! How? Well that’s easy, they just take your domain and blindly fire POST requests to a file called wp-login.php, even if you’re running a non-CMS pure HTML website.

The same applies to known theme and plugin vulnerabilities. Go ahead and check your web server’s access logs, there’s a pretty good chance you’ll find requests to timthumb.php even though none of your themes or plugins use the TimThumb library.

So from a security perspective, the secret sauce is to use a strong password, as well as keep your themes, plugins and especially WordPress core up to date. Plugins such as Google Authenticator and Limit Login Attempts can give you that little extra protection.

The Ferrari Analogy

Sometimes people try hide the fact that they’re running WordPress because they’re afraid other humans will spot that and think they’re “unprofessional” or cheap. Well WordPress is the most professional content management system known to human kind, trusted by some of the largest companies worldwide and although free and open source, certainly not cheap.

When you buy yourself a new Ferrari, do you remove the Ferrari logos before showing it to your friends? No. Although if you did, it would still be obvious.

To wrap that up — don’t hide the fact that you’re using WordPress. Use a strong password, keep it updated and drive it with pride. If you bought a premium “hide my WordPress” plugin, you should ask for a refund and buy something useful instead.

Using get_template_part within Shortcodes

The get_template_part function is one of the most useful things available to WordPress theme developers. Although mostly used in themes for public, get_template_part is often used in custom WordPress websites as an alternative to the PHP include or require.

When using get_template_part with the Shortcode API, there are two things you should always keep in mind:

  • get_template_part executes .php files which (most likely) generates output
  • shortcode callback functions are expected to return a string and not generate any output

So when calling get_template_part within a shortcode callback function, you’ll see that all the output generated by get_template_part is output before the post content, and not replaced inline.

The solution is to use PHP’s output buffering. Create a buffer in your shortcode callback before running get_template_part, clear the buffer and return the content right after. Here’s a quick example with an ads shortcode, which can insert your theme’s ads.php file contents anywhere within a post or page:

function my_ads_shortcode( $attr ) {
    ob_start();
    get_template_part( 'ads' );
    return ob_get_clean();
}
add_shortcode( 'ads', 'my_ads_shortcode' );

The ob_get_clean() function stops buffering and returns whatever was output to the buffer after ob_start(). The same approach could be used with other functions and statement that generate output, such as include and require.

Tip: wp_cron() runs during init

Pro tip: wp_cron() runs during the init action at the default priority, i.e. 10. If you’d like things to be available during your cron tasks, make sure you initialize them earlier: the init action at priority 9 and less, or other actions that run before init — beware of these, since other things might not be available at that time.

Also, Core Control is a good plugin to test and debug cron tasks.