Find depth of nested shortcodes
-
Hi there,
I’m trying to find a way to write a PHP function using recursion that finds the maximum depth of short codes inside other short codes,
Any ideas ? or a lead on how to do that ?
-
OK I might have an idea here, mind you I’m not a PHP programmer so be gentle here…
I think this would work to find the maximum depth of an array, now how can I insert my shortcodes into that array ? thanks….//finds the maximum depth in an array <?php function array_depth(array $array) { $max_depth = 1; foreach ($array as $value) { if (is_array($value)) { $depth = array_depth($value) + 1; if ($depth > $max_depth) { $max_depth = $depth; } } } return $max_depth; }Have came across this one for finding an array’s depth –
Now is there a built WordPress functions that I can insert into that with an array of shortcodes ?
<?php function ArrayDepth($Array,$DepthCount=-1) { // Find maximum depth of an array // Usage: int ArrayDepth( array $array ) // returns integer with max depth // if Array is a string or an empty array it will return 0 $DepthArray=array(0); $DepthCount++; $Depth = 0; if (is_array($Array)) foreach ($Array as $Key => $Value) { $DepthArray[]=ArrayDepth($Value,$DepthCount); } else return $DepthCount; return max($DepthCount,max($DepthArray)); } ?>[Please post code & markup between backticks or use the code button. Your posted code may now have been permanently damaged by the forum’s parser.]
Any idea ?
Thanks
I have gotten to hear then – now the question is – how do I connect these 2 functions…
<?php function ArrayDepth($Array,$DepthCount=-1) { $DepthArray=array(0); $DepthCount++; $Depth = 0; if (is_array($Array)) foreach ($Array as $Key => $Value) { $DepthArray[]=ArrayDepth($Value,$DepthCount); } else return $DepthCount; return max($DepthCount,max($DepthArray)); } ?> <?php function do_shortcode($content) { global $shortcode_tags; if (empty($shortcode_tags) || !is_array($shortcode_tags)) return $content; $pattern = get_shortcode_regex(); return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content ); } ?>Have made some progress here –
<?php add_action( ‘init’, ‘AddShortcodes’ ); function AddShortcodes() { add_shortcode( ‘test’, ‘test’ ); add_shortcode( ‘test’, ‘test’ ); } add_filter( ‘the_content’, ‘findDepth’, 0 ); function findDepth( $content ) { /* Create an array of all the shortcode tags. */ $shortcode_tags = array( ‘test’, ‘test’, ); } function array_depth($array) { $max_depth = 1; foreach ($array as $value) { if (is_array($value)) { $depth = array_depth($value) + 1; if ($depth > $max_depth) { $max_depth = $depth; } } } return $max_depth; } ?>Still won’t work though…
AmitHi Amit,
I don’t think a short code depth routine modeled after an array routine is the right approach. Arrays are clearly structured, it’s easy to identify which elements have child arrays and which do not. Not so with shortcodes. Nested shortcodes are more like nested HTML tags, you cannot know if there are children without parsing through the entire content. You cannot even know what shortcode tag the content following a tag belongs to until a closing tag is found.
Much as you might do with HTML tag depth, you could increment a counter for each opening tag and decrement for each closing tag. After each increment, the value is compared to a maximum depth register and the value is copied to the register if greater than the current value. That works for tags with closing tags. Tags without closing tags complicate things, but a solution probably exists. The counter concept is as far as I got on this subject, I hope it helps some in your quest.
-bc
Thanks! it actually does.
I was just looking at the get_shortcode_regex() – http://wordpress.stackexchange.com/questions/4638/nested-shortcode-detection/4688#4688
I guess I get get the regular expression and then do what you suggest with a counter increment ,do you have any example maybe of something similar for HTML tags ?
Cheers!
AmitHey did you mean something like that maybe ?
$elements = parse($html); if (count($elements) > 0) { echo "Elements found: <b>".count($elements)."</b><br />"; foreach ($elements as $element) { echo "<p>Tpl node: <pre>".htmlentities($element->node)."</pre> Tagname: <tt>".$element->tagname."</tt><br /> Attributes: <tt>".$element->attributes."</tt><br /> Omittag: <tt>".($element->omittag ? 'true' : 'false')."</tt><br /> Inner HTML: <pre>".htmlentities($element->inner_html)."</pre></p>"; } } ?>I think this might be closer though not working yet :
<?php function do_shortcode($content) { global $shortcode_tags; if (empty($shortcode_tags) || !is_array($shortcode_tags)) return $content; $pattern = get_shortcode_regex(); return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content ); $elements = parse($pattern); if (count($elements) > 0) { echo "Shortcode found: <b>".count($elements)."</b><br />"; foreach ($elements as $element) { echo "<p>Tpl node: <pre>".$element($element->node)."</pre>"; } } } ?>Can you take a look please ?
Sorry, I don’t even see where you’re going with this code. You tagged onto the WP do_shortcode() which returns expanded content. One, I thought the goal was to determine the nesting depth, not expand shortcodes? Two, your added code may never be executed as the WP version returns when either there is a shortcode or there isn’t. Three, you should not redefine WP core functions (actually, you cannot redefine functions in PHP).
I don’t have any code to offer unfortunately, what I offered in my first post is really as much thought that I’ve put into this. The get_shortcode_regex() was a good find, it’ll put all the tags into a convenient array. You will need to examine the $matches array returned to determine how to make use of it. It may not help though if you cannot distinguish nested tags from non-nested or if the tag has content.
Determining those various states is key to determining the nesting level. The actual logic to do that and how it effects my counter idea escapes me when it comes to writing actual code. Thinking it is one thing, writing code to reflect that though is another. I’m willing to continue answering any specific questions that may arise, if I can, but I’m not able to help with general coding, sorry.
Hey,
Thanks!
Amit
The topic ‘Find depth of nested shortcodes’ is closed to new replies.