drupal 7

HLKD7FOTW - element_get_visible_children()

Oh hey there. It's been more than a week hasn't it? Well shoot. Here's part two of my (now semi-) weekly series about a 'helpful lesser-known Drupal 7 functions' (HLKD7F Of The Week). I'm sharing fun Drupal 7 tidbits that I've discovered along the way; because even though they are obscure, they can be very helpful as a module or core developer.

Now I present... *drumroll* ...
element_get_visible_children()

Given a form or render-able page array element, it will return an array of the keys of the visible children 'contained' inside the element. It knows what sub-elements there are by use of the also-handy element_children() function. Typically you would use this for fieldset and container elements (the latter being new to Drupal 7). The return value can easily be cast into a boolean TRUE/FALSE value for use with '#access' properties.

Real world example

The Override Node Options module (led by timmillwood, and co-maintained by joachim and myself) makes a good example for how to use this function:

<?php
/**
* Implements hook_form_alter().
*/
function override_node_options_form_node_form_alter(&$form, $form_state) {
  ...
 
// Get a copy of the current node object.
 
$node = $form['#node'];

 
// Add access to the 'Authoring information' fieldset.
 
$form['author']['name']['#access'] = user_access('override ' . $node->type . ' authored by option');
 
$form['author']['date']['#access'] = user_access('override ' . $node->type . ' authored on option');
 
$form['author']['#access'] |= (bool) element_get_visible_children($form['author']);
  ...
}
?>

By selectively setting access to elements in node form's fieldsets, it would not be good if we hide all of a fieldset's elements, but still display an empty fieldset. That would be confusing. So for each fieldset the module alters, it also checks to see if there are any visible items left. It use the boolean OR operator (|=) on the Authoring information fieldset's access property because node.module's node_form() already defines $form['author']['#access'] = user_access('administer nodes'); and we want to only see the fieldset it if either the original access value is TRUE or the return value from element_get_visible_children() is TRUE.

In this case, here's is how the function gets its results:

Value of $form['author']['name']['#access'] Value of $form['author']['date']['#access'] Result of element_get_visible_children($form['author']) Result of (bool) element_get_visible_children($form['author'])
TRUE TRUE array('name', 'date') TRUE
TRUE FALSE array('name') TRUE
FALSE TRUE array('date') TRUE
FALSE FALSE array() FALSE

Best practices with hiding items

The above code from Override Node Options also highlights some best practices when you want to 'hide' elements on a form or page array. You should always use $form['myitem']['#access'] = FALSE; rather than unset($form['myitem']); as other modules that are altering the same form or page may also be altering that same element. When you use unset() the array no longer exists, so it would cause a PHP notice if a later form alter tried to do something like $form['myitem']['#title'] = t('My changed title');.

Add visibility checking by default for Drupal 8?

Maybe we should add a core patch for Drupal 8 to automatically check element_get_visible_children() before any container elements are rendered? Once a form has been altered it would be silly to output an empty fieldset, and it would be nice to not have this burden placed on every module that alters forms or page output. Read more

HLKD7FOTW - field_get_items()

Today chx and timplunkett inspired me to start a regular, short weekly blog post about my experience and knowledge with 'helpful lesser-known Drupal 7 functions' (HLKD7F Of The Week). So I'd like to start sharing these fun Drupal 7 tidbits because even though they are obscure, they can be very helpful as a module or core developer. So with that short introduction, I present... *drumroll* field_get_items().

Trying to get the raw data from a node's field can be confusing and complicated; field data is stored at least two levels deep from the entity object itself. For example, a simple taxonomy field stores its node data on the node object with the following structure:

<?php
stdClass
::__set_state(array(
  
'title' => 'My tagged node',
  
'nid' => '1',
  
'uid' => '1',
  
'type' => 'article',
  
'language' => 'und',
   ...
  
'field_tags' => array(
   
'und' => array(
     
0 => array('tid' => '5'),
     
1 => array('tid' => '28'),
     
2 => array('tid' => '29'),
    ),
  ),
))
?>

We cannot know for certain that the data in the 'field_tags' array is always associated with the unknown language ('und'), so this is where field_get_items() comes in handy. All we need to provide it with is an entity type, the entity object itself, and the field name and it will automatically determine what language the field's data is and return the array of items for you.

<?php
$items
= field_get_items('node', $node, 'field_tags');
var_export($items);
?>

Results:

array(
  0 => array('tid' => '5'),
  1 => array('tid' => '28'),
  2 => array('tid' => '29'),
)

It's important to note that if the specified entity has that field attached to it, but does not currently have any data, this will return an empty array(). But if the entity does not have that field attached (e.g. if my article content type did not have a field named 'field_tags'), then it will return FALSE. I highly recommend using this function rather than trying to get the values directly using statements like $items = $node->field_tags[LANGUAGE_NONE];. Read more

Contact module love

In the last week leading up to the end of the Drupal 7 code slush, there has been a flurry of work and love going into core's Contact module. I'd like to share what has been going on with everyone else.

Anonymous user access to personal contact forms

Contact module provides personal contact forms that allow users to contact other users on the site (e.g. user/1/contact). Unfortunately if you wanted to allow anonymous users to be able to contact users in the same manner, it just wasn't possible. In Drupal core, we should not limit functionality from anonymous users, but rather features should be linked to permissions for the site administrator to choose who can do what.

This feature request was originally posted on April 11, 2006 and was nearing a rivalry with the DBTNG issue for the highest number of comments for an issue. Obviously lots of people were interested in or needed this feature. I'm proud to announce that on the issue's exact three-and-a-half year anniversary, it has finally been committed to core! For those of you interested in this for Drupal 6, I am working on back-porting this functionality into the Anonymous Contact module.

This was Contact module's own personal node/8 so we can finally let it rest in peace. There were tons of people helping with that issue and I'd like to help recognize them. The following users all helped post patches and kept the issue driving: karschsp, matt@antinomia, David Lesieur, Owen Barton, pwolanin, TBarregren, coltrane, mrtoner, deviantintegral, rleigh, swaroopch, and jonhinkle. Several other people helped review: mfer, scottrigby, greg.harvey, binford2k. I could go on forever so I apologize if I left you out.

Official maintainer

I've been posting and reviewing patches for contact.module for a while now and was starting to feel personally responsible for it, so I asked to be added as the official maintainer and it was approved! I'm excited to be helping drive long-needed improvements and bug fixes to a module that doesn't get as much recognition as it's bigger brother modules. I'd also like to thank users gpk and andypost for helping out in several issues. Read more

Preparing your modules for Drupal 7

I know it seems like a far distance away and as much as you'd like to ignore it, Drupal 7 is coming and it will be awesome. Some ambitious developers have actually started with Drupal 7 version of their modules, but what if you just want to get a little head start? I'll show you a few ways that you can help prepare your Drupal 6 modules now to help make life easier when you full port to Drupal 7 later on. To see a list of all the current 6.x to 7.x module changes, view http://drupal.org/node/224333. Read more

Getting noticed for Drupal 7

Greg Knaddison at Growing Venture Solutions recently computed statistics for who are the top patchers and drivers for Drupal 7 so far (see full results here). Guess who's #4? Me! Occasionally it feels nice to be noticed. :)

Big congrats goes to catch, who is rocking things out at #1 and I will also most likely be working on a project with in the near future. There are also a lot of people providing 1-2 patches that are helping making Drupal 7, so let's keep building momentum and make this release the best yet!

Syndicate content