7

In a custom module for drupal 4.7 I hacked together a node object and passed it to node_save($node) to create nodes. This hack appears to no longer work in drupal 6. While I'm sure this hack could be fixed I'm curious if there is a standard solution to create nodes without a form. In this case the data is pulled in from a custom feed on another website.

Isaac Waller
  • 32,709
  • 29
  • 96
  • 107
Steven Noble
  • 10,204
  • 13
  • 45
  • 57

5 Answers5

12

The best practices method of making this happen is to utilize drupal_execute. drupal_execute will run standard validation and basic node operations so that things behave the way the system expects. drupal_execute has its quirks and is slightly less intuitive than simply a node_save, but, in Drupal 6, you can utilize drupal_execute in the following fashion.


$form_id = 'xxxx_node_form'; // where xxxx is the node type
$form_state = array();
$form_state['values']['type'] = 'xxxx'; // same as above
$form_state['values']['title'] = 'My Node Title';
// ... repeat for all fields that you need to save
// this is required to get node form submits to work correctly
$form_state['submit_handlers'] = array('node_form_submit');

$node = new stdClass();
// I don't believe anything is required here, though 
// fields did seem to be required in D5

drupal_execute($form_id, $form_state, $node);

  • I actually consider drupal_execute to be a risk, as it mixes the form and node APIs, and one of the consequences is that it does not work well in a loop, which is often required when creating nodes programmatically. With some contrib modules, it can be required, but it is at best a workaround. – FGM Jan 19 '09 at 09:07
9

node_save() still works fine in Drupal 6; you'll need a couple of specific pieces of data in place to make it work.

$node = new stdClass();
$node->type = 'story';
$node->title = 'This is a title';
$node->body = 'This is the body.';
$node->teaser = 'This is the teaser.';
$node->uid = 1;
$node->status = 1;
$node->promote = 1;

node_save($node);

'Status' and 'Promote' are easy to overlook -- if you don't set those, the node will remain unpublished and unpromoted, and you'll only see if you go to the content administration screen.

Eaton
  • 7,405
  • 2
  • 26
  • 24
  • I think you should set $node->revision also. If you set it to an initial value and save then it should get set as the node ID. I seem to remember running into some trouble with this somewhere in the back of my mind... – Rimian Jun 29 '10 at 04:05
6

I don't know of a standard API for creating a node pragmatically. But this is what I've gleaned from building a module that does what you're trying to do.

  1. Make sure the important fields are set: uid, name, type, language, title, body, filter (see node_add() and node_form())
  2. Pass the node through node_object_prepare() so other modules can add to the $node object.
calebbrown
  • 934
  • 4
  • 7
0

One more answer I discovered was to use the example from the blogapi module in drupal core. The fact that it is in core gives me a bit more confidence that it will continue to work in future versions.

Steven Noble
  • 10,204
  • 13
  • 45
  • 57
0

There are some good answers above, but in the specific example of turning an ingested feed item into a node, you could also take the approach of using the simplefeed module (http://wwww.drupal.org/project/simplefeed). This module uses the simplepie engine to ingest feeds and turns individual items from each feed into nodes. I realize that this doesn't specifically address the issue of creating nodes from cron, but it might be an easier solution to your problem overall.

Chris
  • 93
  • 7