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.

Drupal 7 Changes

A quick note for those of you familiar with Drupal 6. You'll notice two changes in Drupal 7:

Body Field Is No Longer Special

In Drupal 6 the body field was special. Specifically, it had a different data structure than other fields and it always existed, even if it wasn't used. With Drupal 7 the body field is a standard field provided by core and is truly optional.

Language

Language specification is required for the node and some fields.

Filter Format

The format of the text field filter is now specified by machine name, not integer. For example: full_html, filtered_html, or plain_text. This is great news for moving contents between different Drupal systems.

Basic Node Creation

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

<?php/** * Basic Node Creation Example for Drupal 7 * * This example: * - Assumes a standard Drupal 7 installation * - Does not verify that the field values are correct */$body_text = 'This is the body text I want entered with the node.';

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.Here is the data structure of $node after node_object_prepare() is called:

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.

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

The $node->body[$node->language][0]['format'] = 2 statement sets the Text format of the Body field to Filtered HTML. It is possible to set text format to a value the node owner isn't permitted to use, which will almost certainly cause undesirable consequences. Format values can be changed from the Administration menu, so be careful about what you assume.

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.

Updates

To update a node simply load it, make the changes, and then save it. The following example assumes there is a pre-existing node with the node id (nid) of 1.

Remember, you are responsible for insuring the data being saved is valid.

Revisions

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.

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

node_save($node);?>

After running the program the revision tab will display the update:

Understanding the Data Structures

There's no master directory of node data structures. The most reliable way to understand the data is checking the code. This may not be easy and I can not provide specific guidance. Here are some places I've found the information required to give me an understanding of a data structure.

Trusted examples:There are a number of well maintained modules that create Drupal content programmatically. Seeing how they deal with particular fields can be helpful.

Node Content Form Code:The HTML forms used for adding and editing node content can provide understanding for how a field is properly used. In particular, the form validation. Because the code is generalized it is often difficult to home-in on the correct code unless you're familiar with Form API and how the code is called during a form submit.

Node and Field Hooks:After determining the module responsible for saving the data check the code in applicable node and field hooks.

Module schema:The data structure used in code is usually an analog of the structure used in the database. Drupal database tables are defined with schema that usually describes each database column. The schema definition can be seen using the Schema module or viewing the .install file of the applicable module.

Viewing Data Structures

The drush command line and/or the Devel module's Execute PHP code block can be used to display data structures. Here are sample commands for displaying a node object:

drush: drush php-eval "print print_r(node_load(12), 1)"

PHP block: dpr(node_load(12));

The "dpr" function uses the PHP print_r function to display the value. The Devel module has a number of other functions which use different display functions (e.g.: var_dump, krumo) and print to either the message area or display in the browser.

If you've discovered a research process, useful technique, or reference I haven't mentioned please be sure to add it to comments.

Note: This article was updated to reflect the final version of the API.

On a somewhat related note, it seems the ability to load nodes by a number of params, as opposed to just the node ID, has disappeared in D7 (see: http://api.drupal.org/api/function/node_load/7). For example, you can do this in D6 to return a node object:

Thanks for mentioning it. The function is cool because it works for any Drupal form. It can be very tedious figuring out the Form API array structure, though. I used it for something in Drupal 5, but don't think I've every used it to create nodes.

Maybe I'm missing something here, but I don't see how node_object_prepare() can actually affect the $node object: in D7, the variable $node is NOT passed by reference to the function, and the function returns nothing...

But Drupal 7 core itself uses this syntax in node_form(), so there must be something I don't get, but what? ;)

I can't find a good online explanation, which is sad, so here goes mine.

The $node variable is a handle to the object. Although the object handle is passed by value it still points to the same object; for common situations it's essentially the same as passing by reference. Since the object handle in the function and the calling code both point to the same object, changes made in the function are seen outside the function. It's like passing a pointer, but apparently it's more correct to call it a handle.

Thanks for pointing that out, Anonymous.
In one of the alpha releases the method of specifying filter format was changed from from integer to machine name. This is a really great change. It makes the code more transportable across Drupal systems.

Could you explain where it is possible to put these code snippets? What context or bootstrap is needed?

I would like to import a blog in Drupal (all provided solutions are half good and half bad...). I just want to make some sql queries on the blog database to get title/body and then insert it in Drupal with your examples. Can I make a standalone script or should I include my code somewhere in D7?

Your node creation code is very much helpful.The code is working fine.But I have to put this code in my custom module.For that this code should be inside a function.Now I am not getting any way how to put this code inside a function or what the other way to incorporate this to my module.Please suggest me ASAP.

There is a big issue with this command in that it bypasses all Drupal access restrictions in updating/adding/or deleting a node. This could lead to huge vulnerabilities if placed in the wrong place and found by the wrong people.