We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22829 ☆ A M B ☆
    • 80 Posts
    I’ve been writing a few tiny snippets for Revolution. This one takes a parent ID (or will default to the current resource) and returns the contents of a random child.

    [EDIT: see the next post for the latest attempt]


    Feedback very welcome. It’s working for me, but it could use more features. (I’m new to Revolution, xPDO, etc.)

    I’ll be happy to review feedback, make fixes, and get it ready for the repository if the snippet might be useful to someone else.

    EDIT: Updated on 3/27 with the final code used on my site (code that now works without any errors).
      Time is what keeps everything from happening all at once.
      • 22829 ☆ A M B ☆
      • 80 Posts
      Here’s an updated version of a snippet that grabs random content. It can be useful for sidebars or other dynamic content areas.

      <?php
      /**
       *
       * randomChild
       *
       * Returns the ID (or the content) from a randomly selected child resource
       *
       * @ author Paul Merchant
       * @ copyright 2010, Paul Merchant
       * @ version 1.0.0 - May 3, 2010
       *
       * OPTIONS
       * parents - (Opt) A comma delimited list of immediate parents, defaults to current resource
       * getContent - (Opt) Set as true to return the content instead of the ID, defaults to false
       * default - (Opt) The value returned if nothing is found
       * 
       * Exmaple1: [[randomChild?]]
       * Example2: [[randomChild? &parents=`123,124,125` &getContent=`1`]]
       * 
       * Thanks to Susan Ottwell for writing a similar snippet for modx Evolution!
       * 
      **/
      
      // set defaults
      $parents = $modx->getOption('parents',$scriptProperties,$modx->resource->get('id'));
      $getContent = $modx->getOption('getContent',$scriptProperties,false);
      $output = $modx->getOption('default',$scriptProperties,'');
      
      // get the IDs of all immediate and published children from each parent
      $criteria = $modx->newQuery('modResource');
      $criteria->where(array(
          "`parent` IN (" . $parents . ")",
          'deleted' => 0,
          'published' => 1,
      ));
      $criteria->select(array('id'));     
      $children = $modx->getCollection('modResource',$criteria);
      
      // count children found
      $childcount = count($children);
      if ($childcount < 1) {
          return $output;
      }
      
      // get the id of a random child
      $id = $children[rand(1, $childcount) -1]->get('id');
      
      if (!$getContent) {
          // just the id
          $output = $id;
      } else {
          if ($id == $modx->resource->get('id')) {
              // use the current resource
              $resource =& $modx->resource;
          } else {
              // get only the columns we need
              $criteria = $modx->newQuery('modResource');
              $criteria->select(array('id','content'));
              $criteria->where(array('id' => $id,));
              $resource = $modx->getObject('modResource',$criteria);
          }
          // get the contents of the content field
          if (empty($resource)) return $output;
          $fieldValue = $resource->get('content');
          if ($fieldValue !== null) {
              $output = $fieldValue;
          } 
      }
      
      return $output;
      ?>


      Fixes and comments are always welcome.
        Time is what keeps everything from happening all at once.
        • 22303 MODX Staff
        • 10,725 Posts
        You know you can do this with getResources by setting the sortby property to the value RAND() and limit to 1 (if you only want one random result)?

        Also, why grab all of the data from all of the objects if you only want one (and probably only specific fields from it)? That’s a huge waste of memory and resources IMO.
          • 22829 ☆ A M B ☆
          • 80 Posts
          Quote from: OpenGeek at May 04, 2010, 09:10 AM

          You know you can do this with getResources by setting the sortby property to the value RAND() and limit to 1 (if you only want one random result)?

          Also, why grab all of the data from all of the objects if you only want one (and probably only specific fields from it)? That’s a huge waste of memory and resources IMO.

          That first version was pretty lame. I’d love your thoughts on the second post, which attempted to address those issues (and I’ll go up and change that first post to avoid confusion in the future).

          The version of getResources that I cut my teeth on didn’t have a random feature. Now that it does, maybe I should use it instead, although this randomChild thing would probably have less overhead. Thanks for that tip, though (and for the comments).

          Edit: It’s also quite possible that the second version could use a lot of help. There aren’t a ton of code examples and not much documentation yet. Even if this is a dumb idea (duplicating something that getResources can now do), I’d love a few pointers on how to do something like this better.
            Time is what keeps everything from happening all at once.
            • 22829 ☆ A M B ☆
            • 80 Posts
            Oops. I now understand what you’re saying about passing RAND() as a sort order to getResources. I guess that’s something that I could’ve done all along. That’s a cool trick.

            It does look like with all the right settings I could make getResources do the same thing. I’ll have to try it.
              Time is what keeps everything from happening all at once.
              • 21560
              • 145 Posts
              Very, very simple to do ;-)

              <?php
              // Get a random child, using getCollection instead of getObject for possible multiple results.
              $criteria = $modx->newQuery('modResource');
              $criteria->where(array(
                  'deleted' => 0,
                  'published' => 1,
              	'template' => 2
              ));
              $criteria->sortby('RAND()'); //
              $criteria->limit(1); //Limit the results to 1
              $children = $modx->getCollection('modResource',$criteria);
              
              foreach ($children as $child) {
              	echo $child->id.'<br />';
              }
              


              After that, do with it what you will. You can get random content, or whatever you wish.

              You can also do "RAND()" with WayFinder or such in their sortBy field. Should work the same and doesn’t require a seperate snippet.
                [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
                • 21560
                • 145 Posts
                And for people who want to use this for a random link, like mine: http://nimja.com/random

                Make a snippet: RandomPage with this content:
                <?php
                // Get a random page ID.
                $criteria = $modx->newQuery('modResource');
                $criteria->where(array(
                	'deleted' => 0,
                	'published' => 1,
                	'template' => 2 //Only get resources with template 2
                ));
                $criteria->sortby('RAND()');
                $criteria->limit(1); //Limit the results to 1
                $child = $modx->getObject('modResource',$criteria);
                
                return !empty($child) ? $child->id : 1; //1 is the default id when nothing can be found.
                


                And make a weblink (with the alias "random" or whatever) with this as the link:
                [[~[[!RandomPage]]]]


                This just emphesizes why I adore Revolution so much above any other system ^_^. Go Go Gadget Super Flexible CMS!
                  [font=Times]Comics, stories, music, graphics, games and more! http://Nimja.com
                  • 37828
                  • 11 Posts
                  Quote from: Nimja at Mar 30, 2011, 04:39 AM
                  And for people who want to use this for a random link, like mine: http://nimja.com/random

                  Make a snippet: RandomPage with this content:
                  <?php
                  // Get a random page ID.
                  $criteria = $modx->newQuery('modResource');
                  $criteria->where(array(
                  	'deleted' => 0,
                  	'published' => 1,
                  	'template' => 2 //Only get resources with template 2
                  ));
                  $criteria->sortby('RAND()');
                  $criteria->limit(1); //Limit the results to 1
                  $child = $modx->getObject('modResource',$criteria);
                  
                  return !empty($child) ? $child->id : 1; //1 is the default id when nothing can be found.
                  


                  And make a weblink (with the alias "random" or whatever) with this as the link:
                  [[~[[!RandomPage]]]]


                  This just emphesizes why I adore Revolution so much above any other system ^_^. Go Go Gadget Super Flexible CMS!

                  Hello! I want to display the content of a random child from specified folder.
                  I try your to modify your script but not work ...

                  $criteria = $modx->newQuery('modResource'); 
                  $criteria->where(array(
                      'deleted' => 0,
                      'published' => 1
                  ));
                  $criteria->sortby('RAND()');
                  $folder = isset($folder)? $folder:0;
                  $child = $modx->getObject('modResource',$criteria, $folder, 'content');
                  $output = $messages[$index]['content'];
                  return "$output";
                  


                  need for display a call like:
                   [[ClientQuote? &folder=`3`]]
                  ...

                  Any help is appreciated.
                  Thanks in advance.
                    • 4172
                    • 5,888 Posts
                    try this:

                    <?php
                    $folder = isset($folder)? $folder:0;
                    $criteria = $modx->newQuery('modResource');
                    $criteria->where(array(
                        'deleted' => 0,
                        'published' => 1,
                        'parent' => $folder
                    ));
                    $criteria->sortby('RAND()');
                    $child = $modx->getObject('modResource',$criteria);
                    return $child->get('content');
                    
                      -------------------------------

                      you can buy me a beer, if you like MIGX

                      http://webcmsolutions.de/migx.html

                      Thanks!
                      • 3749
                      • 24,544 Posts
                      LOL. Rebuut posted this question in two different places and the final code in both places is identical except that I used $child->getContent().

                      Great minds. wink


                      ------------------------------------------------------------------------------------------
                      PLEASE, PLEASE specify the version of MODX you are using.
                      MODX info for everyone: http://bobsguides.com/modx.html
                        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