Need to create nodes from my module (programatically)

apolo - September 29, 2005 - 17:40

I´m using i18 (drupal 4.6) traslations and I need to create page nodes from my module. I´m still getting in touch with drupal, so if anyone can give some API gidelines I might finish.

node_save()

eldarin - September 29, 2005 - 18:54

Look at node.module and the node_save() function.
;-)

A typical node, has a node->type, node->nid, node->uid, node->name etc.
Other fields can be added by the nodeapi-hook using the 'fields' event. That one is called right before the node gets inserted, and means that you can have "ALTER TABLE node ADD COLUMN myfield int(10) NOT NULL" or something and have the "myfield" inserted to every node. Afterwards the node_save() invokes the 'insert' event via the nodeapi to modules, so you can add any external information outside the node-table being saved. That would be a different approach to the 'fields' and altered node-table, where you might use the $ node->nid as a foreign key in another table.

Well, a lot of information above, but basically - just use node_save(). Remember that some modules would like the 'form pre' or 'form post' events to add something more to some/all node-types, so be careful about what modules you mix, and what expectations they might have - although they ought to behave correctly.
;-)

See http://drupaldocs.org/api/4.6/group/hooks for further clues within the documentation, though.

Learn by example?

dman - September 29, 2005 - 23:54

Sounds good. I went looking at the import/export module to try and see how it was doing this. Somehow I could never track down the definition of the node object I was trying to instantiate.

Any pointers on where I should look to find what fields are required? Some of the examples just seem to make up an object from nowhere, give it a couple of properties and plug it into the system. This makes my OO sensibilites hurt.

.dan.

Sure ...

eldarin - September 30, 2005 - 02:56

from node.module:

/**
* Implementation of hook_nodeapi().
*/
function node_nodeapi(&$node, $op, $arg = 0) {
  switch ($op) {
    case 'settings':
      // $node contains the type name in this operation
      return form_checkboxes(t('Default options'), 'node_options_'. $node->type, variable_get('node_options_'. $node->type, array('status', 'promote')), array('status' => t('Published'), 'moderate' => t('In moderation queue'), 'promote' => t('Promoted to front page'), 'sticky' => t('Sticky at top of lists'), 'revision' => t('Create new revision')), t('Users with the <em>administer nodes</em> permission will be able to override these options.'));

    case 'fields':
      return array('nid', 'uid', 'type', 'title', 'teaser', 'body', 'revisions', 'status', 'promote', 'moderate', 'sticky', 'created', 'changed', 'format');
  }
}

The 'fields' case shows you the deafult ones. Just look at the actual table-data to see what works when you do node_save(). Remember the 'nid' field gets set automatically (auto_increment in node-table).

If you need control on what 'nid' is as a reference to the node you just saved, and can't use an asynchronous approach, I'm sure it's possible to have some global variable help you out with some reference of the $node object you inserted along with the $node object (with the known 'nid') reported as inserted via the nodeapi 'insert' event (if I don't remember incorrectly that is; it might be simpler).

Remember most of this stuff gets set by the node-editing form, so you can even check for edit['attributename'] in the XHTML form served from as the page to help you out.
Good luck!
;-)

Here is a chunk of code I used for saving nodes from a module

nevets - September 30, 2005 - 03:30

I used this code in transfering html files in nodes.

$edit = new StdClass();

$edit->uid = $doc->uid;
$edit->title = $doc->title;

if ( $doc->month && ! $doc->generated_date ) {
$edit->created = mktime ( 0, 0, 0, $doc->month, $doc->day, $doc->year);
$edit->changed = $edit->created;
}

$edit->status = 1;
$edit->promote = 0;
$edit->sticky = 0;
$edit->path = $doc->path;
$edit->taxonomy = array();
$edit->taxonomy[] = $doc->term;
$edit->body = ($doc->have_text ? $doc->text : "");
$edit->type = $doc->type;
$edit->format = 3;

$nid = node_save($edit);

In your case, type would be 'page'. Setting status to 1 makes it published, setting promote to 1 promotes it to the default drupal front page. Set format to 3 means the contents is HTML. If you want something othere than the standard teaser you would also want to set $edit->teaser. $edit->uid is the uid of the user you want the pages posted from. Fields you may not need/want; $edit->path assumes the path module is enable (if not it's ignored), I used it to set a generated path name. $edit->taxonomy is used for set taxonomy terms, in this case each node created had one term. Also, if possible we set the created date ($edit->create), if not set it defaults to current time.

node_save does not return nid in Drupal 5

knugar - February 16, 2007 - 15:12

I found this post very useful. I've started developing a module for Drupal 5 and discovered that node_save no longer returns nid (or anything else). Instead, the function is now call by reference on $node the parameter:

Here is a short example:

  $type = 'page';
 
  $node->title = t('A new node');
 
  $node->created = time();
  $node->changed = $node->created;
 
  $node->status = 1;
  $node->promote = 0;
  $node->sticky = 0;
 
  $node->body = '<p>I was created programatically</p>';
  $node->type = 'page';

  $node->format = 1 // Filtered HTML

  node_save($node);

  $nid=$node->nid;
 
  print theme('page', "Created a new node " . l($node->title, "node/$nid"));

Thanks! This was really

wedge - April 5, 2007 - 13:22

Thanks! This was really helpful to me as well.

That did it

apolo - October 3, 2005 - 12:52

Thanx a lot.

Changed Link

davedelong - January 28, 2008 - 22:51

The DrupalDocs link has been moved and can now be accessed here:

http://api.drupal.org/api/group/hooks/4.6

Thanks for the great posts, btw. =)

Thanks for that -

patrickharris - February 21, 2007 - 03:52

very useful!

 
 

Drupal is a registered trademark of Dries Buytaert.