On March 26, 2019 we launched new MODX Forums. Please join us at the new MODX Community Forums.
Subscribe: RSS
  • It's more of a theoretical thing BobRay. I was trying to understand the methods illustrated by Opengeek in the context of my original issue. This was solved with caching and the site flies, but in an effort to improve my understanding of MODx I wanted to explore these other options and have come unstuck at the first!!
    • I'm trying to use the techniques described here to loop over a chunk but can't get it to work properly. Is it possible to output dynamic content via the process method? If I change OpenGeeks benchmark script to echo the results from each iteration, I get 1000 copies of the first record for getObject and modParser::getElement but getChunk works as expected. Here is the code I', using:
      <?php
      include 'config.core.php';
      include MODX_CORE_PATH . 'model/modx/modx.class.php';
      $modx = new modX();
      $modx->initialize('web');
      
      $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
      $modx->setLogLevel(xPDO::LOG_LEVEL_INFO);
      
      $tstart = $modx->getMicroTime();
      $chunk = $modx->getObject('modChunk', array('name' => 'testSpeed'));
      $chunk->setCacheable(false);
      for ($i = 0; $i < 1000; $i++) {
          echo $chunk->process(array('i' => $i));
      }
      $tend = $modx->getMicroTime();
      $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed 1000 chunks using getObject — %2.4f s\n", $tend - $tstart));
      
      $tstart = $modx->getMicroTime();
      $chunk = $modx->getParser()->getElement('modChunk', 'testSpeed');
      for ($i = 0; $i < 1000; $i++) {
          echo $chunk->process(array('i' => $i));
      }
      $tend = $modx->getMicroTime();
      $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed 1000 chunks using modParser::getElement — %2.4f s\n", $tend - $tstart));
      
      $tstart = $modx->getMicroTime();
      for ($i = 0; $i < 1000; $i++) {
          echo $modx->getChunk('testSpeed', array('i' => $i));
      }
      $tend = $modx->getMicroTime();
      $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed 1000 chunks using getChunk — %2.4f s\n", $tend - $tstart));
      exit();
      
      • Quote from: simonp98 at Mar 01, 2012, 09:23 PM

        What appears to be happening is that the tag is not changing with each new property value and so the result is that the chunk is always retrieved from the source cache.
        Hi, after adding
          $myChunkAsObject->_processed = false;
        

        to the loop with the process() call, it worked, and it was MUCH faster than getChunk(). Thank you for raising the issue, btw, don't know how I'd find what's the problem without your tests.
          <em>The Earth is not the hell, and people aren't cursed, and joy in not a sin, but a gift of God.</em> (Lesia Ukrainka)
        • Where exactly did you add it? Cause $myChunkAsObject is your chunk variable, the provided code does not seem to fix the same value problem.

          The following code outputs the same values for each item:

          $chunkie = $modx->getObject('modChunk', array('name' => 'thumbTemplate'));
          foreach ($items as $item) {
          
              $itemArray = $item->toArray();
              $itemArray['idx'] = $idx;
          
          (...)
          
          $output .= $chunkie->process($itemArray);
          $idx++;
          };
          [ed. note: ellipsis_89 last edited this post 6 years, 11 months ago.]
          • I also just tried out ALL of the suggested alternatives to getChunk also with different things like seen commented out in the following code

            $tpl = 'chunk.name';
            $tpl = $this->modx->getObject('modChunk', array('name' => $tpl));
            //$tpl = $this->modx->getParser()->getElement('modChunk', $tpl);
            //$tpl->setCacheable(false);
            //$tpl->cache_type = 1;
            //$tpl->_processed = false;
            //$this->modx->log(modX::LOG_LEVEL_ERROR, '[' . $this->config['packagename'] . '] Chunk Object ' . print_r($tpl->toArray(),1));
            foreach ( $records as $record ) {
            	// parse tpl chunk
            	if ( $record->getOne('Song') ) {
            		$song = $record->getOne('Song')->toArray();
            		$record = $record->toArray();
            		$data = array_merge($record, $song);
            	} else {
            		$record = $record->toArray();
            		$data = $record;
            	}
            	
            	// parse template chunk and return output, $tpl is a chunk name
            	//$output .= $this->modx->getChunk($tpl, array(
            	$output .= $tpl->process(array(
            		'timestamp'			=> $data['timestamp'],
            		'starttime'			=> $data['starttime'],
            		'audioartist'		=> $data['artistname'],
            		'audiotitle'		=> $data['songtitle']
            	));
            }
            


            I cannot use Bob's suggested str_replace version because I need output modifiers inside the chunk to be processed.

            the scenario is that I have to fetch a large list of songs, think of a 24 hour playlist, around 500 items, and make html out of it...with getChunk this takes loooong (several seconds), so I'm just interested if there was another option, found this thread and sadly it doesn't work, I just get the data of the first fetched record in ALL the playlist items...it's not very urgent or so because I'm caching the generated html anyways (until the next song comes), so the user is not realizing that it takes seconds to generate that playlist from the database, but it kinda bothers me that I'm not able to make use of the nice techniques shown earlier in this thread. Was there maybe something changed in the core or am I just doing it wrong? [ed. note: exside last edited this post 6 years, 5 months ago.]
            • I managed to edit my test code to actually get it to work. The code below is working and the first two methods takes approximately 0,5 seconds to run on my local XAMPP-installation compared to the last one that takes 1,7 seconds.
              <?php
              // A chunk named testSpeed is used with the following content: [[+i]]
              include 'config.core.php';
              include MODX_CORE_PATH . 'model/modx/modx.class.php';
              $modx = new modX();
              $modx->initialize('web');
               
              $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
              $modx->setLogLevel(xPDO::LOG_LEVEL_INFO);
               
              $tstart = $modx->getMicroTime();
              $chunk = $modx->getObject('modChunk', array('name' => 'testSpeed'));
              $chunk->setCacheable(false); // This row is needed
              for ($i = 0; $i < 1000; $i++) {
                  $chunk->_processed = false; // This row is needed
                  echo $chunk->process(array('i' => $i));
              }
              $tend = $modx->getMicroTime();
              $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed 1000 chunks using getObject — %2.4f s\n", $tend - $tstart));
               
              $tstart = $modx->getMicroTime();
              $chunk = $modx->getParser()->getElement('modChunk', 'testSpeed');
              $chunk->setCacheable(false); // This row is needed
              for ($i = 0; $i < 1000; $i++) {
                  $chunk->_processed = false; // This row is needed
                  echo $chunk->process(array('i' => $i));
              }
              $tend = $modx->getMicroTime();
              $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed 1000 chunks using modParser::getElement — %2.4f s\n", $tend - $tstart));
               
              $tstart = $modx->getMicroTime();
              for ($i = 0; $i < 1000; $i++) {
                  echo $modx->getChunk('testSpeed', array('i' => $i));
              }
              $tend = $modx->getMicroTime();
              $modx->log(modX::LOG_LEVEL_INFO, sprintf("Processed 1000 chunks using getChunk — %2.4f s\n", $tend - $tstart));
              exit();
              
              • yesss! that's it, thank you so much... was missing the

                $chunk->_processed = false;


                inside the loop...got me a performance boost of around 2 seconds for the same task!