Wednesday, March 28, 2012

Rendering fields correctly in Drupal 7

While searching for some field api stuff I stumbled on this rather good introduction to the Field API in Drupal 7 and specifically on how to read field contents in a safe manner. 

If you (as I did) read the below excerpt and feel a little guilty then you should most definitely read the full article


You may well have seen (or written!) code that looks something like this:

 
// This is WRONG example.
$block['content'] = $node->field_name['und'][0]['safe_value'];

Poking around the node object for the value you wanted to print was fairly common in Drupal 6, and the 'safe_value' sounds like it's been sanitised, right? What's wrong with that? Oh, Let me count the ways.
  1. Firstly, the ['und'] element is part of the field localisation in Drupal 7 (see this article from Gábor Hojtsy for more on that); directly accessing that value will cause issues in any kind of multi-lingual environment. Boo.
  2. By accessing the field value directly you miss out on any theming that might come courtesy of the normal field markup.
  3. The [0][safe_value] explicitly accesses the first value of the field - if you wanted every value from a multi-value field you'd need to do some sort of loop.
  4. Some fields (such as node references) won't have a safe_value element, only a value - which can easily be printed without thought for sanitisation. This is dangerous, not because node reference fields contain dangerous data (they're just a nid), but because it's not a helpful habit to get into, especially for new developers. Other fields types 'value' may well be highly dangerous.

Thanks, Stephen. I hearby wow never to repeat my sins against Drupal. Honestly.