Ensuring your Wordpress filter affects text generated by a shortcode

Date: Tue Oct 27 2015 Wordpress
wordpress-logo-stacked-rgb.pngSuppose you've developed a Wordpress plugin to expand a shortcode. That's easy enough, the Shortcodes API is straightforward enough and it's pretty simple to do. In my case I've just updated the External & Affiliate Links Processor to handle adding affiliate ID codes to links -- and at the same time I've written a new Wordpress plugin implementing a shortcode that adds links to the content. The problem was that affiliate-able links generated by the shortcode did not get affiliate ID codes added. Instead the links remained as they were, unaffiliated, when my whole purpose for both these changes was to use the shortcode to generate affiliated links.

Yesterday I spent a long time researching how to ensure a filter (added with the Wordpress add_filter function) is run after the shortcodes are expanded.

That is, the behavior is that the filter in the External & Affiliate Links Processor is run before the shortcodes are expanded. If the shortcodes had been expanded, the filter would have found the links and added affiliate codes to them.

The key is a teensy tiny little note in the Shortcodes API documentation. Specifically:

do_shortcode() is registered as a default filter on 'the_content' with a priority of 11.

The function do_shortcode is what causes shortcodes to be expanded. This statement says this function is registered as a the_content filter. The filter in External & Affiliate Links Processor is also registered as a the_content filter. Therefore -- a key question is the order of execution of functions registered as the_content filters.

Turns out the execution order is determined by the priority. Read the add_filter documentation and you see this documentation

$priority (integer) (optional) Used to specify the order in which the functions associated with a particular action are executed. Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the filter. Default: 10

Therefore in External & Affiliate Links Processor when I called add_filter and did not specify a priority, the priority defaulted to 10. Meaning that the External & Affiliate Links Processor filter ran BEFORE the shortcodes, giving me the behavior observed.

Fixing this was simple, change the priority:

// Add this filter with low priority so it runs after
// other filters, specifically shortcodes which might
// expand to include links.
add_filter('the_content', 'dh_nf_urlparse2', 99);