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
(Statically copied from previous site)
Christopher replied on March 11, 2013 - 6:14pm
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.
brad replied on March 12, 2013 - 11:41am
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!
Ed replied on November 1, 2013 - 9:13am
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;
brad replied on November 4, 2013 - 10:36am
Thanks!
Oskari replied on January 11, 2014 - 4:27am
Thanks for this. Very simple and understandable basic article about entity creation.
Oskari replied on January 11, 2014 - 4:29am
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
brad replied on January 11, 2014 - 2:23pm
I generally use Entity reference for everything because I think it will be the easiest to migrate to Drupal 8 when needed.
Nick replied on February 5, 2014 - 9:39am
It’s good for less experienced people to also include global $user; at the top. They will understand it later. :)
Bronius Motekaitis replied on August 26, 2015 - 9:17am
Thanks for sharing. I have seen a dozen or so “how to create nodes in Drupal 7” tuts now, but nobody seems to address how to set field-defined default values on fields. node_object_prepare seems to set node properties but not field defaults. Any ideas?
I’ve posed the same question at d.o on entity issue queue: https://www.drupal.org/node/2558005
brad replied on September 11, 2015 - 1:15pm
Hi Bronius, I’m actually not sure at this time. Maybe someone else knows? You can always check the field default values through Field API, but there is probably an easier way.