Drupal: Working with Fields

Professional Article
October 1, 2012

I want to share what I consider to be the "Drupal way" of working with fields. Here we will go through such things as rendering fields, retrieving values of the field, and saving values in fields.

So, lets begin.

Most of the people work with fields this way. They usually drill down the whole entity that was loaded, whether it's a node or user entity or any other fieldable entity.

  1. // load a node entity with entity id 3
  2. $entity = entity_load_single('node', 3);
  3. // get the value of the field by drilling down the object
  4. $value = $entity->field_tags['und'][0]['tid'];
  5. // now we got the value of the field (which is a taxonomy reference field, that's why we have 'tid' instead of the default 'value' key)

But that's the wrong way of doing that, as we don't know what's the language used in this field and we always have to specify LANGUAGE_NONE ('und') and how many values does it store. We also may not know what's the final key is used to store the value, in our case it's 'tid' but usually in textfields it's 'value'.

So a proper way to retrieve the value will be by using field_get_items function.

  1. // load a node entity with entity id 3
  2. $entity = entity_load_single('node', 3);
  3. // get field items
  4. $items = field_get_items('node', $entity, 'field_tags');

This way we get the following $items values.

We can also render the field or view it's value, by using field_view_value function and field_view_field function:

  1. // load a node entity with entity id 3
  2. $entity = entity_load_single('node', 3);
  3. // get field items
  4. $items = field_get_items('node', $entity, 'field_tags');
  5. // get 1st item's value, also check the image below to see what exactly do we get
  6. $value = field_view_value('node', $entity, 'field_tags', $items[0]);
  7. // we get: <a href="/taxonomy/term/2" typeof="skos:Concept" property="rdfs:label skos:prefLabel">different</a>
  8. $rendered_value = render($value);

So basically we got the pre-rendered array, which we can tweak how we want, and then we rendered it. One should use this approach if he wants to render each value of this field separately, but there's another way of rendering the whole field, and it's by using the field_view_field function:

  1. // load a node entity with entity id 3
  2. $entity = entity_load_single('node', 3);
  3. // here we get a pre-rendered array of the whole field, with all items included
  4. $value = field_view_field('node', $entity, 'field_tags');

I must note that one can use the $display argument to specify which display should be used to render the item or field or you can actually pass an array of display settings (see the function details).

Saving values into a field is a bit tricky. There's no field_set_items. In our projects we use EntityMetadataWrapper. As all objects we get are stdClass instances (entities), they don't have any methods or properties, and what EntityMetadataWrapper does is wraps up that object into something really useful. Once we wrap our object in EntityMetadataWrapper we get lots of useful methods. For instance: 

  1. // load a node entity with entity id 3
  2. $entity = entity_load_single('node', 3);
  3. // wrap our entity in EntityMetadataWrapper of 'node' type
  4. $entity_wrapper = entity_metadata_wrapper('node', $entity);
  5. // set the value of the field
  6. $entity_wrapper->field_tags->set(array(1));

When we set the new value, we have to specify an array as this field is multi-value tagging type of field. If we use $entity_wrapper->field_tags->set(array(1, 2)); we will have the following values:

You are free to use other methods of the EntityMetadataWrapper, you can find'em all here.

My next article will be about Field Collection Items, how to work with them, create new field collection items programmatically and how to get field's and collection item's editing forms.

Comments:

Feel free to ask any question / or share any suggestion!