Getting the count of a shortcode that is nested

Here is very, very rough code that should get you started:

add_shortcode('outer_shortcode',function($attts,$content){return 1;});
add_shortcode('inner_code',function($attts,$content){return 1;});
$str="[outer_shortcode][inner_code url="#" title="Hello"][inner_code url="#2" title="Hello2"][/outer_shortcode]";
$reg = get_shortcode_regex();
preg_match_all('~'.$reg.'~',$str,$matches);
var_dump($matches);
preg_match_all('~'.$reg.'~',$matches[5][0],$matches2);
var_dump($matches2);

What is happening is that you are parsing the string which matches and “pulls apart” the outer shortcode. You then need to parse that shortcode’s content (array element 5) to parse the two inner shortcodes. count($matches[0][0]) should be 2. Simple is principle but there are a lot of ways it could go wrong. You’d want to do a lot of error checking and may want to iterate over the arrays rather than assuming the first match, $matches[5][0], as I did.

If you look at the source for get_shortcode_regex you can see what the different parts of that complicated array mean:

199  * 1 - An extra [ to allow for escaping shortcodes with double [[]]
200  * 2 - The shortcode name
201  * 3 - The shortcode argument list
202  * 4 - The self closing /
203  * 5 - The content of a shortcode when it wraps some content.
204  * 6 - An extra ] to allow for escaping shortcodes with double [[]]

If you are doing what I think you are doing, you probably want something like this:

add_shortcode(
  'outer_shortcode',
  function($atts,$content){
    $reg = get_shortcode_regex();
    preg_match_all('~'.$reg.'~',$content,$matches);
    echo count($matches[0]);
    return do_shortcode($content);
  }
);

add_shortcode(
  'inner_code',
  function($atts,$content){
    $the_stuff="<li>";     
      $the_stuff .= '<a href="' .$atts['url']. '" rel="external">'.$atts['title'].'</a>';
    $the_stuff .= '</li>';
    return $the_stuff;
  }
);

// now test it
$str="[outer_shortcode][inner_code url="#" title="Hello"][inner_code url="#2" title="Hello2"][/outer_shortcode]";
echo do_shortcode($str);

I think you can fill in the rest of the markup.

Leave a Comment