Headless Drupal Revisited: Programmatic Manipulation of CCK Defined Nodes

March 13, 2009

In my previous Headless Drupal post, I proposed ways to work with Drupal content programmatically, particularly for bulk tasks like updating many nodes.

But, in that post, I conveniently only covered plain vanilla Drupal nodes; what if the nodes you need to work with have CCK (Content Construction Kit module) defined fields? These are specified through Drupal’s administrative GUI, and so, its not obvious how to programmatically reference them.

This post will show you the way that I commonly deal with this situation, and I’m embarassed to say, it relies more on knowing a few Drupal tricks than any deep knowledge of the inner workings of Drupal. But these methods easily and reliably show you how to programmatically reference, access and change CCK defined fields just like any other node attribute.

Using Views to Build Complex Queries

If you’ve read any other Drupal posts on my blog, you know how much I love contributed modules. The Views module is quite possibly the module I use most on every site I build, and it is especially powerful when paired with CCK.

The Views module essentially provides a visual query builder for Drupal content and although I usually dislike these types of tools, the Views module is robust, powerful and easy to use once you get used to how it is organized. Its surprising effective.

I’m not going to get into the nuts and bolts of editing views, as that is best learned elsewhere. But, as you build your content query in the Views module administration screens, you will see the option to display a preview of the view, and if you do so, below the preview, you will see the underlying query that Drupal is executing to create the view:

The query being executed behind a view.

The query being executed behind a view.

In this case, I have a CCK field called ‘Masthead’ defined on page nodes, and I have added it as a field in the view. To see all of the available CCK defined fields you can add, select the “Content” option under “Groups” when adding fields to a view:

Selecting CCK fields to display in a view.

Selecting CCK fields to display in a view.

So, when I preview the view, I see this query being executed:

SELECT node.nid AS nid,
   node.title AS node_title,
   node.type AS node_type,
   node.changed AS node_changed,
   node_data_field_masthead.field_masthead_value AS node_data_field_masthead_field_masthead_value,
   node_data_field_masthead.nid AS node_data_field_masthead_nid
 FROM node node
 LEFT JOIN content_field_masthead node_data_field_masthead ON node.vid = node_data_field_masthead.vid
 WHERE node.type in ('page')
   ORDER BY node_changed DESC

And now I can just plug this query into my “headless Drupal” scripts:

<?php
$my_query = "SELECT node.nid AS nid,
   node.title AS node_title,
   node.type AS node_type,
   node.changed AS node_changed,
   node_data_field_masthead.field_masthead_value AS node_data_field_masthead_field_masthead_value,
   node_data_field_masthead.nid AS node_data_field_masthead_nid
 FROM node node
 LEFT JOIN content_field_masthead node_data_field_masthead ON node.vid = node_data_field_masthead.vid
 WHERE node.type in ('page')
   ORDER BY node_changed DESC";

error_reporting(E_ALL);
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

$results = db_query($my_query);
while ($result = db_fetch_object($results)) {
  echo 'A masthead value: ' . $result->node_data_field_masthead_field_masthead_value  . '<br />';
}

Its that simple. So, if you need a complex query in a headless Drupal script and aren’t sure how to formulate it, you can simply build it using a view and cut and paste the underlying query in your script.

Now what if I want to update CCK defined fields on node objects?

Using Contemplates to Inspect Node Objects

Another module to the rescue: the Contemplates (Content Templates) module allows you to modify how the body of a node is displayed, and like Views, it complements CCK well.

And similar to Views, when you create content templates, you will see how to reference CCK fields as node object attributes. Returning to my page node/masthead field example, I am going to start by going through the initial steps to create a content template, by navigating to the appropriate administration screen:

  1. go to Content management
  2. click on Content templates
  3. then click on the Create template link corresponding to the page node

Now, I’m not actually going to complete the process of creating a content template for pages, because I am satisfied with the default. The important thing is that on this screen, I can see how to reference node attributes by clicking on the Body section link, then the Body Variables section link:

View node attributes using content templates.

View node attributes using content templates.

Once I have all the information I need, I can back out of the Content Templates creation screen if I don’t actually want to change the page body.

Be aware that this functionality relies on the existence of sample content in the site, so I had to make sure that I had at least one populated page node on the Drupal site for this to display the fields. Scrolling through this display, I see how I can reference the Masthead field value on a node:

$node->field_masthead[0]['value']

So, armed with this information, and using the previous headless Drupal approach, I could change one Masthead value to another like so:

<?php
error_reporting(E_ALL);
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

$results = db_query('select nid from node where type="page"');
while ($result = db_fetch_object($results)) {
  $node = node_load($result->nid);

  if ($node->field_masthead[0]['value'] == 'This Masthead?') {
    $node->field_masthead[0]['value'] = "That Masthead!";
  }

  if ($node->validated) {
    node_save($node);
  } else {
    echo 'Node: ' . $node->title . '(' . $node->nid . ') was not saved. <br />';
  }
}

6 Comments

Comment by edavison
2009-07-13 11:02:28

I must say that this is just the sort of drupal power programming know-how that I have been looking for! Thank you very much for these articles on headless drupal.

A follow-up question: Do you know how I would go about doing a bulk permissions update to allow all user roles to view all CCK fields as seen under http://somesite.com/admin/user/permissions?

Comment by admin
2009-07-14 08:26:07

Sounds like a good idea for a future post…

 
 
Comment by Kitaj
2010-04-14 00:35:50

Thank you for your “headless Drupal series”. With it I finally managed to import content from a proprietary CMS and migration to Drupal is now in sight.

 
Comment by Tim
2010-05-21 04:00:47

I would recommend the devel modul to inspect nodes and their fields. If you have installed the devel module, you get another tab in your node which displays all fields and their values of the specified node. IMO thats much more easy than using the contemplate module, which is bad in other ways, but thats a different story.

 
Comment by Xbox 360
2010-07-09 05:57:22

With you excellent series (headless Drupal series), my migration to Drupal is now just around the corner!

 
Comment by Cord
2010-08-15 14:35:56

Headless Drupal series are FANTASTIC!
Explaining everything for me.

Thank you!

 

Sorry, the comment form is closed at this time.