DO NOT use do_shortcode() to run a shortcode!
If you have to ask yourself “why?” when reading that, then this post is for you!
This is one of those topics that doesn’t just affect WP-Members – it’s all WP development, and it falls under the topic of best practices for WP development. It’s something that I see a lot of. I’m certain the reason for that is (1) it’s easy, and (2) a lot of WP development for customizing a site is made from code snippets cobbled together from looking up how to solve certain problems on the Internet. So what ends up happening is developers and non-developers alike end up copying bad practices from other developers.
(Note: I’ve written about this in other places around the Internet. One of those is an answer to a question on the StackExchange WordPress group.)
Why is it bad?
What’s so bad about it? All I want to do is run a shortcode in a section that I have some PHP code. That way I can get the shortcode results outside of the page/post content and use it in my [header|sidebar|footer|misc].
So here’s the problem.
First, do_shortcode() runs a fairly extensive regex (regular expression), and in so doing, it has to go through every single shortcode that exists on your site. That’s all WP defaults and any additional shortcodes that exist in your theme or active plugins (or also in custom code snippets). In essence, it has to check the content for every possible shortcode and every possible shortcode attribute all before getting to the callback function for the specific shortcode being requested.
That can be a big chunk to process – all to get your single instance of a specific shortcode.
OK. I’m sold. What I can I do instead?
Hopefully, my very simple explanation has you convinced that you should seek an alternative and avoid using do_shortcode(). Better still, you’ve made a personal commitment to yourself to never use it. But what are the alternatives?
I’m glad you asked 😉
Use a direct function
First, since you’re working in PHP anyway, look for appropriate functions to be used directly. Sometimes a shortcode is just a very simple way to provide a non-PHP wrapper to another function.
Here’s an example from WP-Members. I see a lot of people use the following:
echo do_shortcode( '[wpmem_field some_field]' );
Ultimately, the wpmem_field shortcode is to display a piece of user data – all of these are either WP user fields (from the wp_user table) or user meta fields (from the wp_usermeta) table. If they are custom fields (fields you created yourself), they are user meta. Any user meta field can be retrieved with the WP function get_user_meta().
So instead of running the full shortcode regex to get a custom user field, you could get the same result with a direct function that already exists in WP:
echo get_user_meta( get_current_user_id(), 'some_field', true );
We could run through other examples of this, but in WP-Members and in general, but then this article would get fairly long and we wouldn’t get to the other possibilities.
Find the callback
Another possibility is to just look for the shortcode’s callback function. This is the function that is run for the shortcode. Every shortcode in WP is added the same way – by using add_shortcode().
add_shortcode() has two arguments. First, the name of the shortcode. The second is the function that is run when that shortcode is implemented. Here’s what that looks like for a shortcode called [my_cool_shortcode]:
add_shortcode( 'my_cool_shortcode', 'function_to_run' );
So if the previous direct function method wasn’t useable (or maybe you don’t know the appropriate function to use), finding the shortcode’s callback function an using it directly is a A+ way to go. And most of the time, you don’t really need to do anything other than find the callback.
How do you do that?
If the shortcode comes from a plugin (like WP-Members), search the files for “add_shortcode”. Anywhere that is used will be defining a shortcode. Find the callback function for the shortcode you are using and you can call that directly.
So continuing with our [my_cool_shortcode] example above, instead of doing this:
echo do_shortcode( '[my_cool_shortcode]' ); // BAD!!
this would be better:
echo function_to_run(); // Awesome!!
Note that you may need to look at any arguments that are passed. I’ll probably have to look at some examples and update this article if the question comes up.
There’s one other possibility – and in my opinion, I’ve saved the best for last.
Custom callback utility
What if the callback happens to be inside an object class? (WP-Members shortcodes are all in an object specifically for the shortcodes.) Then it may be tricky to be able to access the callback directly, since you need the object to be invoked.
Well, lucky for all of us, J.D. Grimes wrote a usable utility on his codesymphony.co site. This is just a utility function that allows you to call ANY shortcode along with an array of its attributes and get the direct result without the messy regex of do_shortcode().
And the best part about this utility is that you don’t have to search through the code to find the shortcode’s callback. And you don’t have to already know the existing WP functions that you might use instead. All you need to know is the shortcode tag and the attributes. In other words, you can use it exactly like you would do_shortcode().
You can implement JD’s utility directly in your application, OR, if you’re using WP-Members, there is a utility in the plugin’s API that you can use (it’s JD’s utility, and noted as such, just with a “wpmem_” stem on the function name – you can use it for any shortcodes – not just WP-Members’) – wpmem_do_shortcode().
Here’s an example of that from the first example I mentioned above using the [wpmem_field] shortcode:
echo wpmem_do_shortcode( 'wpmem_field', array( 'some_field' ) );
Well, I hope I’ve convinced you to never use do_shortcode() and that you will now seek out better alternatives to get the same result. Hopefully, you’ll find the options just as easy to implement – especially if you use the shortcode callback utility wpmem_do_shortcode() instead.