? nodehierarchy.patch
Index: nodehierarchy.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodehierarchy/nodehierarchy.install,v
retrieving revision 1.1.4.2
diff -u -p -r1.1.4.2 nodehierarchy.install
--- nodehierarchy.install	14 May 2008 22:22:00 -0000	1.1.4.2
+++ nodehierarchy.install	4 Feb 2010 18:29:09 -0000
@@ -41,6 +41,12 @@ function nodehierarchy_schema() {
         'default' => 0,
         'description' => t('The sort order or weight of the node.'),
       ),
+      'placeholder' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => t('A Boolean value indicating whether a node should be an empty placeholder or not.'),
+      ),
     ),
     'primary key' => array('nid'),
   );
@@ -60,6 +66,19 @@ function nodehierarchy_update_1() {
   return nodehierarchy_add_default_parents();
 }
 
+function nodehierarchy_update_2() {
+  $ret = array();
+  db_add_field($ret, 'nodehierarchy', 'placeholder', 
+    array(
+      'type' => 'int',
+      'not null' => TRUE,
+      'default' => 0,
+      'description' => t('A Boolean value indicating whether a node should be an empty placeholder or not.'),
+    )
+  );
+  return $ret;
+}
+
 // Add nodehierarchy records for pre-existing nodes.
 function nodehierarchy_add_default_parents() {
   $out = array();
Index: nodehierarchy.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/nodehierarchy/nodehierarchy.module,v
retrieving revision 1.4.2.17
diff -u -p -r1.4.2.17 nodehierarchy.module
--- nodehierarchy.module	3 Nov 2009 15:57:05 -0000	1.4.2.17
+++ nodehierarchy.module	4 Feb 2010 18:29:09 -0000
@@ -268,7 +268,11 @@ function nodehierarchy_nodeapi(&$node, $
     case 'view':
       if ($page && !$teaser) {
         nodehierarchy_set_breadcrumbs($node);
+        if ($node->placeholder) {
+          _nodehierarchy_goto_first_child($node);
+        }
       }
+
       break;
   }
 }
@@ -318,6 +322,33 @@ function nodehierarchy_nodehierarchyapi(
         ),
         '#description' => t("Users must have the 'administer menu' permission to create menu items. If you want to allow users to use this feature without that permission you can enable that on !settings", array('!settings' => l(t('the node hierarchy settings page'), 'admin/settings/nodehierarchy'))),
       );
+
+      if (module_exists('token')) {
+        $form['nh_menutitle'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Pattern for menu item title generation'),
+          '#default_value' => variable_get('nh_menutitle_'. $key, '[title-raw]'),
+          '#description' => t("Users may enter a pattern here for the menu item that will be generated for this content type"),
+          );
+        $form['nh_menulink'] = array(
+          '#type' => 'textfield',
+          '#title' => t('Pattern for menu item link generation'),
+          '#default_value' => variable_get('nh_menulink_'. $key, 'node/[nid]'),
+          '#description' => t("Users may enter a pattern here for the menu item link that will be generated for this content type"),
+          );
+        $form['view']['token_help'] = array(
+          '#title' => t('Replacement patterns'),
+          '#type' => 'fieldset',
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+          '#description' => t('Prefer raw-text replacements for text'),
+        );
+
+        $form['view']['token_help']['help'] = array(
+          '#value' => theme('token_help', 'node'),
+        );
+      }
+          
       return $form;
     break;
 
@@ -348,6 +379,12 @@ function nodehierarchy_nodehierarchyapi(
             '#value'  => $node->parent,
           );
         }
