I'm working on a custom node module where I'd like it to create a couple of its own nodes when installed. I have it populating the title and body fields of the nodes using node_save inside a hook_enable implementation, but the custom URL field that is part of the node isn't getting filled in.

Below is what I have for the hook_enable implementation. Is it not possible to add a node with a custom field at that point?

function drubnub_enable() {
  global $base_url;
  // create "ls" command node
  $ls_command->title = 'ls';
  $ls_command->url = $base_url .'/?q=drubnub/ls';
  $ls_command->body = 'test1';
  $ls_command->type = 'drubnub';
  node_save($ls_command);
  
  // build "create" command node
  $create_command->title = 'create';
  $create_command->url = $base_url .'/?q=node/add/drubnub';
  $create_command->body = 'test2';
  $create_command->type = 'drubnub';
  node_save($create_command); 
}

Comments

dman’s picture

If your module correctly uses nodeapi(insert) then I'm thinking it should work.

Code-wise, that snippet is a bit weak - it would not be correct to include the $base_url is a field you are saving to the DB - but for experimentation it's no big deal.
Did you consider utilizing the $node->path instead? Not sure what you are doing...

.dan.
if you are asking a question you think should be documented, please provide a link to the handbook where you think the answer should be found.
| http://www.coders.co.nz/ |

matt v.’s picture

Thanks for the help. I'm a bit confused though. The module I'm working on functions like yubnub.org, where users can create and use "commands" that accept search terms as arguments that then redirect the user to search results on other sites.

I didn't think I needed a hook_nodeapi implementation, since the module is defining a node. I use hook_insert to write the URL to the database. Now that you mention it though, I ran a test and hook_insert doesn't get called when I do a node_save within hook_enable.

I've been going by the example node module in the Pro Drupal Development book, which doesn't implement hook_nodeapi at all. The hook_nodeapi API page says:

If you are writing a node module, do not use this hook to perform actions on your type of node alone. Instead, use the hooks set aside for node modules, such as hook_insert() and hook_form(). That said, for some operations, such as "delete revision" or "rss item" there is no corresponding hook so even the module defining the node will need to implement hook_nodeapi().

The last sentence in the quote seems to contradict the first sentence.

Should I be implementing hook_nodeapi in this case?

Thanks for pointing out the $base_url issue. I'll look into rewriting the way the commands get handled, so that internal URLs can work as commands too. Then I wouldn't need to write the full URL to the database.

dman’s picture

Yeah, you are probably right - node-type modules have stopped using nodeapi as much as possible - I'm still thinking in D4-5 terms.
The way you are instantiating that node object is very minimal. I've found you often have to fill in a few more values than that - although I can't recall seeing it documented completely.
You are skipping the node validate process which would normally tell you what the problem is when a form is submitted.
You can use devel.module or print_r($node) to see the attributes that are expected. Not all are required - but some are.
I would start by filling in

global $user;
$node->name = $user->name;
$node->uid = $user->id;

as that was a sticking point I recall from making nodes programatically.
It may be something else, so make a node as you want it, then investigate its structure and replicate it (devel.module). then experiment with trimming optional attributes back.

Probably could be documented a bit more.

.dan.
if you are asking a question you think should be documented, please provide a link to the handbook where you think the answer should be found.
| http://www.coders.co.nz/ |

matt v.’s picture

After lots of trial and error and even more digging around on api.drupal.org, I think I've figured it out. Apparently, when calling node_save from within hook_install or hook_enable, the new node type hasn't yet been saved, so the corresponding hook_insert wasn't getting called.

I added a call to node_types_rebuild to the top of hook_enable, that did the trick. The nodes now get created with the additional fields.