How Do I Make a Drupal “repeater field” with Field Collections (D7)

April 26, 2013

Up until now I’ve been mainly working in WordPress, mainly because of my love for ACF and their abilities to have repeating groups of fields. And I finally found a resource that helped me achieve the same user content manageability using Drupal. First off, you’ll need to install the Entity and the Field Collection modules by downlowding the files from the above links and putting the folders in the /sites/all/modules folder. After that dont forget to active them both in the admin at site.com/admin/modules

So now we can start setting ourselves up.

<?php
/**
* This function takes a field collection field and returns an object array that contains all of the field
* collection entity's fields. You can then use it the same way you would a node object. For example:
* $loaded_field_collection =  load_collection($node->your_field_collection);
* print 'check this ' . $loaded_field_collection->your_collected_field['und'][0]['value'] . ' value, sucka!';
*/
function load_collection($entity_uri) {
  $loaded_field_collection = entity_load('field_collection_item', array(0 => $entity_uri));
  foreach ($loaded_field_collection as $loaded_field_collection_object ) {
    return $loaded_field_collection_object;
  }
}
?>

And clear the cache at site.com/admin/config/development/performance
In fact, i just wrote a blog about how many times clearing the cache ended up being my problem.
So now you are ready to tackle the node.tpl.php file.  This works for other any of the other template files too, like node–news.tpl.php

<?php
/**
*
* For this example my content type was configured like this:
*
*  node
*   - top_level_collection
*     - second_level_collection
*        - text_1
*        - image_1
*        - third_level_collection
*         - text_2
*         - image_2
*     - second_level_collection_2
*        - text_3
*        - list_1
*        - image_3
*/

// check if field collection is not empty. If content exists, do some stuff.
if (!empty($node->top_level_collection['und'])) {
  //Your custom wrapper goes here
  print '<div class="collectin-it">';

  foreach ($node->top_level_collection['und'] as $a_top_level_collection) {
    //Use the load_collection() function to load your top level field collection's entity into an object.
    $top_level = load_collection($a_top_level_collection['value']);
    //You can use Devel's dsm() to view this object in the Devel tab of your node. Comment out or delete when everything's working well.
    dsm($top_level);

    //if your top_level_collection contains any fields, you can print them here using the $top_level object. Example: print $top_level->your_field['und'][0]['value'];

    //Use the load_collection() function to load your second level field collection entity object from the field in the top level field collection's entity object. All notes from the preceeding level apply.
    foreach ($top_level->second_level_collection['und'] as $a_second_level_collection) {
      $second_level = load_collection($a_second_level_collection['value']);
      dsm($second_level);
      foreach ($second_level->text_1['und'] as $a_text_1) {
        print '<p>' . $a_text_1['safe_value'] . '</p>';
      }
      foreach ($second_level->image_1['und'] as $a_image_1) {
        $var = array(
          'item' => $a_image_1,
          'image_style' => 'large',
          'path' => ''
        );
        print theme_image_formatter($var);
      }

      //Just like above, you can load the next level from the field in this level's field collection entity object.
      foreach ($second_level->third_level_collection['und'] as $a_third_level_collection) {
        $third_level = load_collection($a_third_level_collection['value']);
        dsm($third_level);
        foreach ($third_level->text_2['und'] as $a_text_2) {
          print '<p>' . $a_text_2['safe_value'] . '</p>';
        }
        foreach ($third_level->image_2['und'] as $a_image_2) {
          $var = array(
            'item' => $a_image_2,
            'image_style' => 'medium',
            'path' => ''
          );
          print theme_image_formatter($var);
        }
      }
    }
    //and finally, for the above mentioned case, you can go back to the $top_level object and load that second level field collection #2.
    foreach ($top_level->second_level_collection_2['und'] as $a_second_level_collection_2) {
      $second_level_2 = load_collection($a_second_level_collection_2['value']);
      dsm($second_level_2);
      foreach ($second_level_2->text_3['und'] as $a_text_3) {
        print '<p>' . $a_text_3['safe_value'] . '</p>';
      }
      foreach ($second_level_2->check_1['und'] as $a_check_1) {
        print '<p>Checklist value is: ' . $a_check_1['value'] . '</p>';
      }
      foreach ($second_level_2->image_3['und'] as $a_image_3) {
        $var = array(
          'item' => $a_image_2,
          'image_style' => 'thumbnail',
          'path' => ''
        );
        print theme_image_formatter($var);
      }
    }
  }
  //close your custom wrapper.
  print '</div>' . "\n";
}
?>

And that’s all you do! Thank you Rob W for all your contributions to Drupal and teaching me the ways of the Field Collections
Source

Stay in Touch!

Subscribe to our newsletter.

Solutions Architecture

browse through our blog articles

Blog Archive