2

I need a list of every shortcode inside the content. Is there any way to list them?

This is what I need:

$str = '[term value="Value" id="600"][term value="Term" id="609"]';

So every shortcode should be inside the $str.

I found a code snippet to check if there is a shortcode. But how can I display them all?

$content = 'This is some text, (perhaps pulled via $post->post_content). It has a [gallery] shortcode.';

if( has_shortcode( $content, 'gallery' ) ) {
    // The content has a [gallery] short code, so this check returned true.

}

3 Answers 3

4

Here's one way:

You can look at has_shortcode() and find the parsing there:

preg_match_all( 
    '/' . get_shortcode_regex() . '/', 
    $content, 
    $matches, 
    PREG_SET_ORDER
);

using the get_shortcode_regex() function for the regex pattern.

For non empty matches, you can then loop through them and collect the full shortcode matches with:

$shortcodes = [];
foreach( $matches as $shortcode ) {
    $shortcodes[] = $shortcode[0];
}

Finally you format the output to your needs, e.g.:

echo join( '', $shortcodes );

PS: It can be handy to wrap this into your custom function.

8
  • ps: it might be good to make sure a bracket exists in the content, e.g. with a simple strpos check, before parsing (just as in has_shortcode() ).
    – birgire
    Commented Jun 18, 2019 at 14:45
  • It works well if $content is get_the_content() but not if it's a custom field like get_sub_field("textfield")?!
    – Cray
    Commented Jun 18, 2019 at 14:46
  • It should work for all content that contains shortcodes. @Cray
    – birgire
    Commented Jun 18, 2019 at 14:47
  • 1
    ah, I guess the shortcode is already processed. If I echo get_the_content, it shows me the shorcode with [ ]. If I echo get_sub_field("textfield"), it shows only the result?!
    – Cray
    Commented Jun 18, 2019 at 14:54
  • 1
    It works when I use the field like this: get_sub_field("textfield", false, false);
    – Cray
    Commented Jun 18, 2019 at 14:56
2

If you only need the Shortcodes without the attributes, you can use this function:

function get_used_shortcodes( $content) {
    global $shortcode_tags;
    if ( false === strpos( $content, '[' ) ) {
        return array();
    }
    if ( empty( $shortcode_tags ) || ! is_array( $shortcode_tags ) ) {
        return array();
    }
    // Find all registered tag names in $content.
    preg_match_all( '@\[([^<>&/\[\]\x00-\x20=]++)@', $content, $matches );
    $tagnames = array_intersect( array_keys( $shortcode_tags ), $matches[1] );
    return $tagnames;
}

You will get an array of all shortcodes, that are used within the content you give it.

1
  • Thanks! But I need the attributes
    – Cray
    Commented Jun 18, 2019 at 14:28
1

Love @birgire's accepted answer, but a limitation of it is that any nested shortcodes are missed. You can overcome this by creating a simple walker:

function all_shortcodes($content) {
    $return = array();

    preg_match_all(
        '/' . get_shortcode_regex() . '/',
        $content,
        $shortcodes,
        PREG_SET_ORDER
    );

    if (!empty($shortcodes)) {
        foreach ($shortcodes as $shortcode) {
            $return[] = $shortcode;
            $return = array_merge($return, all_shortcodes($shortcode[5]));
        }
    }
    return $return;
}

$shortcodes_including_nested = all_shortcodes($post_content);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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