We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 5340
    • 1,624 Posts
    Hi,

    Here’s a stripped down version of getField for Revolution. No package yet but you can install it the usual way.


    <?php
    
    /* getField - stripped down version of getField for Revolution
    
    
    USAGE:
    
    1. [[!getField]]   -> current resource pagetitle 
    
    2. [[!getField? &field=`TestTv`]] -> current resource TestTv 
    
    3. [[!getField? &field=`longtitle`]] -> current resource longtitle 
    
    4. [[!getField? &field=`InvalidField`]] -> No Result!
    
    5. [[!getField? &id=`16`]]  -> id 16 resource pagetitle 
    
    6. [[!getField? &id=`16` &field=`longtitle`]]   -> id 16 resource longtitle 
    
    7. [[!getField? &id=`16` &field=`TestTv`]]  -> id 16 resource TestTv 
    
    8. [[!getField? &id=`16` &field=`InvalidField`]] -> No Result!
    
    */
    
    $output = "No result!";
    $tempOutput = "";
    
    if($id){
    
    	if($field){
    		
    		//look for document field
    		$resource = $modx->getObject('modResource',$id);
    		$tempOutput = $resource->get($field);
    		
    		if(!$tempOutput){
    			//look for TV value
    			$aField = $modx->getObject('modTemplateVar', array('name' =>$field));
    			
    			if($aField){
    				$output = $aField->getValue($id);
    			}else{
    				//default output value
    			}
    		
    		}else{
    			$output = $tempOutput;
    		}
    				
    	}else{
    		// id but no field -> return pagetitle
    		$resource = $modx->getObject('modResource',$id);
    		$output = $resource->get("pagetitle");
    	}
    
    }else{
    	if($field){
    		
    		//look for documnet field
    		$resource = $modx->getObject('modResource',$modx->resource->get('id'));
    		$tempOutput = $resource->get($field);
    		
    		if(!$tempOutput){
    			//look for TV
    			$aField = $modx->resource->get($field);
    			if ($aField){
    				$output = $aField[1];
    			}else{
    				//default output value
    			}
    			
    		}else{
    			$output = $tempOutput;
    		}
    		
    		
    	}else{
    		//no id, no field -> return current doc pagetitle
    		$output = $modx->resource->get('pagetitle');
    	}
    }
    
    echo $output;
    ?>


    Any comments and optimizations are welcomed.

    Thank you
      • 28215
      • 4,149 Posts
      1. I recommend calling it ’getResourceField’, as getField is a misnomer (what if i wanted the field of a snippet?).
      2. I’ve optimized it to do the following:

      - Allow for blank values in the fields.
      - Allow for a ’default’ value to be returned, otherwise use blank
      - Only pull the fields from the DB that are necessary (lowers mem usage and sql queries)
      - Use MODx API defined methods
      - If the resource with specified ID is not found, dont fatal error, but return default value

      Here it is:

      <?php
      /**
       * getResourceField
       */
      $output = $modx->getOption('default',$scriptProperties,'');
      $field = $modx->getOption('field',$scriptProperties,'pagetitle');
      
      if (empty($scriptProperties['id']) || $scriptProperties['id'] == $modx->resource->get('id')) {
          /* use the already loaded resource */
          $resource =& $modx->resource;
      } else {
          /* grab only the fields we need, not the whole object */
          $c = $modx->newQuery('modResource');
          $c->select($modx->getSelectColumns('modResource','modResource','','',array('id',$field)));
          $c->where(array(
              'id' => $scriptProperties['id'],
          ));
          $resource = $modx->getObject('modResource',$c);
          if (empty($resource)) return $output;
      }
      
      if ($resource->getFieldName($field) === null) {
          /* if field isnt defined, look for TV value */
          $tvValue = $resource->getTVValue($field);
          if ($tvValue !== null) {
              $output = $tvValue;
          }
      } else {
          /* otherwise get field value */
          $output = $resource->get($field);
      }
      
      return $output;
      
        shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
        • 5340
        • 1,624 Posts
        Thanks,

        It works!

        • This looks great. Thanks to you both.

          I’ve been using this tiny snippet for resource fields:

          <?php
          /*
           * GetFieldValue 
           *
           * Example [[GetFieldValue? &id=`1` &field=`pagetitle`]]
           *
           */
          
          $resource = $modx->getObject('modResource', $id);
          if ($resource) {
             $value = $resource->get($field);
             return $value;
          }
          ?>


          And this little snippet for template variables:

          <?php
          /*
           * GetTvValue 
           *
           * Example: [[GetTvValue? &id=`1` &tv=`MyTv`]]
           *
           */
          
          $resource = $modx->getObject('modResource', $id);
          if ($resource) {
             $value = $resource->getTvValue($tv);
             return $value;
          }
          ?>


          It looks like this new getResourceField snippet would replace both and be more efficient. Am I right?
            Time is what keeps everything from happening all at once.
            • 28215
            • 4,149 Posts
            Yes.
              shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
            • Below you’ll find my own offering of a getResourceField snippet. It’s just a tiny rewrite of several ideas on this thread. I’ve already used it to successfully replace my two initial snippet hacks listed above.

              I started my own rewrite while trying to fix a warning error in the above snippet. I think this:

                  $c->select($modx->getSelectColumns('modResource','modResource','','',array('id',$field)));
              


              should become:

                  $c->select($modx->getSelectColumns('modResource','modResource','',array('id',$field)));
              


              Anyway, this one will optionally output a rendered TV (a feature that I needed) and it doesn’t create an unnecessary modResource when the field is a TV. Here it is, yet another getResourceField snippet (should I name it YAGRFS?):

              <?php
              /**
               *
               * getResourceField
               *
               * A snippet to grab a value from a field or a TV
               *
               * @ author Paul Merchant
               * @ author Shaun McCormick
               * @ version 1.0.0 - April 30, 2010
               *
               * OPTIONS
               * id - The resource ID
               * field - (Opt) The field or template variable name, defaults to pagetitle
               * isTV - (Opt) Set as true to return a raw template variable
               * processTV - (Opt) Set as true to return a rendered template variable
               * default - (Opt) The value returned if no field is found
               *
               * Exmaple1: [[getResourceField? &id=`123`]]
               * Example2: [[getResourceField? &id=`[[UltimateParent?]]` &field=`myTV` &isTV=`1`]]
               * Example3: [[getResourceField? &id=`[[*parent]]` &field=`myTV` &processTV=`1`]]
               *
              **/
              
              // set defaults
              $id = $modx->getOption('id',$scriptProperties,$modx->resource->get('id'));
              $field = $modx->getOption('field',$scriptProperties,'pagetitle');
              $isTV = $modx->getOption('isTV',$scriptProperties,false);
              $processTV = $modx->getOption('processTV',$scriptProperties,false);
              $output = $modx->getOption('default',$scriptProperties,'');
              
              if ($isTV || $processTV) {
                  // get the tv object
                  $tv = $modx->getObject('modTemplateVar',array('name'=>$field));
                  if (empty($tv)) return $output;
                  if ($processTV) {
                      // get rendered tv value
                      $tvValue = $tv->renderOutput($id);
                  } else {
                      // get raw tv value
                      $tvValue = $tv->getValue($id);
                  }
                  if ($tvValue !== null) {
                      $output = $tvValue;
                  }
              } else {
                  if ($id == $modx->resource->get('id')) {
                      // use the current resource
                      $resource =& $modx->resource;
                  } else {
                      // grab only the columns we need
                      $criteria = $modx->newQuery('modResource');
                      $criteria->select($modx->getSelectColumns('modResource','modResource','',array('id',$field)));
                      $criteria->where(array('id'=>$id));
                      $resource = $modx->getObject('modResource',$criteria);
                      if (empty($resource)) return $output;
                  }
                  $fieldValue = $resource->get($field);
                  if ($fieldValue !== null) {
                      $output = $fieldValue;
                  }
              }
              
              return $output;
              ?>


              Feedback or comments or fixes always welcome.
                Time is what keeps everything from happening all at once.
              • Great stuff Paul (and everyone)! I’m excited to see this kind of exploration and collaboration occurring around the API’s.
                  • 5340
                  • 1,624 Posts
                  Could someone give real life example for using processTV param?
                  I don’t really understand why would this be necessary.

                  Thank you
                  • Template Variables have raw values and processed (or rendered) values. For instance, if the raw value of a TV is @INHERIT, the processed value would be the actual inherited value. Output widgets applied to TVs are another example; a Delimited widget renders a particular formatted output from the raw value of the TV. This is the processed output.

                    Processing TV’s from other Resources in MODx however can create a lot of overhead, so the option is provided so cases where the processed output is not needed (or not wanted perhaps) that overhead is avoided. If you need the processed output of the TV though, you’ll have to set this property to 1 (Yes).
                      • 8522
                      • 145 Posts
                      thanks, this is very useful. just wanted to comment that it doesn’t get lost in the forums.
                      cheers
                      eni