+        $form['placeholder'] = array(
+          '#type'           => 'checkbox',
+          '#title'          => t('Treat node as placeholder?'),
+          '#default_value'  => isset($node->placeholder) ? $node->placeholder : 0,
+          '#description' => t("This will cause Drupal to redirect the user to the node's first child"),
+        );
 
         // Automatic menu item creation.
         if (module_exists('menu') && variable_get('nodehierarchy_menus', TRUE)) {
@@ -400,6 +437,8 @@ function nodehierarchy_nodehierarchyapi(
 function nodehierarchy_insert_node(&$node) {
   global $user;
 
+  // @TODO check to see if the value needs to be updated to save a DB query
+  db_query("UPDATE {nodehierarchy} SET placeholder = %d WHERE nid = %d", $node->placeholder, $node->nid);
   // If the node is valid and the parent has changed or the node does not already have a parent.
   if ($node->nid && (@$node->old_parent !== @$node->parent) || @$node->old_parent === NULL) {
 
@@ -435,7 +474,7 @@ function nodehierarchy_insert_node(&$nod
       $node->order_by = _nodehierarchy_get_next_child_order(@$node->parent);
 
       db_query('DELETE FROM {nodehierarchy} WHERE nid = %d', $node->nid);
-      db_query("INSERT INTO {nodehierarchy} (nid, parent, order_by) VALUES (%d, %d, %f)", $node->nid, $node->parent, $node->order_by);
+      db_query("INSERT INTO {nodehierarchy} (nid, parent, order_by, placeholder) VALUES (%d, %d, %f, %d)", $node->nid, $node->parent, $node->order_by, $node->placeholder);
       _nodehierarchy_normalize_child_order(@$node->old_parent);
 
       // Reload order (it may have shifted during the sort).
@@ -487,10 +526,11 @@ function nodehierarchy_delete_children($
  * Load a node's parent and weight when the node is loaded.
  */
 function nodehierarchy_load_node($node) {
-  $additions = db_fetch_array(db_query('SELECT parent, order_by FROM {nodehierarchy} WHERE nid = %d', $node->nid));
+  $additions = db_fetch_array(db_query('SELECT parent, order_by, placeholder FROM {nodehierarchy} WHERE nid = %d', $node->nid));
   return $additions;
 }
 
+
 /**
  * Invoke a hook_nodehierarchyapi() operation in all modules.
  *
@@ -979,9 +1019,16 @@ function _nodehierarchy_create_menu(&$no
       $item['parent'] = variable_get('nodehierarchy_menus_default', 'primary-links:0');
       list($item['menu_name'], $item['plid']) = explode(":", $item['parent']);
     }
+    if (module_exists('token')) {
+      $item['link_title'] = trim(token_replace(variable_get('nh_menutitle_' . $node->type , '[title-raw]'), 
+        $type = 'node', $object = $node, $leading = '[', $trailing = ']'));
+      $item['link_path'] =  token_replace(variable_get('nh_menulink_' . $node->type , 'node/[nid]'),
+        $type = 'node', $object = $node, $leading = '[', $trailing = ']');
+    } else {
+      $item['link_title'] = trim($node->title);
+      $item['link_path'] = "node/$node->nid";
+    }
 
-    $item['link_title'] = trim($node->title);
-    $item['link_path'] = "node/$node->nid";
     // Editable menu weight range used to start at -10.
     $item['weight'] = $node->order_by - 11;
     if (!menu_link_save($item)) {
@@ -1021,7 +1068,15 @@ function _nodehierarchy_set_menu_order($
  * Find the menu ID for the given node.
  */
 function _nodehierarchy_get_menu($nid) {
-  return db_fetch_array(db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = '%s'", "node/$nid", 0, 1));
+
+  if (module_exists('token')) {
+    $node=node_load($nid);
+    $link_path =  token_replace(variable_get('nh_menulink_' . $node->type , 'node/[nid]'),
+      $type = 'node', $object = $node, $leading = '[', $trailing = ']');
+   } else {
+     $link_path = "node/$nid";
+   }  
+  return db_fetch_array(db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = '%s'", $link_path, 0, 1));
 }
 
 /**
@@ -1034,7 +1089,14 @@ function _nodehierarchy_get_parent_menu(
   }
   // Otherwise get the parent menu of the item (if any).
   else {
-    return db_fetch_array(db_query_range("SELECT plid FROM {menu_links} WHERE link_path = '%s'", "node/$nid", 0, 1));
+    if (module_exists('token')) {
+      $node=node_load($nid);
+      $link_path =  token_replace(variable_get('nh_menulink_' . $node->type , 'node/[nid]'),
+        $type = 'node', $object = $node, $leading = '[', $trailing = ']');
+     } else {
+       $link_path = "node/$nid";
+     }  
+    return db_fetch_array(db_query_range("SELECT plid FROM {menu_links} WHERE link_path = '%s'", $link_path, 0, 1));
   }
 }
 
@@ -1042,7 +1104,14 @@ function _nodehierarchy_get_parent_menu(
  * Find the menu ID for the given node with the given parent menu ID.
  */
 function _nodehierarchy_get_child_menu($nid, $plid = NULL) {
-  return db_fetch_array(db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = '%s' AND plid = '%d'", "node/$nid", $plid, 0, 1));
+  if (module_exists('token')) {
+    $node=node_load($nid);
+    $link_path =  token_replace(variable_get('nh_menulink_' . $node->type , 'node/[nid]'),
+      $type = 'node', $object = $node, $leading = '[', $trailing = ']');
+   } else {
+     $link_path = "node/$nid";
+   }  
+  return db_fetch_array(db_query_range("SELECT mlid FROM {menu_links} WHERE link_path = '%s' AND plid = '%d'", $link_path, $plid, 0, 1));
 }
 
 /**
@@ -1109,3 +1178,16 @@ function _nodehierarchy_get_parent_types
   return $types;
 }
 
+/**
+ * Redirect a node to the first child node.
+ */
+function _nodehierarchy_goto_first_child($node) {
+    watchdog("nh", "$node->nid has pl $node->placeholder");
+    if ($node->placeholder) {
+      $result = db_query_range('SELECT nid FROM {nodehierarchy} WHERE parent = %d ORDER BY order_by ASC', $node->nid, 0, 1);
+      while ($node = db_fetch_object($result)) {
+        drupal_goto("node/$node->nid");
+      }
+    }
+}
+
