Programmically Add/Edit Nodes in Drupal 7

There are quite a few references out there for how to programmically add and edit nodes – but I think I need my own. Lets first start with someone elses work that covers all of the basics.

The steps for programmatically creating a node are:

  • Create a PHP object representing the node data
  • Save the object using the node_save() function

While the mechanics are simple, there is an important responsibility involved. The Drupal work flow does data validation before calling the node_save() function; node_save() does no validation. By calling node_save() directly your code takes the responsibility for providing valid data.

Basic Node Creation

The following code assumes an unchanged Drupal 7 Standard installation and will create a Drupal 7 article node.

$body_text = 'This is the body text I want entered with the node.';
$node = new stdClass();
$node -> type = 'article';

$node->language = LANGUAGE_NONE;
$node->uid = 1;

$node -> title = 'Node Created Programmatically on ' . date('c');
$node -> language = LANGUAGE_NONE;
$node -> body[$node -> language][0]['value'] = $body_text;
$node -> body[$node -> language][0]['summary'] = text_summary($body_text);
$node -> body[$node -> language][0]['format'] = 'filtered_html';
$path = 'content/programmatically_created_node_' . date('YmdHis');
$node -> path = array('alias' => $path);
$node = node_submit($node); // Prepare node for a submit


  • The node_object_prepare() function does a number of useful things:

    • Provides the default values for the status, promote, sticky, and revision flags. These values are type specific if $node->type is defined, and can be modified as required.
    • Makes the current user the node owner by setting the $node->uid. (Note: If you are running from drush and haven’t explicitly set a user, the node owner will be the anonymous user, typically UID 0.)
    • Runs hook_prepare and hook_node_prepare on the object.
  • Node and Field API hooks called by node_save() may alter the saved data. For example, if the Pathauto module is enabled it will override the path given in this example.

  • A list of Node and Field API hooks called during node_save() is available at the Drupal API Reference Site: Node API Hooks.


The LANGUAGE_NONE string constant value is und. It’s useful to know this if you’re ever looking at the node data values.

You can set this yourself

$node->language = LANGUAGE_NONE;

User ID

  • User 0 is Guest
  • User 1 is Super User
  • You can get the current User ID with
global $user;
$node->uid = $user->uid;


Editing simply involves loading, changing and saving as follows;

$nid = 1;
$node = node_load($nid);
$node->title = 'Updated Title Text';


Fields are quite complicated. There may be a single field

$node->field_custom_name[$node->language][0]['value'] = 'This is a custom field value';

or multiple, depending on the field type

$node->field_custom_name[$node->language][0]['value'] = 'This is a custom field value';
$node->field_custom_name[$node->language][0]['format'] = 'full_html';

Also, some fields may have multiple values.

Body is a field of type Text Area.


Revisions are a handy method for keeping a record of changes, programmatic or otherwise. If humans are involved in a review process they can also provide a measure of comfort and clarity by confirming what the program changed and what was preexisting, and providing the human reviewer a mechanism for undoing the change.

The following example assumes there is a pre-existing node with the node id (nid) of 1. The $node->log value isn’t required but is useful.

$nid = 1;
$node = node_load($nid);
$node->body[$node->language][0]['value'] .= "\nA line of text added by program.";

// Make this change a new revision
$node->revision = 1;
$node->log = 'This node was programmatically updated at ' . date('c');



// Some file on our system
$file_path = drupal_realpath('somefile.png'); // Create a File object
$file = (object) array(
    'uid' => 1,
    'uri' => $file_path,
    'filemime' => file_get_mimetype($filepath),
    'status' => 1,
$file = file_copy($file, 'public://');
$node->field_image[LANGUAGE_NONE][0] = (array)$file; // associate the file object with the image field:
  • Save the file to the root of the files directory. You can specify a subdirectory, for example, public://images


$node->field_tags[$node->language][]['tid'] = 1;

field_tags here is the name of a term reference field attached to your content type, ‘1’ is a term id you wish to assign to a node. Simple!

Don’t worry about which vocabulary it is from as each term has its own ID.

Leave a Reply