We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    Ok, here’s an example of what I’m trying to do:

    $base_path = MODX_CORE_PATH . 'components/mycmp/';
    $modx->addPackage('mycmp',$base_path.'model/','');  
    
    $things = $modx->getCollection('Things',array());
    
    $output = '';
    
    $x = new modElement();
    $tpl = '
    <tr>
    <td>[[+thing_id]]</td>
    <td>[[+name]]</td>
    <td>[[+etc]]</td>
    </tr>
    ';
    foreach ($things as $t)
    {
    	$output = $x->process( $t->toArray(), $tpl);
    }
    
    return $output;


    Granted, I could just put the tpl stuff into a Snippet, but in principle I want to know how to declare a modElement object and process it. The above code (used in a Custom Manager Page), generates an error:
    Fatal error: Call to a member function getPackage() on a non-object in /path/to/revo/core/xpdo/om/xpdoobject.class.php on line 598
      • 22303 MODX Staff
      • 10,725 Posts
      You cannot create a new modElement -- it does not define a complete process method; in fact that defines the first part of the process method for every modElement derivative. This is the same thing as saying $modx->newObject(’modChunk’), and calling process($properties, $content).
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        Ok, that makes sense. How about controlling caching? $x->setCacheable(false);
        doesn’t seem to be having the effect I was expecting. If I replace my code so it looks like this:

        $x = $modx->newObject('modChunk');
        $tpl = '
        <tr>
        <td>[[+thing_id]]</td>
        <td>[[+name]]</td>
        </tr>
        ';
        foreach ($things as $t)
        {
        	$x->setCacheable(false);
        	$output .= $x->process( $t->toArray(), $tpl);
        }
        return $output;


        I’m having 2 problems with that:
        1. Only the first row in the collection is processed (i.e. the result is cached and returned for each $t ($thing) ).
        2. Null values don’t process. So if I have a row that has a null value for one of the placeholders, the placeholder comes back. I would expect it to go from [[+placeholder]] to ’’.

        Are there ways around this?
          • 4172
          • 5,888 Posts
          try:
          $tpl = '
          <tr>
          <td>[[+thing_id]]</td>
          <td>[[+name]]</td>
          </tr>
          ';
          foreach ($things as $t){
              $x = $modx->newObject('modChunk');
              $x->setCacheable(false);
              $x->setContent($tpl);
              $output .= $x->process( $t->toArray());
          }
          return $output;


          I’m not sure, if you could also create the object before your loop and process it more than once, when using setContent()
            -------------------------------

            you can buy me a beer, if you like MIGX

            http://webcmsolutions.de/migx.html

            Thanks!
            • 9207 ☆ A M B ☆
            • 2,475 Posts
            Thanks, Bruno... but the only thing that seemed to work was declaring an object for each iteration:

            		foreach ($thing as $t)
            		{
            			$x = $modx->newObject('modChunk');
            			$x->setCacheable(false);
            			$x->setContent($tpl);
            			$output .= $x->process( $t->toArray() );
            		}
            


            I guess that’s Ok... dunno if there are any performance hits.

            Any idea how to force MODx to clean up the unused placeholders? I’m ending up with more than a few [[+of_these]] in my output.
              • 25037
              • 32 Posts
              Quote from: Everett at Nov 22, 2010, 04:09 PM

              Any idea how to force MODx to clean up the unused placeholders? I’m ending up with more than a few [[+of_these]] in my output.

              Might be easiest to use a regular expression. Here’s an example.
              foreach ($thing as $t)
              {
                 $x = $modx->newObject('modChunk');
                 $x->setCacheable(false);
                 $x->setContent($tpl);
                 $output .= $x->process( $t->toArray() );
              }
              
              $prefix = preg_quote('[[');
              $suffix = preg_quote(']]');
              $regex = '/' . $prefix . '\+[^' . $prefix . $suffix . ']+' . $suffix . '/';
              if($result = preg_replace($regex ,'',$output))
              {
                 $output = $result;
              }
              

              Edit: alternatively, the regex could look like this:
              $regex = '/' . $prefix . '\+[a-zA-Z0-9_]+' . $suffix . '/';
              

                • 9207 ☆ A M B ☆
                • 2,475 Posts
                Thanks, rickj... I know my way around regular expressions, but I’m really hoping to tie into the MODx native stuff here without re-inventing the wheel. I mean... I’ve already got code that does all this, but it’s kind of a waste to load it all up when somewhere, somehow, MODx has a function that does this already. If I start structuring all my plugins and snippets off of my own versions of MODx functions, those plugins and snippets get to be really bulky and un-maintainable, even if they are easier to code.
                  • 25037
                  • 32 Posts
                  Ok, sorry for boring you with the regex smiley

                  I don’t know if modx has something to remove placeholder tags, but the response class calls the parser to remove unprocessed tags and it is a very expensive operation. That’s because it has to remove nested tags as well. Since I don’t think you don’t have to worry about that, nothing could be faster than the simple regex.
                    • 22303 MODX Staff
                    • 10,725 Posts
                    You don’t need to call setContent(). It just works by calling it with the parameters I suggested. This is how getResources, and many other Snippets work. If it’s only processing your first row, you have another problem that needs to be diagnosed.
                      • 9207 ☆ A M B ☆
                      • 2,475 Posts
                      Blink. There’s not much else in that Snippet. I posted almost everything in the example. Any ideas of what else to look for?