regex - Extract attribute values from every shortcode in post

admin2025-06-02  1

I have multiple shortcodes in the post:

[section title="first"]
[section title="second"]
[section title="third"]

I want to extract all title values (i.e first, second, third) from external function, that's how I'm trying to do:

$pattern = get_shortcode_regex();
preg_match('/'.$pattern.'/s', $post->post_content, $matches);
    if (is_array($matches) && $matches[2] == 'section') {
        $attribureStr = str_replace (" ", "&", trim ($matches[3]));
        $attribureStr = str_replace ('"', '', $attributeStr);
        $attributes = wp_parse_args ($attributeStr);
        echo $attributes["title"];
    }

The problem is that code extracts value only from first shortcode. How to get it working for every shortcode in the post?

I have multiple shortcodes in the post:

[section title="first"]
[section title="second"]
[section title="third"]

I want to extract all title values (i.e first, second, third) from external function, that's how I'm trying to do:

$pattern = get_shortcode_regex();
preg_match('/'.$pattern.'/s', $post->post_content, $matches);
    if (is_array($matches) && $matches[2] == 'section') {
        $attribureStr = str_replace (" ", "&", trim ($matches[3]));
        $attribureStr = str_replace ('"', '', $attributeStr);
        $attributes = wp_parse_args ($attributeStr);
        echo $attributes["title"];
    }

The problem is that code extracts value only from first shortcode. How to get it working for every shortcode in the post?

Share Improve this question asked Dec 14, 2014 at 19:57 LionheartLionheart 431 silver badge3 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 10

Method #1

If available, I would use the:

shortcode_atts_{$shortcode}

filter to collect the attributes of a given shortcode.

Example:

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

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
            [link] => 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( '/' . 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"][/caption]
';
$out = wpse172275_get_all_attributes( 'gallery', $text );
print_r( $out );

with the output:

Array
(
    [0] => 
    [1] => Array
        (
            [ids] => 1,2
            [link] => file
        )

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

)

I hope you can modify this to your needs.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1748815445a313952.html

最新回复(0)