Following scenario: I'm building a theme framework which I want to reuse in various themes of mine. In this framework there is a collection of many shortcodes. For exemplary illustration of my problem, let's say one of these shortcodes fetches the recent posts ([recent_posts]) and displays them.

Now, maybe I want sometimes to show the post titles above and sometimes below a post thumb image, sometimes I want to show the post date and sometimes not. In short I need some (as handy as possible) way to to change the output code while keeping the shortcode logic itself the same.

Please have a look at the exact point of the concretely described use case: https://github.com/dotwired/Inferno/blob/master/inc/class-shortcodes.php#L591 (the code I want to be flexible starts at the marked line 591 and ends at line 595). I figured out following ways to do so:

  • apply_filters():
    • pro: feels like doing "WordPress way" ...
    • contra: ...but I feel pretty uncomfortable with having too many filters added then (with possibly a large amount of passed arguments, e.g. in case that the post thumb is generated by another class accepting arguments)
  • a checking for a template file via file_exists() and then including:
    • pro: easy and functional
    • contra: would require to add one file for each shortcode where I would want to have the HTML flexible, and the files should be all outside the framework directory. Also, this is surely not the "WordPress way"
  • a template string:
    • pro: No extra files or modular code needed, just specifying the HTML in the shortcode itself
    • contra: easily would get too complicated in shortcode logic and especially in usability.

The first problem you didn’t even mention is: you are putting shortcodes into a theme. Shortcodes are pure plugin territory, because they are changing post content and must survive a theme switch.

Once you fixed that and moved the shortcodes to a plugin named inferno_shortcodes, the rest is easy:

In your plugin ask for theme support:

$default_templates = array(
    'stacked'       => 'stacked.php',
    'one_half'      => 'one_half.php',
    'one_half_last' => 'one_half_last.php',
$theme_templates = (array) get_theme_support( 'inferno_shortcodes' );

$templates = array();

foreach ( $default_templates as $shortcode => $file )
    if ( isset ( $theme_templates[ $shortcode ] ) )
        $templates[ $shortcode ] = locate_template( $theme_templates[ $shortcode ] );
        $templates[ $shortcode ] = plugin_dir_path( __FILE__ ) . "templates/$file";

Now any theme can provide templates for all or some shortcodes with …

    array (
        'stacked'       => 'inferno-shortcodes/stacked.php',
        'one_half'      => 'inferno-shortcodes/one_half.php',
        'one_half_last' => 'inferno-shortcodes/one_half_last.php',

… and in your plugin you just include the template to render the output.

  • I originally came from a plugin and decided that I want to have the shortcodes in the theme. So basically You're favoring template files. :) May 24 '13 at 9:34

I develop and utilize shortcodes too, and I found passing options as attributes works well. For example, your shortcodes can accept extra parameters such as:

[recent_posts thumb="true" date="false"]

Then in your shortcodes, you just need to write conditionals to check for the attributes.

The official documentation describes how to retrieve the attributes as option and even set defaults for most common setup.


I also create different "modes" so that I'm turning on/off various sets of conditionals based on the typical usage. Such as [recent_posts mode="widget"] will turn off lot of options to keep the display very minimal.

  • That would need many attributes, You cannot have full control over output with attributes only... May 24 '13 at 9:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.