I apologize in advance for my lack of PHP/WP knowledge, and my wordiness in explaining what I'm looking for, but I've been trying to work out a solution for a couple of days now, and I'm just starting to wrap my head around filters and the loop.

Here's what I'd like to accomplish:

A shortcode for a plugin I'm using has an attribute tag "sched" that I would like to make essentially dynamic, changed to the current (custom)post's (custom)category slug. Here's an example of an existing shortcode that works well with the MSTW Schedules and Scoreboards plugin:

[mstw_schedule_table sched="v-football"]

My plan was to set the "sched" attribute's value to "sport" (on all posts) as a placeholder that would be replaced with the current post's "sport" custom category slug. I've set up all "sport" category slugs to correspond with the "sched" values used in the plugin, to ensure that the schedule table displayed on the current post is correct.

Note: All of these custom posts (set up as "team") should only have one "sport" category applied to them: I have set up "sport" categories as a dropdown meta box in admin, like this.

Also Note: I'd like the editable shortcode to be available within the custom post's content, so I can edit other attributes as needed for each post.

Here is what I've tried:

This is the closest I've gotten, but I know that I'm using the wrong filter, or otherwise calling the function at the wrong time. Note that I ran this code in the "single-team.php" file I created for my custom post type, before the loop. I'm aware it should probably be in functions.php or a separate plugin (please advise).

My inspiration:
do_shortcode_tag / get_the_terms

    add_filter( 'do_shortcode_tag', 'wpse_106269_do_shortcode_tag', 10, 4);
    function wpse_106269_do_shortcode_tag( $output, $tag, $attr, $m ) {

        if( $tag === 'mstw_schedule_table' ) {
            //* Do something useful
            if ($attr['sched'] === 'sport-slug') {

                // Get a list of tags and extract their names
                $sport = get_the_terms( get_the_ID(), 'sport' );
                if ( ! empty( $sport ) && ! is_wp_error( $sport ) ) {
                    $sport_slug = wp_list_pluck( $sport, 'slug' );

                    $attr['sched'] = $sport_slug[0];

                echo "<br>";

        return $output;

This outputs:

Array ( [sched] => sport-slug ) 
Array ( [sched] => v-football )

So I know I can change the value of the shortcode's $attr, but I don't know how to replace the original shortcode with the modified one, before it's parsed by the plugin.

I tried using the_content:

// Modify Content of a Post
add_filter('the_content', 'se24265_my_function');
function se24265_my_function( $content )
    $write = 'hello world'; 
    $new_content = $write . $content;

        $sport = get_the_terms( get_the_ID(), 'sport' );
        if ( ! empty( $sport ) && ! is_wp_error( $sport ) ) {
            $sport_slug = wp_list_pluck( $sport, 'slug' );

            str_replace("sport-slug", $sport_slug[0], $new_content);
        return $new_content; 
        // outputs hello world
        // outputs inital shortcode without modifications

I also thought about running the plugin's shortcode handler function (like this) with a modified argument, but I don't know how to access/modify that argument before it's interpreted out by the plugin.

I've also seen this example where the shortcode is generated within the custom post template...

// Making your custom string parses shortcode
$string = do_shortcode( $string );
// If your string has a custom filter, add its tag name in an applicable add_filter function
add_filter( 'my_string_filter_hook_tag_name', 'do_shortcode' );

... but I'd like to maintain the ability to edit / place the shortcode in different places within each custom post as needed, and I still don't know which filter hook to use (content_edit_pre ?)

Any help would be appreciated. Thanks.


For anyone who might stumble upon this, I've found a solution:

In my particular case, I'm using a single-[taxonomy].php template file, and was able to add the shortcode manually via the WordPress function do_shortcode() instead of modifying a shortcode within the post content.

Here's how I wrote it:

<?php echo do_shortcode( '[mstw_schedule_table sched="'.$sports_slug.'" ]' ); ?>

And here's how I got the $sports_slug to work for me. Previously in the file (outside the loop) :

// Get this post's sport taxonomy - https://wordpress.stackexchange.com/a/168862/127459
           $sports = get_the_terms($post->ID, 'sport');
           $sports_slug = '';
           if ($sports) { 

                foreach ($sports as $sport) {   
                    $sports_slug = $sport->slug;    

This code is slightly less complicated than what I used ( I needed to select only non-parent sport taxonomies ) but this simplified version may help someone else. These links helped me along the way:

Get custom category name from ID (Answer)


| improve this answer | |
  • You can also use the shortcode's callback directly or use the shortcode_atts_{shortcode} filter. – birgire Sep 27 '17 at 16:58
  • Thank you, @birgire - I'm still learning WP filters - this helps a lot for future reference. – Peter Arthur Sep 27 '17 at 18:46

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.