Programmatically creating nodes using Entity Wrapper

Creating nodes via the UI in Drupal is easy, creating or updating them programmatically(in code) has always been a tedious. I've nearly lost my mind staring into the depths of a dpm($node);

The problem was the lack of straightforward API to handle the field level CRUD. You had to manually shove correctly formatted data into an object, often by comparing against an existing node's array. The correct old process went(and still can if you want!) like this:

// Create a new node
$node = new stdClass();
// Set the content type
$node->type = 'image';
// Add default values
node_object_prepare($node);
// Set the language
$node->language = LANGUAGE_NONE;
// Specify the author
$node->uid = $user->uid;
// Create textfield formatted data array
$data = array(
  array(
    'value' => 'Field value text',
    'format' => 'plain_text',
  )
);
$field_name = 'field_text_field';
// Locate the field's language
$langcode = field_language('node', $node, $field_name, NULL);
// Set the value
$node->{$field_name}[$langcode] = $value;
$node->title = 'Test node';
// Save the node.
node_save($node);

That process works and really isn't bad for small content types, but you already know where the problem occurs. You probably still have nightmares about that client's content type requirements list. When there many fields of multiple types on a node, to keep your sanity, you've got to create functions to build the data arrays and put it in the node. At some point you ask yourself, "Wait.. there has to be a better way." Don't worry! There is: http://drupal.org/project/entity

Effectively hidden in the Entity API module is the Entity Wrapper; described on the module page as "data wrappers that make use of the available information to provide a simple and unified access to entities and their properties." This greatly simplifies the process of creating or updating nodes. The above code can be simplified to:

// Create an Entity
$e = entity_create('node', array('type' => 'image'));
// Specify the author
$e->uid = $user->uid;
// Create a Entity Wrapper of that new Entity
$entity = entity_metadata_wrapper('node',$e);
 
// Specify the title
$entity->title = 'Test node';
 
// Add field data... SO MUCH BETTER!
$entity->field_text_field = 'Field value text';
// Save the node.
$entity->save();

Try it out on your next project. Soon you'll be adding:

dependencies[] = entity

to the .info file for every custom module.

Comments

These code lines, from your entity_metadata_wrapper usage example, generate an exception in Drupal 7.x:

// Create an Entity
$e = entity_create('node', array('type' => 'image'));
// Create a Entity Wrapper of that new Entity
$entity = entity_metadata_wrapper('node',$e);
 
// Specify the author
$entity->uid = $user->uid;
 

Apparently 'uid' isn't a valid property of $entity.

Oops! I compared this with my production code and changed it in the article text. You specify the author on the $node, not the $entity. The corrected code is:

// Create an Entity
$node = entity_create('node', array('type' => 'image'));
// Specify the author
$node->uid = $user->uid;
// Create a Entity Wrapper of that new Entity
$entity = entity_metadata_wrapper('node', $node);

Thank you!

The corrected code in the comment above is right, but there's a typo in the article text.
This line:
$node->uid = $user->uid;

Should be:
$e->uid = $user->uid;

Thanks!

Thanks for this. Very simple and understandable basic article about entity creation.

Sorry for the fast submit.

Do you have any preference wheter to use Entityreference or basic reference to reference nodes? I'm creating node with reference to other nodes and I'm thinking about which way to go

I generally use Entity reference for everything because I think it will be the easiest to migrate to Drupal 8 when needed.

It's good for less experienced people to also include global $user; at the top. They will understand it later. :)

Add new comment