4

I'm trying to print a field from an entity reference field - but I don't have a clue how to do it!

A bit of background: I've got two content types - master and variation. Variation includes an entity reference field, pulling in fields from the referenced master. But they share an image field. When the variation's image field is empty, I need the master's to display in its place. On the other hand, if the variation's image-field is in use, the masters needs to be hidden. My first thought was to use a display mode, but as you can see I need a little more flexibility than that.

So the details.

A dpm($node) on a variation node gives me:


... (Object) stdClass

field_master_reference (Array, 1 element)

--und (Array, 1 element)

----0 (Array, 3 elements)

------target_id (String, 2 characters ) 11

------entity (Object) stdClass

--------(list of lots of strings which I'll leave out for concision)

--------field_country (Array, 1 element)

--------field_publisher (Array, 1 element)

--------field_catalog (Array, 1 element)

--------field_main_image (Array, 1 element)

----------und (Array, 1 element)

------------0 (Array, 13 elements)

--------------fid (String, 2 characters ) 10

--------------alt (String, 0 characters )

--------------title (String, 0 characters )

--------------width (String, 3 characters ) 518

--------------height (String, 3 characters ) 360

--------------uid (String, 1 characters ) 1

--------------filename (String, 21 characters ) testimage99_r1_c1.png

--------------uri (String, 38 characters ) public://masters/testimage99_r1_c1.png

--------------filemime (String, 9 characters ) image/png

--------------filesize (String, 4 characters ) 4627

--------------status (String, 1 characters ) 1

--------------timestamp (String, 10 characters ) 1366482521

--------------uuid (String, 36 characters ) 67gf4dbb-0a37-4ee9-893e-6g51e3et33c1

------access (Boolean) TRUE

(miscellaneous other fields which I leave out)


I've bolded the relevant structure. From it, how do I print field_main_image (as a fully rendered image)? Sincere thanks to anyone who can help me with something that has perplexed me since Wednesday.

2 Answers 2

6

You could do this using either of these:

  • hook_node_view() in your own custom module
  • hook_preprocess_node() in your theme template.php

Here's an example of both of these methods. The idea is the same as what rooby suggested earlier but you need to modify the content of the node, not the fields.

Example 1: hook_node_view(), can be used in a custom module.

    // Implements hook_preprocess_node();
    function mycustommodule_node_view($node, $view_mode, $langcode) {

      $field_name = 'field_main_image';

      // Check that the field exists in our node and that it has no content.
      // Alternatively we could check $node->type.
      if (
        isset($node->$field_name) &&
        empty($node->$field_name)
      ) {

        // Use entity metadata wrapper to gain easy access to referenced entities.
        // This method is more reliable than digging the field array.
        $node_wrapper = entity_metadata_wrapper('node', $node);
        if ($node_wrapper->field_master_reference->raw()) {

          // Get the referenced node object.
          $master = $node_wrapper->field_master_reference->value();

          // Use field_view_field to get the renderable content of the field.
          // Save this data in $node->content so that node template can output it. 
          $node->content[$field_name] = field_view_field('node', $master, $field_name);
        }
      }
    }

Example 2: hook_preprocess_node(), can be used in theme template.php.

    // Implements hook_preprocess_node();
    function mycustomtheme_preprocess_node(&$vars) {

      $node = $vars['node'];
      $field_name = 'field_main_image';
      if (
        isset($node->$field_name) &&
        empty($node->$field_name)
      ) {
        $node_wrapper = entity_metadata_wrapper('node', $node);
        if ($node_wrapper->field_master_reference->raw()) {
          $project = $node_wrapper->field_master_reference->value();
          $vars['content'][$field_name] = field_view_field('node', $project, $field_name, array(
          'type' => 'image',
          'settings' => array(
            'image_style' => 'thumbnail',
            'image_link' => 'content',
          ),
        ));
        }
      }
    }
3
  • You, sir, are a scholar and a gentleman. The preprocessing code worked perfectly. Thankyou! Commented Apr 21, 2013 at 23:53
  • Oh yeah, you're totally right about my answer and the content array. - Also note that your code depends on the entity module.
    – rooby
    Commented Apr 22, 2013 at 0:26
  • I've updated the code above with formatting options. This is the code I've ended up using. Thanks again Juhog not just for writing the code, but for the explanatory comments which have taught me a lot about usage of entity_metadata_wrapper and field_view_field. Commented Apr 28, 2013 at 6:31
1

This is off the top of my head but does it work?:

/**
 * Implements hook_node_view().
 */
function MYMODULE_node_view($node, $view_mode, $langcode) {
  if ($node->type == 'variation') {
    $img_lang = field_language('node', $node, 'field_main_image');
    // If the image is not set on the variation, use the master image.
    if (!isset($node->field_main_image[$img_lang][0])) {
      $ref_lang = field_language('node', $node, 'field_master_reference');
      if (isset($node->field_master_reference[$ref_lang][0]['entity'])) {
        $ref_img_lang = field_language('node', $node->field_master_reference[$ref_lang][0]['entity'], 'field_main_image');
        if (isset($node->field_master_reference[$ref_lang][0]['entity']->field_main_image[$ref_img_lang][0])) {
          $node->field_main_image[$img_lang][0] = $node->field_master_reference[$ref_lang][0]['entity']->field_main_image[$ref_img_lang][0];
        }
      }
    }
  }
}
1
  • Thanks for your help, Rooby! I've more experience adding to template.php than creating custom nodes, so I went with the preprocessing code from the other reply. But for the sake of curiosity, if I get time when I finish this project, I will return and test this code. Thank you! Commented Apr 21, 2013 at 23:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.