When are Shortcode Attributes Available in Template

I need access to the shortcode attributes before the content (and
it’s shortcode) is processed…. in the first “is $atts available
here” after the add_shortcode

In that case, you can manually parse the shortcode and retrieve its attributes (if any) like so, which uses get_shortcode_regex() and shortcode_parse_atts():

$content="before blah2 [foo bar="baz" num="123"] after";

preg_match( "https://wordpress.stackexchange.com/" . get_shortcode_regex() . '/s', $content, $matches );
$atts = isset( $matches[3] ) ? shortcode_parse_atts( $matches[3] ) : '';

var_dump( $atts );
/* Output:
array(2) {
  ["bar"]=>
  string(3) "baz"
  ["num"]=>
  string(3) "123"
}
*/
  • Note that the above will only retrieve the attributes of the first shortcode found in $content. So use that code only if you’re sure the content would never contain any other shortcodes..

Or you can try this function which parses all shortcodes of a certain tag and return an array of attributes:

function my_shortcode_parse_atts( $text, $tag ) {
    $all_atts = array();

    preg_match_all( "https://wordpress.stackexchange.com/" . get_shortcode_regex() . '/s', $text, $matches );

    // If the shortcode ($tag) is found in $text, we parse the attributes.
    if ( isset( $matches[3] ) ) {
        // $matches[3] is the attributes string like ' bar="baz" num="123"'
        foreach ( $matches[3] as $i => $s ) {
            if ( $tag === $matches[2][ $i ] ) {
                $all_atts[] = shortcode_parse_atts( $s );
            }
        }
    }

    return $all_atts;
}
  • Sample usage and output:

    $content="before [foo] blah2 [foo bar="baz" num="123"] after";
    $all_atts = my_shortcode_parse_atts( $content, 'foo' );
    
    var_dump( $all_atts );
    /* Output:
    array(2) {
      [0]=>
      string(0) ""
      [1]=>
      array(2) {
        ["bar"]=>
        string(3) "baz"
        ["num"]=>
        string(3) "123"
      }
    }
    */
    

    Note: In the above $content, there are 2 instances of the foo shortcode; one without any attributes, and the other with 2 attributes.

Also, I used a dummy text, so it’s up to you on how to get the actual $content‘s value..