We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22843
    • 5 Posts
    Hi folks; OK, I’ve had a pretty thorough search around, and I can’t seem to find an explanation or solution for this issue with ModX Evolution. Here’s the skinny:

    A chunk in a page template makes a call to Ditto as follows:

    [[Ditto? &id=`latestSpecialsListBlock`&hideFolders=`1`&depth=`0`&display=`3`&orderBy=`bookPubDate DESC`&paginate=`1`&paginateAlwaysShowLinks=`1`&tpl=`latestListBlock` ]]


    Here’s that tpl mentioned at the end:

    <li class="latest-books-block-item">
    <a href="[+url+]"><h4>[+bookTitle+]</h4></a><br />
    <a href="[+url+]"><img src="[+bookCoverImage+]" title="[+bookTitle+] by [+author+]" height="100px"></a><br />
    <p>[+introtext+]</p>
    
    {{[+numberOfStates+]Ditto}}
    </li>


    Now, that chunk call near the end is using a radio-button selected TV from the resources being pulled in by Ditto to select the appropriate chunk to insert; I need to insert slightly different forms depending on certain conditions of the resource in question, but as far as I can tell that shouldn’t matter.

    When I call up the page with the Ditto call with everything as it is above, nothing comes through from that chunk call. However, if I remove the {{ }}, it cheerfully spits out the right value as plain text; furthermore, if I simply paste in the code from one of the chunks I’m trying to call instead, it appears as it should do.

    Have I simply run into a limitation of the platform here, or is there some way I can use a TV placeholder in a Ditto template to call another chunk into that template? And if so, how do I do it?

    I’m sure I’m missing something blindingly obvious, but I’ve spent a couple of hours fiddling with this to no avail... any advice would be appreciated! smiley
      • 27708 MODX Staff
      • 2,502 Posts
      Paul,

      I think you are running into an issue relating to the order of execution in Evo (this will exist in any app where there is a parser). If you look at the following link: http://wiki.modxcms.com/index.php/Order_of_execution you will see that at #20-23 may be where you are hitting the limit. Another thought is that you likely need to call Ditto uncached but I am not sure on that.

      Cheers,

      Jay
        Author of zero books. Formerly of many strange things. Pairs well with meats. Conversations are magical experiences. He's dangerous around code but a markup magician. Blog ✦ Twitter ✦ LinkedIn ✦ GitHub
        • 22843
        • 5 Posts
        Thanks, Jay, I think that’s answered my initial question: if placeholders are parsed after chunk calls, then what I’m doing isn’t going to work.

        So the next question is "is there another way to achieve the same thing"? Maybe I should expand a bit on what I’m trying to do...

        OK, so the site I’m building here is a webstore for a small press publisher. The Ditto call shown above is calling for the set of resources which each represent a single title; however, each title (Book X by Joe Y) can have between one and three different ’states’ or editions, each of which has a different price.

        Now, the resource for each book has a radio-button TV [*numberOfStates*], the output of which is used to call one of three different chunks when that resource is displayed; these three chunks are FoxyCart buy-link forms customised for the number of different editions the book has. Eg, if [*numberOfStates*] is set to ’1’ in the Manager, it outputs the string "oneStateBuyFormChunk"; set to ’2’, it outputs "twoStateBuyFormChunk". In the resource template, those strings are inserted into a chunk call thusly: {{[*numberOfStates*]}}, so that a form with the necessary options to select from the available editions is displayed. This works just fine.

        Now, back to the Ditto call, which is supposed to produce a browseable and paginated list of books in the catalogue. These are coming out just fine, but I want to put the same FoxyCart buy forms in each book listing, so the customer doesn’t have to click through to the actual resource for the title to be able to add it to their cart. Because we’re working with Ditto, I have to use placeholders instead of TV calls, so I’ve cloned the chunks that output the buy forms to versions that use placeholders.

        Example: this is {{oneStateBuyFormChunk}}:

        <form action="https://xxxx.foxycart.com/cart" class="foxycart" method="post">
            <input type="hidden" name="name" value="[*bookTitle*]" />
            <input type="hidden" name="category" value="[*freeShipping*]" />
        <select name="state">
            <option value="[*firstState*]{p:[*firstStatePrice*]}">[*firstState*] - £[*firstStatePrice*]</option>
        </select>
            <input type="submit" value="Buy It Now!" />
        </form>


        And this is {{oneStateBuyFormChunkDitto}}:

        <form action="https://xxxx.foxycart.com/cart" class="foxycart" method="post">
            <input type="hidden" name="name" value="[+bookTitle+]" />
            <input type="hidden" name="category" value="[+freeShipping+]" />
        <select name="state">
            <option value="[+firstState+]{p:[+firstStatePrice+]}">[+firstState+] - £[+firstStatePrice+]</option>
        </select>
            <input type="submit" value="Buy It Now!" />
        </form>


        If I just drop {{oneStateBuyFormChunkDitto}} directly into the Ditto template, it displays just fine. The problem is that I need to switch between chunks in that position depending on the value of [+numberOfStates+] for each individual Ditto result, in order to present the option to buy any edition of the book from the dropdown list. But as Jay has pointed out, the chunk call is parsed before the TV placeholder, which at that point in proceedings doesn’t contain a valid chunk name, and so no buy form appears in the Ditto results at all.

        I’m suspecting now that what I need to do probably involves some sort of snippet wizardry, but I’m uncertain of how I’d go about setting the right chunk call for each Ditto result. Can anyone suggest a way to do it? Or (better still, and probably more likely given I’m a self-taught n00b at PHP) is there a method that circumvents the issue entirely?
          • 22843
          • 5 Posts
          OK, so I’ve made a bit of progress here, but I think I’ve hit a brick wall at the same time.

          In the Ditto template, I’m now calling a snippet and passing on a few placeholders, as follows:

          [[buyFormChunkSelectionSnip? &tvName=`[+numberOfStates+]`&docID=`[+id+]`]]


          In that snippet is the following PHP:

          $chunkName = $tvName.'Ditto';
          $output = $modx->getChunk($chunkName);
          return $output;


          Now, this is progress, because the correct chunk for the current Ditto result is being spooled out... but all the placeholders within said chunks are empty of the placeholder values that should populate them. *headdesk*

          Digging around in the API docs leads me to suspect that what I need to do is use parseChunk instead of getChunk, but the documentation for parseChunk has me a bit confused as to what variables I need to pass in when I call it (I can’t get it to return anything so far, and I know the second variable needs to be an array, but an array of what, exactly?), let alone whether it’s actually going to do what I hope it’s going to do (namely populate the chunk with the right values before returning it). I’ve tried the following:

          $chunkName = $tvName.'Ditto';
          $output = $modx->parseChunk($chunkName, $modx->placeholders, '[+', '+]');
          return $output;


          ... but while that does still display the framework of the correct chunk, the values of the placeholders are still absent. I’ve tried switching around and alternating the cached/non-cached status of the two snippet calls, but there’s no change as a result. Any suggestions?
            • 22843
            • 5 Posts
            Victory! Turns out what I needed to do was pass all the placeholders I wanted to use into the snippet as arguments, then stuff ’em into an array so they matched the right placeholder names...

            $dittoplaceholders = array(
              'bookTitle' => $bookTitle,
              'firstState' => $firstState,
              'firstStatePrice' => $firstStatePrice,
              'secondState' => $secondState,
              'secondStatePrice' => $secondStatePrice,
              'thirdState' => $thirdState,
              'thirdStatePrice' => $thirdStatePrice


            ... and then pass that array as the second argument of parseChunk. Bam!

            I’m still somewhat concerned at how database-heavy that code will be (given that there’s ~200 items in the client’s catalogue already, and they add about five a month if not more), and it strikes me as an oddly inelegant solution compared to how simple most things I’ve wanted to do have been (which, I should point out, is a reflection on my expectations more than it is on the software), but for now, ModX is doing my bidding, and that feels real sweet!

            Hopefully some other clueless n00b will find this post one day, and I’ll have saved them five hours of incredibly frustrating tedium. smiley