Extract attribute values from every shortcode in post

Method #1

If available, I would use the:

shortcode_atts_{$shortcode}

filter to collect the attributes of a given shortcode.

Example:

$text="
    
    
    
    
";

if( class_exists( 'WPSE_CollectShortcodeAttributes' ) )
{
    $o = new WPSE_CollectShortcodeAttributes;
    $out = $o->init( $shortcode="gallery", $text )->get_attributes();
    print_r( $out );
}

where our helper class is defined as:

class WPSE_CollectShortcodeAttributes
{
    private $text="";
    private $shortcode="";
    private $atts      = array();

    public function init( $shortcode="", $text="" )
    {
        $this->shortcode = esc_attr( $shortcode );
        if( shortcode_exists( $this->shortcode ) 
            && has_shortcode( $text, $this->shortcode ) 
        )
        {
            add_filter( "shortcode_atts_{$this->shortcode}", 
                array( $this, 'collect' ), 10, 3 );
            $this->text = do_shortcode( $text );
            remove_filter( "shortcode_atts_{$this->shortcode}", 
                array( $this, 'collect' ), 10 );
        }
        return $this;
    }

    public function collect( $out, $pair, $atts )
    {
        $this->atts[] = $atts;
        return $out;
    }

    public function get_attributes()
    {
        return $this->atts;
    }
}

The output of our example is:

Array
(
    [0] => Array
        (
            [0] => 
        )

    [1] => Array
        (
            [ids] => 1,2
            https://wordpress.stackexchange.com/questions/172275/extract-attribute-values-from-every-shortcode-in-post => file
            [orderby] => post__in
            [include] => 1,2
        )

    [2] => Array
        (
            [ids] => 3
            [orderby] => post__in
            [include] => 3
        )

)

so for the gallery shortcode, we get some extra attributes as well.

Method #2

But not all shortcodes support the above filter. In that case you could try the following:

/**
 * Grab all attributes for a given shortcode in a text
 *
 * @uses get_shortcode_regex()
 * @uses shortcode_parse_atts()
 * @param  string $tag   Shortcode tag
 * @param  string $text  Text containing shortcodes
 * @return array  $out   Array of attributes
 */

function wpse172275_get_all_attributes( $tag, $text )
{
    preg_match_all( "https://wordpress.stackexchange.com/" . get_shortcode_regex() . '/s', $text, $matches );
    $out = array();
    if( isset( $matches[2] ) )
    {
        foreach( (array) $matches[2] as $key => $value )
        {
            if( $tag === $value )
                $out[] = shortcode_parse_atts( $matches[3][$key] );  
        }
    }
    return $out;
}

Example:

$text="
    [gallery]
    [gallery ids="1,2" link="file"]
    [gallery ids="3"]
    [caption id="attachment_6" align="alignright" width="300"]
";
$out = wpse172275_get_all_attributes( 'gallery', $text );
print_r( $out );

with the output:

Array
(
    [0] => 
    [1] => Array
        (
            [ids] => 1,2
            https://wordpress.stackexchange.com/questions/172275/extract-attribute-values-from-every-shortcode-in-post => file
        )

    [2] => Array
        (
            [ids] => 3
        )

)

I hope you can modify this to your needs.

Leave a Comment