WordPress.org

Ready to get started?Download WordPress

Forums

Nesting Shortcodes... Doesn't work as expected?? (8 posts)

  1. MGmirkin
    Member
    Posted 1 year ago #

    So, I'm trying to create a nested toggling system for expanding / collapsing a long text by sections and sub-sections.

    I've installed the Arconix Shortcodes (and a few others in the attempt).

    See:
    http://wordpress.org/support/topic/feature-req-nesting-toggles-nesting-accordions-specify-openclosed-on-load

    Basically, I want to do something like this:

    [toggle title="Guide Book on Topic X"]

    [toggle title="Preface"]Initially hidden, expandable Preface text[/toggle]

    [toggle title="Introduction"]Initially hidden, expandable Intro text[/toggle]

    ...

    [/toggle]

    In my surmise, the way this SHOULD work is via NESTING.

    That is, there is a PARENT toggle, and inside that there are two CHILD toggles.

    If the parent toggle is "closed," the child toggles are hidden (regardless whether they're "open" or "closed" at the time; PARENT toggle takes priority over CHILD toggles).

    If the PARENT toggle is "open", we can see the CHILD toggles and act upon them, to either open them, if "closed," or close them, if already "open."

    However, it seems, from other sources I've managed to Google after some painstaking attempts to fix this issue, that WordPress currently doesn't handle shortcode nesting properly, in general terms.

    In particular, the Codex seems to note here:

    http://codex.wordpress.org/Shortcode_API#Nested_Shortcodes

    This is a limitation of the context-free regexp parser used by do_shortcode() - it is very fast but does not count levels of nesting, so it can't match each opening tag with its correct closing tag in these cases.

    That feels like it's a problem, since this sort of thing SHOULD, one would think, be fairly easy to handle in some systematic sort of way.

    The WP core codebase coders seem to then want to pass off the problem onto the plugin coders, as if the codebase problem was somehow their problem:

    The shortcode parser correctly deals with nested shortcode macros, provided their handler functions support it by recursively calling do_shortcode():

    [tag-a]

    [tab-b]

    [tag-c]

    [/tag-b]

    [/tag-a]

    However the parser will fail if a shortcode macro is used to enclose another macro of the same name:

    [tag-a]

    [tag-a]
    [/tag-a]

    [/tag-a]

    (As an aside, there's a typo in the Codex entry, above. That should really say [tag-b] not [tab-b] in the first set of block quotes. Not that it matters to the overall argument here.)

    Should plugin coders really have to do a coding version of highwire gymnastics to "support" nesting? Isn't that something the core codebase should handle?

    I'm kind of disappointed this hasn't been "fixed." It feels a bit like folks kind of throwing up their hands and saying "not my problem, you solve it, ad hoc."

    My opinion is that the 2nd method is the correct method. Not the method requiring additional coding gymnastics to "band-aid over" the actual problem of core codebase insufficiency. Seems like a bit of unnecessary work offloaded onto plugin programmers just to avoid having to fix a single module in the core codebase that could/should have been written better? Am I wrong? Shouldn't it be fixed in one place rather than requiring oodles of extra lines of "workaround" code in the hundreds of plugins that could/should potentially be used in a "nested" manner?

    Ideally, one should be able to arbitrarily "nest" whatever one feels like, and it should *just work.* I mean the "nesting" logic feels like it should be pretty simple. "Nesting" is pretty much how HTML works, so I'm a bit confused why such a mature CMS as WordPress should have a "problem" with it. It sounds like the "regexp parser" mentioned in the Shortcodes entry in Codex is in some way insufficiently designed to handle the logic? But, nobody's taken the time to fix it or invent a better parser that actually handles this kind of nesting in a more systematic way that doesn't require coding "band-aids."

    If we could, y'know, get this kind of thing shored up in short order, that'd be great... I'm sure a great many page builders would be quite happy if this were the case. No? Then we wouldn't have to keep bugging our plugin makers about it or Googling all over the web or searching the Codex to figure out why something [one would think should be] intuitive... really isn't.

    Sorry if this has at all been brought up before (probably?)... If so, just add my voice to those voices who may have already called WP out on this problem. A systematic solution (rather than an ad hoc 'do it yourself' one or a 'complain to your plugin programmer' one) would be best, in my opinion. Feels like this should be one of those "working directly out of the box" features. It certainly feels like it would add a certain robustness to the project.

    I love shortcodes, and love them better when they function AS INTENDED out of the box without quirky ad hoc problems because some module is known to be insufficient and nobody has taken the time to burrow into the core codebase and fix it.

    Just the frustrations of someone fairly new to the project and thus with a "fresh" set of eyes. Pointing out a problem, albeit one that's probably "known," if seemingly also "neglected."

    Feels like if this problem with the core codebase were given some loving attention, it could probably be fixed relatively easily.

    I know, I know, "...says the non-programmer." But that's kind of the point, isn't it? I'm not a programmer, which is why I like preprogrammed CMS solutions like WordPress. It's precisely so I don't have to *be* a programmer, but rather I can be a 'designer.' I can leave the "programming" to the programmers. But on the other hand, there's a certain implicit expectation that the "programming" be sufficient for as robust an implementation as possible. In essence a black box whose internal function I don't need to *know*. So long as the internals work 'as-advertised' and don't break, I should simply be able to plug things in and play with them and not have to worry about "breakage."

    Right now, it feels like it's not a "black box" because there *is* apparent breakage, when I do things in the way they feel like they SHOULD be done, and the logic isn't there to handle it and something breaks and goes sideways, mucking up the works.

    I don't mean to sound negative. I'm really not, I LOVE WordPress so far... It's just, there's an apparent insufficiency/shortcoming in the core codebase here. It seems to be explicitly acknowledged in the Codex. The question is, I suppose: what can/will be done about it?

    Thx for your time!

    P.S. If anyone knows of an easily available somewhat "mature" plugin that in some way easily SUPPORTS nested accordion or toggle boxes, it would be very handy, right about now. But don't let that stop you from fixing the aforementioned shortcoming(s), too. Thx!

  2. keesiemeijer
    moderator
    Posted 1 year ago #

    I didn't read your whole post, but I think you can use nested shortcodes the way you want by renaming the shortcodes inside the enclosing shortcode "toggle" to "toggle_inside":

    [toggle title="Guide Book on Topic X"]
      [toggle_inside title="Preface"]Initially hidden, expandable Preface text[/toggle_inside]
      [toggle_inside title="Introduction"]Initially hidden, expandable Intro text[/toggle_inside]
    [/toggle]

    With this in your theme's functions.php:

    function toggle_inside( $atts, $content = null ) {
       extract( shortcode_atts( array(
          'title' => 'Toggle This',
          ), $atts ) );
          return do_shortcode('[toggle title="'.$title.'"]'.$content.'[/toggle]');
    }
    add_shortcode('toggle_inside','toggle_inside');

    btw:
    consider creating a child theme instead of editing your theme directly - if you upgrade the theme all your modifications will be lost.
    Or create your own plugin with the code for functions.php:
    http://wordpress.org/extend/plugins/pluginception/

  3. MGmirkin
    Member
    Posted 1 year ago #

    Hmm, so, question... If that's the case, if I wanted to have more than one level of nesting would I then have to create x number of "sub-shortcodes," one for each level of nesting, or could I alternate between strictly two shortcodes so long as neither is directly inside another copy of itself? I'm not a programmer, so I don't know the programming logic...

    So, for instance, could I do this (alternating back & forth):

    [tag-a]

    [tag-b]

    [tag-a]

    [tag-b]
    [/tag-b]

    [/tag-a]

    [/tag-b]

    [/tag-a]

    Or would I have to create a hundred shortcodes if I want a hundred levels of hierarchy (clearly nobody needs 100 levels of hierarchy, but you see my point, I'm sure)?

    [tag-a]

    [tag-b]

    [tag-c]

    [tag-d]
    [/tag-d]

    [/tag-c]

    [/tag-b]

    [/tag-a]

    Personally, I'd rather just see the core codebase issue fixed and not have to fiddle with ad hoc solutions, which was kind of the point of the ramble (sorry 'bout that). Seems like it's a "known issue" that nobody wants actually fix. And it feels like it would be better if the community fixed the core issue that leads to all the other problems, rather than suggesting ad hoc solutions to band-aid over the root problem, which seems to just be getting ignored.

    Which was why *I think?* I put this in suggestions & feedback rather than "how-to," where it seems to have gotten moved to... My suggestion/feedback is that the CORE CODEBASE ISSUE needs to get addressed & fixed so things simply WORK AS EXPECTED, rather than having to kludge together an ad hoc solution out of duct tape and baling wire every time it breaks. It would be better to have a SINGLE SOLUTION that works for everyone (and for all potentially nestable shortcodes) than for everyone to have to put in extra man hours coming up with non-standard solutions on a case-by-case basis.

    It's like putting 100,000 man hours of work onto the community instead of taking 10 man-hours to figure out a systematic fix to the root problem that solves everyone's issues in an amicable way and moreover make the core codebase more stable, flexible and robust.

    Just the 2c of a pseudo-n00b. ^_^

  4. keesiemeijer
    moderator
    Posted 1 year ago #

    I'm under the impression you think (after reading your first post) nested shortcodes are fairly easy. It's not. How would WordPress differentiate between the nested structure you want and the nested structures other users want? That's part of why these constraints exist. If you don't like these constraints create your own plugin replacing (nested) shortcodes or work around it.

    Hmm, so, question... If that's the case, if I wanted to have more than one level of nesting would I then have to create x number of "sub-shortcodes," one for each level of nesting, or could I alternate between strictly two shortcodes so long as neither is directly inside another copy of itself?

    Try and test it. (read: I don't know)

    btw:
    I didn't moderate this post and put it in: How-To and Troubleshooting
    [Moved back to Requests and Feedback]

  5. MGmirkin
    Member
    Posted 1 year ago #

    Never said you did, but thanks. ^_^ Maybe someone else did or maybe I just forgot where I put it... C'est la vie!

    Well, like I said, I'm not a programmer. So, not quite sure what you mean by "How would WordPress differentiate between the nested structure you want and the nested structures other users want?"

    Seems to me like nesting is nesting, no? Things nested inside go inside, things not nested inside don't go inside?

    From Codex (listed above, already):
    http://codex.wordpress.org/Shortcode_API#Nested_Shortcodes

    This is a limitation of the context-free regexp parser used by do_shortcode() - it is very fast but does not count levels of nesting, so it can't match each opening tag with its correct closing tag in these cases.

    The codex entry sure makes it sound like a pretty simple issue (regexp doesn't count levels of nesting to match opening and closing tags), hence my assumption it was a pretty simple issue (fix regexp or replace regexp with a better system that DOES count levels of nesting and act on that information to match up opening and closing tags), just one not yet dealt with?

    If that's not the case, my apologies for over-simplifying... Perhaps it's "more complicated than that." But the explanation makes it sound like a pretty simple issue to define and remedy. Hence my uncertainty over why it hasn't been defined and remedied by whoever maintains the WP core codebase, but rather offloaded to everyone else to make up ad hoc solutions on a case-by-case bases.

    Just seems like fixing the core issue of "not dealing with matching up opening / closing tags for shortcodes" is what's at issue here.

    Maybe it's more difficult than that or maybe it's simply ambivalence on the part of the core codebase maintainers (I know everyone has time constraints, most folks do this out of the goodness of their hearts, and there are maybe more pressing issues, etc.). I don't know which is the case?

    Just seems like one of those times where a single fix could fix a host of problems and make the system more robust / intuitive.

    Anywho, not trying to be a pill... Sorry. Appreciate the input. ^_^

    Just see a thing that could be improved with perhaps a little concerted effort to make the out-of-the-box experience go slightly smoother / more intuitively.

    But, again, maybe I'm oversimplifying? I dunno... Problem seems pretty well defined to me, tho'? Clearly there are "workarounds," so why not apply the "workaround" to the core codebase in a more "systematic" way that works for all cases? Again, if it's possible. & it feels like it should be, if it's just an issue of tracking opening and closing shortcode tags to determine nesting hierarchy?

  6. keesiemeijer
    moderator
    Posted 1 year ago #

    Anywho, not trying to be a pill... Sorry. Appreciate the input. ^_^

    No problem :-)

    Just seems like fixing the core issue of "not dealing with matching up opening / closing tags for shortcodes" is what's at issue here.

    If I read it right, core developers choose speed using regular expressions over parsing text for opening and closing shortcode tags (slow). This will cover most use cases but unfortunately not yours.

  7. MGmirkin
    Member
    Posted 1 year ago #

    Hmm, s'pose so...? No chance at a happy middle ground?

    Some way of "seeing" if there might be a hierarchy and only invoking the "slower" method when deemed necessary?

    Almost seems like something where some extra meta-data could be stored in/with a page having shortcode "same name nesting hierarchy" needing processing, which would act as a "flag" to the handler script to "switch gears" when rendering this specific page in order to deal with the [shortcode] "nesting" hierarchy.

    No "hierarchy-denoting" meta-data? Use the "faster" script. "Hierarchy-denoting" meta-data? Switch gears to to the slower but more accurate script to deal with hierarchical shortcodes.

    Best of both worlds?

    Heck, maybe it would even be some kind of a case of an enclosing

    [ShortcodeSameNameNesting]
    ...
    [/ShortcodeSameNameNesting]

    shortcode that WP would insert around the offending "nested" "SameName" shortcodes (perhaps OnSave?) that could tell the handler at runtime "everything in this section, parse 'rigorously'" "everything outside this section, parse 'fast.'"

    Seems like maybe a workable solution that allows for the extra processing only when necessary and light execution for everything else?

    Dunno. Just trying to think outside the box here... ^_^

    I don't know how to build such things (still not a programmer, but get some of the basic premises, sort of, once in a while, when I feel like it), but it seems like it wold be a useful function / shortcode / plugin if someone DID build it.

    ----------

    Sounds like there are a few other "known issue" that could use a systematic cleanup too?

    The shortcode parser uses a single pass on the post content. This means that if the $content parameter of a shortcode handler contains another shortcode, it won't be parsed:

    [caption]Caption: [myshortcode][/caption]

    This would produce:

    <span class="caption">Caption: [myshortcode]</span>

    If the enclosing shortcode is intended to permit other shortcodes in its output, the handler function can call do_shortcode() recursively:

    function caption_shortcode( $atts, $content = null ) {
    return '<span class="caption">' . do_shortcode($content) . '</span>';
    }

    In the previous example, this would ensure the "[myshortcode]" macro in the enclosed content is parsed, and its output enclosed by the caption span:

    <span class="caption">Caption: The result of myshortcode's handler function</span>

    ...

    Note: The behavior described below involving shortcodes with hyphens ('-') still applies in WordPress 3+. This could be due to a bug in do_shortcode() or get_shortcode_regex().

    Take caution when using hyphens in the name of your shortcodes. In the following instance WordPress may see the second opening shortcode as equivalent to the first (basically WordPress sees the first part before the hyphen):

    [tag]
    [tag-a]

    It all depends on which shortcode is defined first. If you are going to use hyphens then define the shortest shortcode first.

    Perhaps neither here nor there.

    Save that is seems like [shortcodes] generally need a bit of shoring up against bugs & some modifications to add flexibility.

    I hope that someone's actively looking into these issue and not just shrugging and walking away. 'Cause, clearly, they're "known" and they seem to intermittently cause some issue. Would be nice to see some spit shine to buff out some rough spots in a few places. ^_^

    ----------

    Anywho, hope my approach to the problem / solution is a useful suggestion? ^_^ Maybe even bordering on meritorious?

    Cheers,
    ~MG

  8. adelval
    Member
    Posted 9 months ago #

    Hi kissiemeijer,

    You say:
    "I'm under the impression you think (after reading your first post) nested shortcodes are fairly easy. It's not. How would WordPress differentiate between the nested structure you want and the nested structures other users want?"

    Also:

    "core developers choose speed using regular expressions over parsing text for opening and closing shortcode tags (slow)."

    ---

    First, for the other posters, it's mathematically impossible to handle nesting structures with regular expressions. So if WP insists on using regexes for this, the problem of nested shortcodes will always be there.

    Second, parsing nested shortcodes is a matter of parsing a tree (in the CS sense), which can be done for example with a simple depth-first search. It's pretty easy to do, I had to do it recently for a job interview. Browsers parse trees from strings all the time with the DOM.

    Third, I doubt that regexes are more efficient than parsing a tree with depth first search. The latter is O(n), linear in the size of the string, the former is what? With all the needed restarts over the string when some partial matching fails... For example, here http://stackoverflow.com/questions/21669/complexity-of-regex-substitution it is said that the overall complexity is O(2^m + n), where m is the size of the regex, n the size of the string.

    Finally, yes, nested shortcodes could be fairly easy with the right approach. A tree (or a forest) of shortcodes (i.e. one or more nested structrues of shortcodes) is either well-formed or not, just as xml is well-formed or not. It's not at all a matter of "what users want". And even if not well-formed, it seems pretty easy to handle it (just close any tag that should have been closed before reaching the closing of the parent's -or some ancestor's- tag). Regexes are simply not the right approach.

    Cheers.

    AdV

Topic Closed

This topic has been closed to new replies.

About this Topic