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 badges1 Answer
Reset to default 10Method #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.