3

How can I properly render a field collection ? Is there any specific function for that ? I tried field_view_field but it does not output children fields.

My field collection is attached to a line item entity, and I want to display it in a Commerce checkout pane review.

function mymodule_pane_review($form, $form_state, $checkout_pane, $order) {
  //loading line item
  $line_item = commerce_line_item_load($order->commerce_line_items['und'][0]['line_item_id']);
  //loading field_collection from its id
  $paxsup = entity_load('field_collection_item', array($line_item->field_paxsup['und'][0]['value']));

  return drupal_render(field_attach_view('field_collection_item',$paxsup, 'full'));
}

but get an error EntityMalformedException: Missing bundle property on entity of type field_collection_item

EDIT : I got a step forward, with the use either of

$paxsups = entity_load('field_collection_item', array($line_item->field_paxsup['und'][0]['value']));
$paxsup = end($paxsups);
//or shortcut, as per Marcvangend
$paxsup = field_collection_field_get_entity($line_item->field_paxsup['und'][0]);

dsm($paxsup) now returns

dsm($paxsup)

So I can output a child field with

$view = field_view_field('field_collection_item', $paxsup, 'field_paxsup_civilite', $display);
return drupal_render($view);

EDIT 2: I ended chaining #markup

$display = array('label' => 'hidden');
$cv = field_view_field('field_collection_item', $paxsup, 'field_paxsup_civilite', $display);
$nom = field_view_field('field_collection_item', $paxsup, 'field_paxsup_nom', $display);
$prenom = field_view_field('field_collection_item', $paxsup, 'field_paxsup_prenom', $display);
$date = field_view_field('field_collection_item', $paxsup, 'field_paxsup_datenaiss', $display);
$view .= $cv[0]['#markup'] .' '. $nom[0]['#markup'] .' '. $prenom[0]['#markup'] .t(', né(e) le '). $date[0]['#markup'] ;

But I'm not happy with this "old style" solution, would have preferred to find a more elegant and Drupal way to output that field collection

2 Answers 2

2

You may want to have a look how the field_collection module itself renders field collections in the field_collection_field_formatter_view function. I think it's important to note that is uses field_collection_field_get_entity() to load a field collection.

Looking at the code (not tested) I think you can do something like this:

if ($field_collection = field_collection_field_get_entity($line_item->field_paxsup['und'][0])) {
  return $field_collection->view('full');
}
6
  • Thanks for you answer ! Out of the box, your snippet returns field_collection_item: ? Not sure I understand how you suggest to use it.
    – Kojo
    Aug 22, 2014 at 13:12
  • OK, I don't know what the rest of your code does so that's hard to debug for me. You could try return drupal_render($field_collection->view('full')); instead. Also, make sure the full view mode of the field collection is configured correctly. Aug 22, 2014 at 13:15
  • 1
    Of course you can't do the job for me ;) I edited the question with my progress. field_collection_field_get_entity is a kind of shortcut that gives me the full FieldCollectionItemEntity, but I still feel stupid on how to render all children fields
    – Kojo
    Aug 22, 2014 at 14:02
  • I think it better to not go into the field collection and take specific field out of it, but rather navigate to /admin/structure/field-collections and click the 'manage display' link for your field collection. That page should allow you to configure the visibility, formatter and order of the fields in your field collection. Does that answer your question? Aug 22, 2014 at 14:51
  • Not really, sorry : as you can see in dpm($fieldcollection), there's no view property in FieldCollectionItemEntity object. So $field_collection->view('full') or similar fails. I already went several times to related manage display page and tried all possibilities :(( At the moment I ended chaining #markup of each field_view_field child array, which is a horrible solution
    – Kojo
    Aug 22, 2014 at 15:06
0

Just to expand on the above answer if you put the below into a node preprocess it should work

function MODULETHEME_preprocess_node(&$variables) {
  // ...
  foreach ($variables['field_conference_day'] as $day) {
    if ($field_collection = field_collection_field_get_entity($day)) {
      $conference_days[] = drupal_render($field_collection->view('full'));
    }
  }
  $variables['conference_days'] = $conference_days;
  // ...
}

You can then render $conference_days in your theme node template file.

Note that field_collection_field_get_entity wants a field item. Always good to check the source code.

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.