
I've been busy with a migration work for my client recently. There is an established website built with some proprietary CMS with a decent amount of articles / pages, different categories and user comments. My team was hired to make a complete migration from this money-sucking old-fashioned proprietary CMS to a modern shiny open-source Drupal 7. I like this kind of tasks. It’s always a pleasure to help people get rid of an old and proprietary technologies. To accomplish this task, I needed to create nodes, comments and taxonomies programmatically in Drupal 7, which is a pretty trivial task for Drupal 6. But in D7 with the introduction of entities and fields in core (aka CCK in core) things have changed a bit.
In today's post I'll show you how to programmatically create nodes, comments and taxonomies in Drupal 7. In detail you’ll find out how to:
- Programmatically create a node:
- Initialize a node object
- Add body field
- Add custom fields
- Add file / image field
- Add a term to a node
- Save a node
- Programmatically create a comment
- Programmatically create a term
1. How to programmatically create a node
1.1 Initialize a node object
$node = new stdClass(); // We create a new node object
$node->type = "page"; // Or any other content type you want
$node->title = "Your title goes jere";
$node->language = LANGUAGE_NONE; // Or any language code if Locale module is enabled. More on this below *
$node->uid = 1; // Or any id you wish
$node->path = array('alias' => 'your node path'); // Setting a node path
node_object_prepare($node); // Set some default values.
*We set LANGUAGE_NONE for $node->language, if you don’t have the locale module enabled, the node will not be assigned any particular language. So that's why we put here the constant LANGUAGE_NONE. In Drupal, nodes and fields can exist in more that one language, so if your site is multilingual you should specify the language code for your field. You can configure languages and get language codes by going this path in Drupal administration: Configuration -> Regional and language -> Languages.
1.2 Add a body field
// Let's add standard body field
$node->body[$node->language][0]['value'] = 'This is a body text';
$node->body[$node->language][0]['summary'] = 'Here goes a summary';
$node->body[$node->language][0]['format'] = 'filtered_html'; // If field has a format, you need to define it. Here we define a default filtered_html format for a body field
1.3 Add custom fields
// Let's add some CCK/Fields API field. This is pretty similar to the body example
$node->field_custom_name[$node->language][0]['value'] = 'This is a custom field value';
// If your custom field has a format, don't forget to define it here
$node->field_custom_name[$node->language][0]['format'] = 'This is a custom field value';
// And etc. you can add as much fields here as your content type has. The sky is the limit... and the server specs, of course ;)
1.4 Add file / image fields
// 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://'); // Save the file to the root of the files directory. You can specify a subdirectory, for example, 'public://images'
$node->field_image[LANGUAGE_NONE][0] = (array)$file; //associate the file object with the image field:
1.5 Add a term to a node
$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!
1.6 Save a node
$node = node_submit($node); // Prepare node for a submit
node_save($node); // After this call we'll get a nid
2. How to programmatically create a comment
// Let's create a managed object $comment = new stdClass(); // We create a new comment object
$comment->nid = $node->nid; // nid of a node you want to attach a comment to
$comment->cid = 0; // leave it as is
$comment->pid = 0; // parent comment id, 0 if none
$comment->uid = 1; // user's id, who left the comment
$comment->mail = 'email@example.com'; // user's email
$comment->name = 'User name'; // If user is authenticated you can omit this field, it will be auto-populated, if the user is anonymous and you want to name him somehow, input his name here
$comment->thread = '01/'; // OPTIONAL. If you need comments to be threaded you can fill this value. Otherwise omit it.
$comment->hostname = '127.0.01' // OPTIONAL. You can log poster's ip here
$comment->created = time(); // OPTIONAL. You can set any time you want here. Useful for backdated comments creation.
$comment->is_anonymous = 0; // leave it as is
$comment->homepage = ''; // you can add homepage URL here
$comment->status = COMMENT_PUBLISHED; // We auto-publish this comment
$comment->language = LANGUAGE_NONE; // The same as for a node
$comment->subject = 'Comment subject';
$comment->comment_body[$comment->language][0]['value'] = 'Comment body text'; // Everything here is pretty much like with a node
$comment->comment_body[$comment->language][0]['format'] = 'filtered_html';
$comment->field_custom_field_name[LANGUAGE_NONE][0]['value'] = ‘Some value’; // OPTIONAL. If your comment has a custom field attached it can added as simple as this // preparing a comment for a save
comment_submit($comment); // saving a comment
comment_save($comment);
3. How to programmatically create a taxonomy term
This one is the most easiest part of the tutorial. To create a term you just need to do the following:
$term = new stdClass();
$term->name = ‘Term Name’;
$term->vid = 1; // ‘1’ is a vocabulary id you wish this term to assign to
$term->field_custom_field_name[LANGUAGE_NONE][0]['value'] = ‘Some value’; // OPTIONAL. If your term has a custom field attached it can added as simple as this
taxonomy_term_save($term); // Finally, save our term
Well, that’s all for today my friends, hope this article helps you. Please leave your comments and additions and if you liked the post, share it on twitter and facebook, spread the knowledge!

Comments
Submitted by Rafael Silva on Mon, 05/23/2011 - 17:30
That's very nice, but I was wondering if you have considered using Migrate module. I recently used it to migrate some data to a D6 website and it was pretty slick!
Submitted by Tim on Mon, 05/23/2011 - 18:39
Yes, I know I could use this module, but I wanted to get an experience with D7's programmatic node / comments creation for my future projects, so I decided to choose my own custom way.
Submitted by Florian Loretan on Wed, 05/25/2011 - 16:06
You use $node->language as the language key in field structures:
$node->body[$node->language][0]['value'] = 'This is a body text';However, the language of the field is not always the language of the node. The language code to be used should be retrieved using field_language() instead.
Submitted by Tim on Wed, 05/25/2011 - 19:58
Useful note, can be used when you have multiple languages enabled, but it's no point to make things more complex when you know that you have no language defined. Thanks for the addition, Florian.
Submitted by Deep on Thu, 05/26/2011 - 15:09
But where this file should be stored? in module folder?
Submitted by Tim on Thu, 05/26/2011 - 17:48
Deep, this code can be used as a function in your custom Drupal module.
Submitted by mamoun.othman on Sat, 07/09/2011 - 16:02
Thanks for this article really helped me, I am using drupal 6 for creating a node programmaticlly, and in drupal 6 the function to save a term is
taxonomy_save_term($term);
maybe this will help someone like me found this article and working on drupal 6 ;)
Again thanks for sharing.
Submitted by penguin89 on Thu, 12/08/2011 - 09:35
I have a error when i using a query to read a node in a database to write in my database is: PDOException: in drupal_write_record() (line 6868 of C:\xampp\htdocs\emerald\includes\common.inc). my query can read data in db but it only read 7line in db, and it have a problem like this, so it's not work. Can you show me how to resolve my problem. Thanks
Submitted by Marc Isaacson on Fri, 01/20/2012 - 06:20
Thanks so much for this write up. It helped me to do exactly what I needed to do!
Add new comment