Here are some tips on how to create a node programmatically in a Drupal module. The safest way to create a node is to use the drupal_execute() function which simulates the submission of a form [see API documentation]. This function accepts a variable number of arguments: 1) $form_id; 2) $form_state; and 3) any additional arguments. When creating a new node, the 3rd argument should be a $node object.
The $form_id should be formatted: NODETYPE_node_form. To confirm this, you could use hook_form_alter to show the form IDs for the current page (NOTE: you'll have to be on node/add/NODETYPE to display the node form ID).
<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
echo $form_id . "<BR>";
}
?>For the second argument, you'll have to create an array that contains $form_state values (the data submitted from the node/add/NODETYPE form). Here is a basic $form_state array:
<?php
$form_state = array();
$form_state['values'] = array(
'title' => t('MYTITLE'),
'body' => t('MYBODY'),
'name' => $GLOBALS['user']->name,
'op' => t('Save'),
);
?>If you are creating a more complex node type, you'll want to include more information in in the $form_state['values'] array. I find it helpful to view the submitted node form data using the following code:
<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
// ensure we are modifying the right node type
if ($form_id == 'NODETYPE_node_form') {
// add an additional validation handler
$form['#validate'][] = '_MYMODULE_node_form_validate';
}
}
function _MYMODULE_node_form_validate($form, &$form_state) {
// display the submitted data and then die
echo "<pre>";
print_r($form_state['values']);
echo "</pre>";
die;
}
?>Now, if you create a test node (node/add/NODETYPE), you'll see the data that's being submitted from the form. NOTE: be sure to remove these two functions when you are familiar with the structure of the $form_state variable.
The 3rd argument will be a (mostly) empty $node object containing the node type:
<?php
$node = (object) NULL;
$node->type = 'NODETYPE';
?>Here's a code snippet that shows all the pieces together:
<?php
// create $form_state
$form_state = array();
$form_state['values'] = array(
'title' => t('MYTITLE'),
'body' => t('MYBODY'),
'name' => $GLOBALS['user']->name,
'op' => t('Save'),
);
// create $node
$node = (object) NULL;
$node->type = 'NODETYPE';
// include node file, necessary for node generation
module_load_include('inc', 'node', 'node.pages');
// create node using drupal_execute
drupal_execute('NODETYPE_node_form', $form_state, $node);
?>





















Comments
How to update the form using it
I need to update the node instead of adding new one. Is it possible in the drupal_execute()?
node_save
node_save is a great alternative to drupal_execute. In this tutorial, I wanted to show how to use drupal_execute. I find myself using node_save more these days...
-Eric
Thanks so much
I just keep coming back to this blog post again and again. Very informative. And since this post comes up so often while Googling, it makes it much easier to find!
How can I access the 'nid' of the node just created?
I have made a custom form to create the node, and I need to combine the 'nid' of the node that is created with drupal_execute() with a value from the submitted form to create a cross-reference. Since I don't have $form_state in scope during the insert op in hook_node_api(), I need to handle in my submit function.
Any reliable way to get the 'nid' of the node we just created with drupal_execute()?
Thank you.
return value
Unfortunately, drupal_execute() will not supply what you are looking for, since the executed form has no standard return value. You could query the database using the submitted data from the custom form.
Is this a CCK node? Another approach would be to use the CCK node form and use hook_form_alter() to modify the form to your liking.
drupal_execute versus node_save when creating new nodes?
Is there any benefit in using drupal_execute() over a simple node_save() when creating new nodes programmatically?
Thanks,
Bogdan.
first thing that comes to mind
Hi Bogdan,
The first thing that comes to my mind is the validation handlers.
Regards,
Eric
Isn't node_submit() supposed
Isn't node_submit() supposed to perform validation? As in the code below:
$node = node_submit($node); // performs validation
if ($node->validated) {
node_save($node); //Actually save the node
}
yes
Yes, thanks for pointing that out. A simple node_save() command will not suffice.
More Info
Sorry everyone, I just realized I did not show where to put your CCK field data. This snippet shows how you could add some simple CCK field data to your node:
<?php
// create $form_state
$form_state = array();
$form_state['values'] = array(
'title' => t('MYTITLE'),
'body' => t('MYBODY'),
'name' => $GLOBALS['user']->name,
'op' => t('Save'),
);
// add CCK fields
$form_state['values']['field_MYFIELD1'][0]['value'] = "blah";
$form_state['values']['field_MYFIELD2'][0]['value'] = "wee";
// create $node
$node = (object) NULL;
$node->type = 'MYNODETYPE';
// include node file, necessary for node generation
module_load_include('inc', 'node', 'node.pages');
// create node using drupal_execute
drupal_execute('MYNODETYPE_node_form', $form_state, $node);
?>
Hope this helps!
Error when running drupal_execute
I've been searching for days on a solution for an error I'm getting when running drupal_execute on D6. I followed your code example verbatim (with the exception of changing the node names, user, etc) and keep getting a:
"Fatal error: Unsupported operand types in ".../form.inc on line 511"
Have you encountered this? I've asked in other forums, IRC, etc. to no avail.
I got this error when I used the above code with a webform
Fatal error: Cannot unset string offsets in /var/www/hkcec/sites/all/modules/cck/includes/content.node_form.inc on line 71
Any suggestions will be appreciated.
Thanks!
hmm
Post your code and I'll be happy to take a peak.