Urchin: Building a better API for Drupal

Urchin: Building a better API for Drupal

Urchin: Building a better API for Drupal

As web developers, we have numerous tools at our disposal to build a platform. Drupal is one such tool that we keep returning to, due to its flexibility, great community support and quick deployment. In the past year alone, Ashe Avenue has launched Drupal sites for everything from high volume magazines to grassroots music organizations, all with very aggressive launch schedules.

That being said, I actually want to discuss what Drupal does not do very well: present data in a consistent manner. As Ashe Avenue’s Lead Front-end Developer I have noticed that whether it’s a custom module, theme or whatnot, retrieving and displaying entity data is anything but uniform. Often, it ends up being a mess of node object references, scattered views, and render arrays peppered with various core function calls. These inconsistencies create code that is difficult to read, maintain and makes you want to sweep it under a rug.

In order to overcome these issues Tim Boisvert, Ashe Avenue Lead Developer, collaborated with me to create a better API for Drupal: Urchin. Our goal was to achieve the following:

• Create a chainable set of functions for querying the database for entities and their field data
• Create a function for retrieving a specific field’s data given an entity, no matter the field type
• Ensure that Urchin would be portable to any Drupal site

With these goals in mind, we created what became the core of Urchin, the Article and Node classes.

One of the great things that Drupal 7 introduced is the EntityFieldQuery (EFQ) class, which helps developers build database queries without having to write a number of joins and conditions. What’s not so great about EFQ is that it’s still pretty verbose. Let’s take a look at some sample EFQ code that’s written to load the ten most recent nodes of type ‘article’.

$query = new EntityFieldQuery();
$query->entityCondition(‘entity_type’, ‘node’)
           ->entityCondition(‘bundle’, array(‘article’))
           ->propertyCondition(‘status’, ‘1’)
           ->range(0, 10)
           ->propertyOrderBy(‘created’, ‘DESC’);
$result = $query->execute();

I should also mention that the above code only returns a result array of node IDs, which in turn must be loaded and looped through in order to finally display the relevant data. Contrast that code with the following Urchin statement, which returns a nice and clean associative array of node data after executing the query (no entity_load() calls necessary!):

Article::get()->limit(10)->sort(‘recent’)->execute();

So…what’s going on here? The get() function creates a new EFQ instance with a few predetermined settings and returns that instance for other chainable functions to manipulate. Each chainable function is essentially a shortcut for EFQ with a little added pizazz to make your life easier. The beauty lies in the simplicity of the execute() function, which does two very important things: 1) executes the EFQ instance and 2) loads the resulting node data using Node::getNodeData(). Without getting into too much detail, getNodeData() essentially loads all of the fields for each node using the getField() function, which is the magical function I described earlier that helps us retrieve any field type’s data.

The getField() function may seem simple, and it is, but we believe that it really streamlines the way a node’s field data is referenced. For example, you’re on a node template and you need to access a field named byline and you don’t want to use render arrays. You might write something like the following:

$node->field_byline[$node->language][0][‘value’]

Yikes! The above technique can get unwieldy with complicated data types — such as fields that support multiple values — and can throw errors if you aren’t careful due to a reference to an unset object property. Contrast the above with Urchin’s getField() below:

Node::getField($node, ‘field_byline’)

Easy peasy. getField() performs all the necessary isset() checks to avoid errors, supports multiple value fields, and even automatically loads and retrieves the data for node reference fields.

In addition the above examples Urchin contains many other functions that ease development. We feel that Urchin has exceeded our expectations in terms of making a Drupal site easier to use, maintain and scale. After installing it on a few sites, we open-sourced the tool to allow for community input.

While we feel that most Drupal sites will benefit from an Urchin installation, there is still more work to be done. Urchin is great at retrieving data, but currently it can’t manipulate or save data to the database. Furthermore, the Taxonomy functions are useful, but not as powerful as we would like them to be. These are features we plan to release in the near future and we gladly welcome any collaborators that would like to share in the development of Urchin.

Let me know: What features would you like to see in Urchin?

Heath Beckett

RELATED ARTICLES

Wireframe your “IDEA”

Wireframe your “IDEA”

Introduction It all begins with an idea in mind, often asked question how do we write specifications and why do we

READ MORE