Let's say I have nested shortcode where the outmost shortcode is just HTML but the inner one is the one who displays the data.

[outer_shortcode][inner_code url="#" title="Hello"][/outer_shortcode]

In this case, the count of inner items is one. In the following one:

[outer_shortcode][inner_code url="#" title="Hello"][inner_code url="#2" title="Hello2"][/outer_shortcode]

The inner count is two.

How can I determine this on the functions that I work with?

I currently have (outer shortcode that calls the inner):

return '<section id="recipes"><nav><ul>'.do_shortcode($content).'</ul></nav></section>';

And as inner:

        $the_stuff .= '<li>';     
        $the_stuff .= '<a href="' .$url. '" rel="external">'.$title.'</a>';
        $the_stuff .= '</li>';

        return $the_stuff;

That's what I want. To count the list items. How can I accomplish this?

1 Answer 1


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();

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:

    $reg = get_shortcode_regex();
    echo count($matches[0]);
    return do_shortcode($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.

  • This is a tad over my paygrade.... :s. I should add this on which of the functions for the shortcode? Outer or inner? Commented Oct 1, 2013 at 2:37
  • @MarcoBerrocal: There is code for both shortcodes there.
    – s_ha_dum
    Commented Nov 7, 2013 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.