There’s a hidden gem available in WordPress 3.6 that I’m excited about, and that is the shortcode_atts_{$shortcode} filter. It will allow developers to filter a shortcode by passing in new shortcode parameters, and even override existing ones. You can read more about it in this post by Mark Jaquith.

Taking advantage of shortcode_atts_{$shortcode} in a plugin

EDD Featured Downloads is a plugin I wrote for Easy Digital Downloads that allows you to display your featured downloads via a [[edd_featured_downloads]] shortcode.

It’s always bugged me that I had to copy the entire [[downloads]] shortcode from the core Easy Digital Downloads plugin, just to do a simple query to retrieve the correct posts.

Each time EDD was updated, I’d have to check my plugin and make sure that it matched EDD’s plugin for consistency. I even left myself a comment in the code, reminding myself why I created the shortcode in the first place:

/**
* Featured Downloads Shortcode
* Created a new shortcode as filtering the shortcode atts is not possible yet
* https://core.trac.wordpress.org/ticket/15155
* @since 1.0
*/

Shortcodes must include the new parameter to be filterable

One thing to note is that the shortcode you are filtering must have the new parameter included as the 3rd parameter in the shortcode_atts array. This will be the {$shortcode} in the filter name. WordPress 3.6’s core shortcodes (gallery etc) will have this new parameter added when it is released.

In the spirit of ditching my plugin’s shortcode, I submitted a minor patch to Easy Digital Downloads that will appear in v1.7.2 (At the time of writing, EDD is still on v1.7.1).

Here’s what that 3rd parameter looks like in the shortcode_atts array:

extract( shortcode_atts( array(
// an array of the shortcode's default options
), $atts, 'downloads' ) // the new 'downloads' parameter which will allow filtering
);

How to use the shortcode_atts_{$shortcode} filter

Now that the shortcode is filterable, we can build our filter. Going by the example above, the filter’s name would be:

shortcode_atts_downloads

Filtering the shortcode

The following code adds a new “featured” parameter to the [[downloads]] shortcode in Easy Digital Downloads.

function edd_fd_filter_downloads_shortcode( $out, $pairs, $atts ) {
    if ( isset( $atts['featured'] ) && 'yes' === $atts['featured'] ) {
        $out['featured'] = 'yes';
    }
    return $out;
}
add_filter( 'shortcode_atts_downloads', 'edd_fd_filter_downloads_shortcode', 10, 3 );

My EDD Featured Downloads plugin can now use EDD’s default downloads shortcode like this:

[[downloads featured="yes"]]

Now that we’ve added the new shortcode parameter, we need to do something with it. I want my plugin to filter the download query to show only posts with the edd_feature_download meta key, but only if featured is set to yes. Here we’re relying on a filter already available in the EDD downloads shortcode called edd_downloads_query.

function edd_fd_filter_downloads_query( $query, $atts ) {
    if( isset( $atts['featured'] ) && 'yes' == $atts['featured'] ) {
        $query['meta_key'] = 'edd_feature_download';
    }

    return $query;
}
add_filter( 'edd_downloads_query', 'edd_fd_filter_downloads_query', 10, 2 );

The end result

The next version of my EDD Featured Downloads plugin will rely on both EDD 1.7.2+ and WP 3.6+ but I’ve managed to replace just over 160 lines of code with the two simple filters you see above.

This drastically reduces code, plugin maintenance as well as future-proofing it against future updates within the Easy Digital Downloads plugin.

7 comments

  1. Great post!

    What should you do for the mass of wordpress users who aren’t using 3.6 and above?

    Will this fail gracefully or do we need to setup other measures?

    Thanks,
    David

    1. You can provide a standard shortcode for users that aren’t on WP 3.6 yet. That’s what I’ve done, and when I’m confident that enough users are using 3.6 I’ll strip the old shortcode out. In my testing it fails gracefully, ie the query just ignores it. No reason why you couldn’t start using it now.

  2. Great article ! And you do use WordPress coding standards. This gives me the opportunity to use this article as a reference for my students when I teach WordPress programming.

    Thanks !

    Christiane Lagacé
    christianelagace.com

  3. How can a query be filtered with more than one attribute. For instance
    [downloads featured=”yes” published=”yes”]

Comments are closed.