We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 50574
    • 70 Posts
    Hello

    I'm using the Related Pages tutorial http://rtfm.modx.com/revolution/2.x/making-sites-with-modx/customizing-content/template-variables/creating-a-multi-select-box-for-related-pages-in-your-template to create a TV checklist of 3 resource's children and I'm having a problem getting all the parents that are called in my @EVAL snippet to show.
    @EVAL return $modx->runSnippet('listProducts',array('parent:IN' => array(4,5,6)));


    ListProducts Snippet
    $parent = $modx->getOption('parent',$scriptProperties,5);
    $parentObj = $modx->getObject('modResource',$parent);
    if (!($parentObj instanceof modResource)) { return ''; }
    $resArray = $parentObj->getMany('Children');
    $resources = array();
    foreach($resArray as $res) {
      if ($res instanceof modResource) {
        $resources[] = $res->get('pagetitle') . '==' . $res->get('id');
      }
    }
    $out = implode("||",$resources);
    return $out;


    When editing the Resource TV the only children that show in the checklist are the ones that have the parent at the end of the getOption call in the listProducts snippet. I can change that number to any of the Resource IDs and their children show. It would seem that the 'parent' property isn't finding all the parents listed in the @EVAL call and is using the default, where am I going wrong?

    Thanks in advance

    This question has been answered by BobRay. See the first response.

      • 3749
      • 24,544 Posts
      getOption() is expecting a simple associative array of properties. 'parent' is not a key in the array you're sending, so it's not finding anything.

      You could use array('parent' => 4) but if you want to use multiple parents, you'll have to send a &where property as a JSON string and create a query object in the snippet.

        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 50574
        • 70 Posts
        Thanks Bob. As I'm a new user of ModX would you be able to give a little more detail?
        I've taken a look at your site and had a read through the Dynamic Search page.

        I've added the &where property to my resource call in my template
        [[relatedProducts? &where=`[[CalculatedWhere]]` &input=`[[*relatedProducts]]` &tpl=`relatedProductsTpl`]]

        which is calling the CalculatedWhere snippet
        $c = array(
            'parent' => 4,
            'parent' => 5,
            'parent' => 6,
        );
        return $modx->toJSON($c);

        The @EVAL is the same as before with the 'parent' array, should this be changed to use the CalculatedWhere snippet?
        @EVAL return $modx->runSnippet('listProducts',array('parent:IN' => array(4,5,6)));

        Then I've edited the listProducts snippet to incorporate the CalculatedWhere results (which I'm presuming is where the problem is)
        $jsonString = $modx->toJSON($myArray);
        $parent = $modx->setPlaceholder('CalculatedWhere', $jsonString);
        // $parent = $modx->getOption('parent',$scriptProperties,5);
        $parentObj = $modx->getObject('modResource',$parent);
        if (!($parentObj instanceof modResource)) { return ''; }
        $resArray = $parentObj->getMany('Children');
        $resources = array();
        foreach($resArray as $res) {
          if ($res instanceof modResource) {
            $resources[] = $res->get('pagetitle') . '==' . $res->get('id');
          }
        }
        $out = implode("||",$resources);
        return $out;


        Again, any help is greatly appreciated.
        • discuss.answer
          • 3749
          • 24,544 Posts
          I think you're heading in the right direction. It's generally a lot faster not to use a TV, though sometimes clients prefer them.

          If it works for you, I would do it this way, with the tag in the page content or template:

          [[!listProducts? &parents=`4,5,6`]]


          $c = $modx->newQuery('modResource');
          
          /* third argument is a default list */
          $parents = $modx->getOption('parents', $scriptProperties, '4,5,6`, true);
          $parents = explode(',', $parents)
          $c->where(array(
              'parent:IN' => $parents,
          ));
          
          $resArray = $modx->getCollection('modResource', $c);
          if (empty($resArray)) {
             return 'No products found';
          }
          // etc.
          


          You won't need instanceof, since getCollection() is guaranteed to return resources (or an empty array if nothing qualifies).

          If you need the TV, I'd use a text TV called 'parents' and just put a comma-separated list of parents in it. Then you can do this at the top of the ListProducts code:

          $parents = $modx->resource->getTVValue('parents');
          $parents = explode(',', $parents);




            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 50574
            • 70 Posts
            Brilliant, thanks Bob. I just used your snippet re-jig above and everything started to show in the resource's TV (the client needs to be able to select which products to show).

            Just to clarify for anyone else looking I used the following:

            RelatedProducts TV to show a checklist
            @EVAL return $modx->runSnippet('listProducts',array('parent:IN' => array(4,5,6)));

            listParents snippet
            $c = $modx->newQuery('modResource');
            $parents = $modx->getOption('parents', $scriptProperties, '4,5,6', true);
            $parents = explode(',', $parents);
            $c->where(array(
                'parent:IN' => $parents,
            ));
            $resArray = $modx->getCollection('modResource', $c);
            if (empty($resArray)) {
               return 'No products found';
            }
            foreach($resArray as $res) {
                $resources[] = $res->get('pagetitle') . '==' . $res->get('id');
            }
            $out = implode("||",$resources);
            return $out;

            RelatedProducts snippet to pull the info from the selected resources
            if (empty($input)) { return 'This article is so unique, that we couldn\'t find anything related to it!'; }
            $tpl = $modx->getOption('tpl',$scriptProperties,'relatedProductsTpl');
            if ($modx->getChunk($tpl) == '') { return 'We found some related pages, but don\'t know how to present it.'; }
            $ids = explode('||', $input);
            $output = array();
            foreach ($ids as $key => $value) {
              $resource = $modx->getObject('modResource',array(
                'published' => 1,
                'id' => $value));
              if ($resource instanceof modResource) {
                $ta = $resource->toArray();
                $tvs = $resource->getTemplateVars();
                foreach ($tvs as $tv) {
                   $ta[$tv->get('name')] = $tv->get('value');
                }
                $output[] = $modx->getChunk($tpl,$ta);
              }
            }
            return implode('',$output);

            Page template call
            [[relatedProducts? &input=`[[*relatedProducts]]` &tpl=`relatedProductsTpl`]]
            [ed. note: cottoncreative last edited this post 11 years, 3 months ago.]