How to extract WordPress shortcode attributes from post content

Viewed 14932

In my posts on WordPress I have an unknown number of shortcodes of type my_player that I created and correctly added hooks to. I was wondering if there is some type of WordPress function you can pass your content to and shortcode name, and it could give you an array of matched shortcodes with their attributes indexed by attribute name. Something like my code below...

$matches = get_shortcode_matches($content, "my_player");

for($i = 0; $i < sizeof($matches); $i++)
{
    $title = $matches[$i]['title'];
    $mp3 = $matches[$i]['mp3'];
    $soundcloud = $matches[$i]['soundcloud'];
}

I know that when you create the hook for the shortcodes using the add_shortcode() function you can use these indexed values like I have above, but I need to have a function that can access them later and outside of the loop. Does WordPress have any such function?

4 Answers

I couldn't find anything either, so I created my own. First I created the following function to pull the attributes out of a shortcode properly:

function eri_shortcode_parse_atts( $shortcode ) {
    // Store the shortcode attributes in an array here
    $attributes = [];

    // Get all attributes
    if (preg_match_all('/\w+\=\".*?\"/', $shortcode, $key_value_pairs)) {

        // Now split up the key value pairs
        foreach($key_value_pairs[0] as $kvp) {
            $kvp = str_replace('"', '', $kvp);
            $pair = explode('=', $kvp);
            $attributes[$pair[0]] = $pair[1];
        }
    }

    // Return the array
    return $attributes;
}

Then I created the following function to search the page for all iterations of the shortcode:

function eri_get_shortcode_on_page( $post_id, $shortcode ) {
    // Get the post content once
    $content = get_the_content( null, false, $post_id );
    // $content = apply_filters( 'the_content', get_the_content( null, false, $post_id ) ); // Alternative if get_the_content() doesn't work for whatever reason

    // Double check that there is content
    if ($content) {

        // Shortcode regex
        $shortcode_regex = '/\['.$shortcode.'\s.*?]/';

        // Get all the shortcodes from the page
        if (preg_match_all($shortcode_regex, $content, $shortcodes)){
            
            // Store them here
            $final_array = [];
            
            // Extract the attributes from the shortcode
            foreach ($shortcodes[0] as $s) {
                $attributes = eri_shortcode_parse_atts( $s );

                // The return the post
                $final_array[] = $attributes;
            }

            // Return the array
            $results = $final_array;

        // Otherwise return an empty array if none are found
        } else {
            $results = [];
        }

        // Return it
        return $results;
    } else {
        return false;
    }
}
Related