How to Create Drupal Nodes with a Script

One of the most power features about Drupal is it's API. Sometimes it's necessary to manually create content such as a story or page (aka: nodes) using a PHP program/script. The current documentation about this is very limited or hard to follow. So I provide complete instructions here. They have been tested in Drupal 5.x but they should also work in version 6.x without much modification.

Consider the following example, lets create a new "Page". Set-up your PHP script as follows:

<?php require_once './includes/bootstrap.inc';drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);$new_page_node = array('type' => 'page');?>

The first two lines are required to initialize the Drupal system, function, and variables. The 3rd line creates a node object (an associative array). The index "type" tells Drupal the Content Type that we want to create. We use the internal system name of the content type here. You can substitute any content types that exists in your Drupal site, including ones you created with the CCK module.

For example, if I have a custom type called "Help File", and it's internal system name is "helpfile" then I would use the following code:

<?php...$new_page_node = array('type' => 'helpfile');?>

The next step is to fill out the fields. The fields are contained in an array variable. So lets say we wanted to specify the Page Title:

<?php$values = array();$values['title'] = "Welcome to Unibia";?>

The array variable name does not matter, I just chose that for no reason at all. The key piece here is the array index, this has to match up to the field you want to populate. Page nodes are simple. The only fields you need to worry about are "title" and "body". Their are two other important fields , "uid" is the user ID that this node is created as, and "name" is the username that this node is created as. To keep things simple, we will just use the admin user with ID 1. (Your admin user may have a different name).

<?php$values['title'] = "Welcome to Unibia";$values['body'] = "This is the content that appears on the page";$values['uid'] = 1;$values['name'] = "admin";$values['status'] = 1;?>

The "status" field with a value of "1" marks the new node as "Published".

TIP: If you've created a custom content type with custom fields using the CCK module, just include the additional fields in your code. However, bear in mind that CCK fields may need to be in the form of an array of arrays. For example:

<?php$values['field_address'] = array(array('street1' => '132 N Main St.', 'city' => 'Naples', 'state' => 'FL', 'zip' => '34100', 'country' => 'US'));$values['field_phone_number'] = array(array('value' => '239-123-1111'));?>

It's possible to take a look at the node/field structure by loading an existing node and printing out the array structure using PHP's print_r() function. First get the node ID of an existing node, just look at the link to and existing page. The end of the URL looks something like this: "node/2". The ID would be "2".

Let us load the node into an associative array by using the built in Drupal "node_load()" function:

<?php$existing_pagenode = node_load(2);print_r($existing_pagenode);?>

It's relatively simple, the function takes one argument, that is the node ID. It returns the node data structure. Then we just print out the array structure to our web browser. You'll have to look at the page source so it's better formatted. It should look similar to this:

stdClass Object
(
    [nid] => 2
    [vid] => 2
    [type] => page
    [status] => 1
    [created] => 1226008263
    [changed] => 1226010433
    [comment] => 0
...

You may ask yourself what "vid" stands for. Pay no mind to it for now, it simply refers to the revision number, usually the same as the node id.

Now for the last step, to actually save the node to the Drupal DB. It's as simple as one line.

<?php ...$result = drupal_execute('page_node_form', $values, $new_page_node);...?>

  • The first parameter is always in the following format, "_node_form". Tells Drupal to load the form for the node you are creating.
  • The second parameter is the array containing the fields and values.
  • The last parameter is the node variable

Lets say you want to categorize your new page, that is assign it a term/vocabulary that you created using the taxonomy module. It's not as difficult as you would believe. You do this part after you have created your node. The drupal_execute() function returns your node ID in the form of "node/XX" where XX is your node ID.

The PHP code to assign a term to a node is as follows:

<?php...$result = drupal_execute('page_node_form', $values, $new_page_node); //From above//Extract the node ID from the result string$nid = str_replace("node/", "", $result);//Get the term ID by name$term = taxonomy_get_term_by_name('Legacy');//Assign it to the nodetaxonomy_node_save($nid, $term);?>

That's all their is to it! However, lets say we want to update the newly submitted node. Just load it with the node_load() function and make your changes. The following example is done with a custom created Content Type using the CCK Module. You can apply the same concept by omitting the extra fields.

<?php$contact_node = node_load(32);$values['title'] = 'New Title.';$values['body'] = $node->body;$values['status'] = 1;$values['field_address'] = $node->field_address; //CCK Field$values['field_email'] = $node->field_email;  //CCK Field$values['field_fax'] = $node->field_fax;  //CCK Field$values['field_phone_number'] = $node->field_phone_number;  //CCK Field$result = drupal_execute('contact_node_form', $values, $contact_node);?>

When you have required fields (with CCK), you need to copy the existing values. Most of the time, you can omit the fields that don't need updating.

Their is another item worth mentioning which seems to also lack proper documentation. That is how to properly build the array for a CCK node reference field. It's very simple, but the lack of documentation can frustrate you. The example below assigns a node reference field named "mynode_reference" to the node with and id of 30:

<?php$values['field_mynode_reference'] = array('nids' => '30');?>

Once thing to add, their appears to be an issue in Drupal which prevents Drupal from properly assigning a node's author. To work around this issue, do insert the following code before executing "drupal_execute" (replace "uid" with the user id of the user you want to appear as the author).

<?php    global $user;    $user = user_load(array(uid => 1));?>

The above will tell Drupal to create nodes as the specified user. In this example, it's the admin user.

Comments

Fri, 11/05/2010 - 07:58

Very nice and useful samples! Thanks a lot :)

Couple of questions:
- is it possible to assign the list of terms in a simple way? I need to create nodes with up to 30 keywords. These keywords could be existent or new terms (which must be created upon save of a node).

- easy way of working with CCK field 'image file'? Can i just assign a file name like $values['filename'] = 'uploaded/file.name'?

Fri, 02/11/2011 - 15:37

warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'node_form' not found or invalid function name in /Applications/MAMP/htdocs/mwfmagDev/includes/form.inc on line 378.

Assembled you code fragments into this:

<?php

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

$values = array(); //for our variable values

global $user;
$user = user_load(array(uid => 1)); //load user 1 into global

$new_page_node = array('type' => 'page');

//load the data values we need
$values['title'] = "Test Page Node";
$values['name'] = "mwfadmin";
$values['uid'] = 1;
$values['status'] = 1;

$result = drupal_execute('page_node_form', $values, $new_page_node);

?>

Just wondering where I went wrong... Thanks!

hi there, i want to create a node using php(means *.tpl.php) file for my web application. My fields of the nodes are Object_name , Plan value, Real Value, date, Color(this filed must generate by application, example: if [plan value>Real value] -> color is red, if not green)

Actually i did create a file called {node-Objetivos.tpl.php} , inside the folder called sites->all->contemplates. then I write this code only to check if it works.

<?php print $node->field_name_objetivo[0]['view'] ?>
<?php print $node->field_plan_objetivo[0]['view'] ?>
<?php print $node->field_real_objetivo[0]['view'] ?>

=============================
please help me with this, itz important because I need this for my tesis.