We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 25141
    • 49 Posts
    Hello all you patient people,

    this time I’m trying to write a Snippet that outputs data from a custom database.
    I’ve been following this tutorial: http://rtfm.modx.com/display/revolution20/Templating+Your+Snippets and it works fine as long as I only have one placeholder in my chunk.

    Now I want to define chunks for a php call that outputs data from several different tables in my database:

    <?php
    $tpl = $modx->getOption('tpl',$scriptProperties,'ShowDB_MDNETChunk');
    $path = MODX_CORE_PATH . 'components/db_mdnet/';
    $result = $modx->addPackage('db_mdnet',$path . 'model/','db_');
    
    $einrichtungen = $modx->getCollection('Einrichtung');
    	foreach($einrichtungen as $einrichtung) {
    		$einrichtungArray = $einrichtung->toArray();
       		$output .= $modx->getChunk($tpl,$einrichtungArray);
    
    $standorte = $einrichtung->getMany('Standort');  
    	foreach($standorte as $standort) {
    		$output .= '<p>Ort: ' . $standort->get('ort').'</p>';
    }
    $einrichtung_leiters = $einrichtung->getMany('EinrichtungLeiter');  
    	foreach($einrichtung_leiters as $einrichtung_leiter) {
    		$output .= '<p>Leiter der Einrichtung, Funktion: ' . $einrichtung_leiter->get('funktion').'</p>';
    $kontakt = $einrichtung_leiter->getOne('Kontakt');
    		$output .= '<p>Telefon des Leiters der Einrichtung: ' . $kontakt->get('telefon').'</p>';
    }
    $emails = $einrichtung->getMany('Email');  
    	foreach($emails as $email) {
    		$output .= '<p>E-Mail Adresse: ' . $email->get('email').'</p>';
    }
    }
    return $output;


    The first part ("Einrichtung") works but when I try adding chunks to the other parts of the call in a similiar fashion I get all sorts of arrays ...

    Thanks for your support!
    R


    - Revo 2.0.7-pl (trad.)
    - Solaris 10
    - PHP 5.2.14
    - Apache 5.1.45
    - pdo_mysql installed
    - Firefox 3.6.13 / Mac OS
      • 3749
      • 24,544 Posts
      Does the code above work? I don’t see anything wrong with it.

      If it does, show us the code that *doesn’t* work. wink

        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
        • 29019 ☆ A M B ☆
        • 104 Posts
        When you get arrays instead of chunks, it’s usually because you’re outputting the chunk object, instead of the chunk content. You might try throwing a ->process() on the end of the offending chunks.
          www.darkstardesign.com

          Are you in the Nashville area? Join us for our next MODX meetup!
          • 3749
          • 24,544 Posts
          Quote from: swespi at Jan 31, 2011, 03:20 PM

          When you get arrays instead of chunks, it’s usually because you’re outputting the chunk object, instead of the chunk content. You might try throwing a ->process() on the end of the offending chunks.

          $modx->getChunk(’ChunkName’,$properties) will always return the processed content of the chunk, so process() is unnecessary as long as you use getChunk().
            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
            • 4172
            • 5,888 Posts
            may be this is something you can use.
            Added a quick example for Templates/Resources/Createdby-user/Templatevars to see how it works.


            snippet parseCollection:

            <?php
            $tpls = $modx->getOption('tpls',$scriptProperties,'{}');
            $path = MODX_CORE_PATH . 'components/db_mdnet/';
            $result = $modx->addPackage('db_mdnet',$path . 'model/','db_');
            
            $tpls = $modx->fromJson($tpls);
            
            //echo '<pre>'.print_r($tpls,1).'</pre>';
            
            /* example:
            [[!parseCollection? 
                &tpls=`{
            	"class":"modTemplate",
            	"tpl":"Templatechunk",
            	"innertpls":[{
            	    "alias":"Resources",
            	    "tpl":"Resourcechunk",
            	    "innertpls":[{
            		    "alias":"TemplateVars",
            		    "tpl":"Templatevarschunk"
            	    },{
            		    "alias":"CreatedBy",
            		    "tpl":"Userchunk"
                }]}]}
            `]]
            */
            
            /* chunks:
            
            Templatechunk:
            <h2>[[+templatename]]</h2>
            [[+innerrows.Resources]]
            
            Resourcechunk:
            <h4>[[+pagetitle]]</h4>
            [[+innerrows.CreatedBy]]
            [[+innerrows.TemplateVars]]
            
            Templatevarschunk:
            [[+name]]
            
            Userchunk:
            [[+username]]
            
             */
            
            function parseInnerChunks(& $object,$tpls){
            global $modx;
            
            foreach ($tpls as $tpl){
                $FKDef=$object->getFKDefinition($tpl['alias']);
                $output='';
                switch ($FKDef['cardinality']){
                    case 'many':
                        if ($collection = $object->getMany($tpl['alias'])){
                            foreach ($collection as $innerobject){
                                $arr = $innerobject->toArray();
                                if ( isset ($tpl['innertpls'])){
                                    $arr['innerrows'] = parseInnerChunks($innerobject, $tpl['innertpls']);
                                }
                                $output .= $modx->getChunk($tpl['tpl'], $arr);
                            }		    	
            		    }
                        break;
                    case 'one':
                        if ($innerobject = $object->getOne($tpl['alias'])){
                            $arr = $innerobject->toArray();
                            if ( isset ($tpl['innertpls'])){
                                $arr['innerrows'] = parseInnerChunks($innerobject, $tpl['innertpls']);
                            }
                            $output = $modx->getChunk($tpl['tpl'], $arr);		    	
                        }
                        break;
                    default:
                        $output = '';
                        break;							
                }
                $innerrows[$tpl['alias']]=$output;		
            }
            return $innerrows;
            }
            
            $collection = $modx->getCollection($tpls['class']);
            foreach ($collection as $object){
            	$arr=$object->toArray();
                if (isset($tpls['innertpls'])){
                	$arr['innerrows']=parseInnerChunks($object,$tpls['innertpls']);
                }
            	$output.= $modx->getChunk($tpls['tpl'],$arr);
            	
            }
            
            return $output;	
            
            	
            	


            you can try to call it like that:
            [[!parseCollection? 
            &tpls=`{
            	"class":"Einrichtung",
            	"tpl":"ShowDB_MDNETChunk",
            	"innertpls":[{
            	    "alias":"Standort",
            	    "tpl":"standortchunk"
            	    },{
            	    "alias":"EinrichtungLeiter",
            	    "tpl":"leiterchunk",
            	    "innertpls":[{
            		    "alias":"Kontakt",
            		    "tpl":"kontaktchunk"
            	    }]
            	    },{
            	    "alias":"Email",
            	    "tpl":"emailchunk"
            	    }]}
            `]]


              -------------------------------

              you can buy me a beer, if you like MIGX

              http://webcmsolutions.de/migx.html

              Thanks!
              • 25141
              • 49 Posts
              @Bob: I tried using this method to template the other loops with the same chunk (which had all four placeholders in it):
              $einrichtungen = $modx->getCollection('Einrichtung'); 
              foreach($einrichtungen as $einrichtung) {
              	$einrichtungArray = $einrichtung->toArray();
                 	$output .= $modx->getChunk($tpl,$einrichtungArray);
              
                 
              		$standorte = $einrichtung->getMany('Standort');   
              			foreach($standorte as $standort) {
              				$standortArray = $standort->toArray();
                 				$output .= $modx->getChunk($tpl,$standortArray);
              				}
              		$einrichtung_leiters = $einrichtung->getMany('EinrichtungLeiter');  
              			foreach($einrichtung_leiters as $einrichtung_leiter) {
              				$einrichtung_leiterArray = $einrichtung_leiter->toArray();
                 				$output .= $modx->getChunk($tpl,$einrichtung_leiterArray);
              				}
              		$kontakt = $einrichtung_leiter->getOne('Kontakt');
              				$output .= $modx->getChunk($tpl,$kontakt);
              				}
              		$emails = $einrichtung->getMany('Email');  
              			foreach($emails as $email) {
              				$emailArray = $email->toArray();
                 				$output .= $modx->getChunk($tpl,$emailArray);
              				}
              	}


              This code outputs only a list of ’Einrichtung’, which didn’t surprise me - I didn’t post this code before because I am kind of ashamed of it wink - I now understand that I would probably have to use a seperate chunk for each loop and add some tricky php (like Bruno’s) to help ModX figure out what table in the DB I mean.

              @Bruno: Wow, thank you for your detailed help!! I got it set up and learned some basics while doing so.

              Now in the meantime I had been experimenting with Smarty for my templating, as I’ve worked with Smarty previously. I actually used the code you posted in the german forum (http://www.modxcms.de/forum/comments.php?DiscussionID=4075&page=1#Item_5); I only had to change the delimiters to {}.
              This is how I set my templating up with Smarty:

              Snippet:
              <?php
              $path = MODX_CORE_PATH . 'components/db_mdnet/';
              $result = $modx->addPackage('db_mdnet',$path . 'model/','db_');
              global $smarty;
              
              $einrichtungen = $modx->getCollection('Einrichtung'); 
              $einrichtungenArray = array();
              
              foreach($einrichtungen as $einrichtung) {
              
              $einrichtungArray = $einrichtung->toArray();
              $einrichtungArray['standort'] = array();
              $standorte = $einrichtung->getMany('Standort');   
              
              foreach($standorte as $standort) {
              $standortArray = $standort->toArray();
              $einrichtungArray['standorte'][] = $standortArray;
              }
              $einrichtungenArray[] = $einrichtungArray;
              
              }
              $smarty->assign('einrichtungenArray',$einrichtungenArray);
              return $smarty->fetch('chunk:ShowDB_MDNETChunk_Smarty');


              And the chunk ShowDB_MDNETChunk_Smarty:
              {foreach from=$einrichtungenArray item=einrichtung}
              <li>Name: {$einrichtung.name_kurz}</li>
              <li>Standorte:
              <ul>
              {foreach from=$einrichtung.standorte item=standort}
              <li>Ort: {$standort.ort}</li>
              {/foreach}
              </ul>
              </li>
              {/foreach}


              To my programming-dense designer-brain this seems to be a lot easier, especially as this is not an official plugin I’m making but rather a thing that only I will use and change - but I know that templating via Smarty in the frontend is frowned upon. Does anybody have any recommendations as to which method I should decide to use?

              And thanks again for all your help, you people are awesome.