We're looking at developing a CCK-based solution for a petition website, where we have Petitions and Petitioners as separate node types linked together in a parent-child relationship.

One good example of a parent-child node relationship is the book module. This is very easy to implement using CCK's nodereference field type and you can even filter it according to node type. However, it still ultimately requires that the user to select the parent node from a drop-down or an autocomplete field. So, we need a way of automatically supplying the nid of the parent to the child's creation form.

Options, as far as I can tell:

1. Pull the referring URL when the child node form is created, and use it after submission to pull the nid out and place it in a nodereference field. This relies on the fact that the user visits the parent node immediately before visiting the child node creation page.

2. Pass the nid to the child node creation form as an argument or via a specialized URL. This would involve modifying function mapping so that a custom link like ?q=node/add/child/1337 would pull up the creation form and allow the form to pull the nid (1337) from the URL. This is more robust than the previous solution in that it is not reliant on a particular series of events.

Does anyone have any thoughts on how this might be accomplished?

Comments

Julesy’s picture

when I was developing our athletics club website. I wanted to associated news and results CCK types to event CCK types.

The event is created first (in advance of the event to produce a fixture list).

When the event has taken place, we add a news item and/or results to the event.

I used a method similar to that you described in point (2), though the parent/child relationships are done as menu items. I had to make some modifications to the menu.module for it to work (which is not ideal, and goes against best practice).

For example, if adding a news story to 'AAAChamps' event, the user navigates to the 'AAAChamps' event, which has a link to "/node/add/news/597/AAAChamps/" (I'm using clean URLs & 597 is the menuid for 'AAAChamps'). The site is www.kentac.org.uk if you want to see how results/news link to events.

Alternatively, the categories module may offer an alternative solution I tried it, but it had impact on other modules, especially image publishing and image gallery.

I'm relatively new to Drupal, so there may well be better ways of acheiving what you want, and I would be keen to know about them too.

csc4’s picture

I've been trying to do something similar - and I was wondering about the way Minutes works?

I also want to create a parent with child events - say a course with different modules, or a festival with a number of events/appearances I've looked at lots of options but can't seem to find quite the right one!

chiddicks’s picture

We forged ahead on this project by making a custom widget for the node reference field. We simply pulled the nid from the referring URL, put it in a form element that would ultimately lead to a correct variable setup for the field to process and store. We also explored option #2 (special URL), which worked, but means you have to customize your URLs. Anyway, I've written a little bit about how to make a widget here, which also includes the code for the custom widget:

http://openconcept.ca/blog/ethan/creating_custom_cck_widgets

faunapolis’s picture

Very interested :)

http://www.faunapolis.org/

Jkello’s picture

Is this working? I have tried but how do I use it?

Jkello’s picture

Hey hi. I tried the module but it gave me an error.

Because even during setting up, it referenced to the page that linked to it. Thus it is not an allowed referenced page. Thus I cannot save the settings in drupal content type cck form.

Please assist

faunapolis’s picture

I am experimenting with something based on this solution, but not exactly the same, it might work for you as well:

I will be passing the current node by argument along the URL:

http://drupal.org/node/204994

http://www.faunapolis.org/

Jkello’s picture

Will try it out thanks.

Jkello’s picture

Will try it out thanks.

Summit’s picture

subscribing, greetings, Martijn

icstars’s picture

Thank you all for this. For those of you who need a little more direction. Here is how we built our petition signing approach. We opted against doing it in a module but will revisit in D7.

1 - we have a cck type called Petition. Nothing fancy, just title and body with explanation guidelines.

2 - we have a block called 'Sign petition link'. The block displays in the content bottom region. The body of the block parses the URL for the current node id and appends it to a link to add the signpetition content type.
Body:

$url = request_uri();
$arguments = explode('/', $url);
$nid = array_pop($arguments);
$dest = 'add/signpetition/' . $nid;
echo '<a href="' . $dest . '">SIGN OUR PETITION</a>';

input format: php

page specific visibility settings:
show only if the following php code returns true:

  // Only show if $match is true
  $match = false;
  // Which node types
  $types = array('petition');
  // Match current node type with array of types
  if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) != 'edit') {
    $nid = arg(1);
    $node = node_load(array('nid' => $nid));
    $type = $node->type; 
    $match |= in_array($type, $types);
  }
  return $match;

3 - signpetition content type - contains whatever fields we want to get from the signer - firstname, lastname, address, etc. and a node reference field for petition. we use auto-nodetitles so the user does not title their signature form. the default value of the petition field including error handling is as follows:

$url = request_uri();
$arguments = explode('/', $url);
$nid = array_pop($arguments);

if (is_numeric($nid)) {
return array(0 => array('nid' => $nid ));
}
else {
return array(0 => array('nid' => 0 ));
}

4 - we create a field group on the signpetition form called invisible. we put the node reference to the petition in this group. we add the folllowing to our theme style.css:

fieldset.group-invisible {
display: none;
}

this hides the node reference from ALL users. We chose to put this in the css instead of using field permissions. The decision was that another layer of security was not warranted when in reality we simply wanted to create a hidden field not a non-existent field. hope this helps someone. it took us several days to get here and COMPLETE panic when the signit module exploded on us.

WorldFallz’s picture

out of curiosity, is there any reason you don't use the arg function:

<?php
if (arg(0) == 'node' && is_numeric(arg(1))) {
return array(0 => array('nid' => arg(1)));
}
else {
return array(0 => array('nid' => 0 ));
}
?>

===
"Give a man a fish and you feed him for a day.
Teach a man to fish and you feed him for a lifetime."
-- Lao Tzu
"God helps those who help themselves." -- Benjamin Franklin
"Search is your best friend." -- Worldfallz

icstars’s picture

arg would be much better. thanks.

also, we have since moved from the block approach above to the following computed CCK field on the petition content type:

COMPUTED CODE:
if (!$node->nid) node_save($node);
$nid = $node->nid;
$node_field[0]['value'] = $nid;

DISPLAY FORMAT:
$dest = 'add/signpetition/' . $node_field_item['value'];
$display = '<a href="' . $dest . '">SIGN PETITION</a>';
stopbox’s picture

Thanks for this, I got the node reference link up and running.

Is it possible to use this method to pass over a node reference and a user reference at the same time?

BarisW’s picture

Quicksketch made this request into a module. It works great: http://drupal.org/project/nodereference_url

Baris Wanschers (@BarisW)
Drupal specialist