? .svn
? CHANGELOG.txt
? taxonomy_menu-drupal6_menu-304379-18.patch
? translations/.svn
Index: taxonomy_menu.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/taxonomy_menu/taxonomy_menu.inc,v
retrieving revision 1.2.2.2
diff -u -p -r1.2.2.2 taxonomy_menu.inc
--- taxonomy_menu.inc	9 Sep 2008 11:54:04 -0000	1.2.2.2
+++ taxonomy_menu.inc	5 Feb 2009 10:25:49 -0000
@@ -16,80 +16,16 @@
  *   Array. The form fields.
  * @ingroup forms
  */
-function _taxonomy_menu_admin(&$form_state) {
-  $options = array(
-    TAXONOMY_MENU_NONE    => t('No'),
-    TAXONOMY_MENU_NORMAL  => t('Normal')
-  );
-
-  // If the Views module is enabled, add some special
-  // new features
-//   if (module_exists('views')) {
-//     // Add the Views file with more functions
-//     require_once(drupal_get_path('module', 'views') .'/views_cache.inc');
-//
-//     // Add a new options on Categories
-//     $options[TAXONOMY_MENU_VIEW] = t('Views');
-//
-//     // Get the list of User generated views
-//     $views = db_query("SELECT * FROM {view_view}");
-//     while ($view = db_fetch_array($views)) {
-//       $views_list[$view['name']] = $view['page_title'];
-//     }
-//
-//     // Now get a list of default Views
-//     foreach (_views_get_default_views() as $view => $viewdata) {
-//       $views_list[$view] = $viewdata->name;
-//     }
-//   }
-
-  // If the Taxonomy Default module is enabled, add some special
-  // new features
-  if (module_exists('taxonomy_defaults')) {
-    $options[TAXONOMY_MENU_DEFAULT_TAX] = t('Module types');
-  }
-
-  // Create some options for each of the vocabularies
-  foreach (taxonomy_get_vocabularies() as $vocab) {
-    $form[$vocab->vid] = array(
-      '#title'          => $vocab->name,
-      '#tree'           => FALSE,
-      '#type'           => 'fieldset'
-    );
-    $form[$vocab->vid]['taxonomy_menu_show_'. $vocab->vid] = array(
-      '#default_value'  => variable_get('taxonomy_menu_show_'. $vocab->vid, TAXONOMY_MENU_NONE),
-      '#options'        => $options,
-      '#title'          => t('Show this category in menu'),
-      '#type'           => 'radios'
-    );
-
-    // In case of View options selected, select Views
-//     if (module_exists('views')) {
-//       $form[$vocab->vid]['taxonomy_menu_show_view_'. $vocab->vid] = array(
-//         '#default_value'  => variable_get('taxonomy_menu_show_view_'. $vocab->vid, ''),
-//         '#options'        => $views_list,
-//         '#title'          => t('Views available'),
-//         '#type'           => 'select'
-//       );
-//     }
-  }
-
-  // General options
-  $form['taxonomy_menu_display_page'] = array(
-    '#default_value'  => variable_get('taxonomy_menu_display_page', 'category'),
-    '#description'    => t('How should be the first item on the menu? Example: categories/1/2/3, technology/1/2/3'),
-    '#title'          => t('Module page'),
-    '#type'           => 'textfield',
-  );
+function taxonomy_menu_admin_settings() {
   $form['taxonomy_menu_display_num'] = array(
     '#default_value'  => variable_get('taxonomy_menu_display_num', FALSE),
-    '#description'    => t('If checked, number of node per term will be displayed in the menu.'),
-    '#title'          => t('Display number of nodes per terms'),
+    '#description'    => t('If checked, number of nodes per term will be displayed in the menu.'),
+    '#title'          => t('Display number of nodes per term'),
     '#type'           => 'checkbox',
   );
   $form['taxonomy_menu_hide_empty'] = array(
     '#default_value'  => variable_get('taxonomy_menu_hide_empty', FALSE),
-    '#description'    => t('If checked, only taxonomy terms with members will be shown in the menu.'),
+    '#description'    => t('If checked, only taxonomy terms with associated nodes will be shown in the menu.'),
     '#title'          => t('Hide Empty Terms'),
     '#type'           => 'checkbox',
   );
@@ -100,231 +36,6 @@ function _taxonomy_menu_admin(&$form_sta
     '#type'           => 'checkbox',
   );
 
-  $form['submit'] = array(
-    '#type'           => 'submit',
-    '#value'          => t('Save configuration')
-  );
-
-  return $form;
-}
-
-/**
- * Admin area. Configure the module, setting which
- * vocabularies will be converted into menus items
- */
-function _taxonomy_menu_admin_submit($form, &$form_state) {
-  // Save these options
-  variable_set('taxonomy_menu_display_page',        $form_state['values']['taxonomy_menu_display_page']);
-  variable_set('taxonomy_menu_display_num',         $form_state['values']['taxonomy_menu_display_num']);
-  variable_set('taxonomy_menu_hide_empty',          $form_state['values']['taxonomy_menu_hide_empty']);
-  variable_set('taxonomy_menu_display_descendants', $form_state['values']['taxonomy_menu_display_descendants']);
-
-  // Save which category should be displayed on menu
-  // and save which views it should use, in case Views
-  // mode is selected
-  foreach (taxonomy_get_vocabularies() as $vocab) {
-    variable_set('taxonomy_menu_show_'. $vocab->vid,
-      $form_state['values']['taxonomy_menu_show_'. $vocab->vid]);
-    variable_set('taxonomy_menu_show_views_'. $vocab->vid,
-      $form_state['values']['taxonomy_menu_show_view_'. $vocab->vid]);
-  }
-
-  // Rebuild the menu to include these features
-  menu_rebuild();
-}
-
-/**
- * Implementation of hook_menu().
- *
- * Its the main function for this module.
- */
-function _taxonomy_menu_menu() {
-  $items['admin/settings/taxonomy_menu'] = array(
-    'access arguments'    => array('administer site configuration'),
-    'description'         => t('Global configuration of taxonomy menu functionality.'),
-    'file'                => 'taxonomy_menu.inc',
-    'page callback'       => 'drupal_get_form',
-    'page arguments'      => array('_taxonomy_menu_admin'),
-    'path'                => 'admin/settings/taxonomy_menu',
-    'title'               => t('Taxonomy Menu settings'),
-    'type'                => MENU_NORMAL_ITEM
-  );
-
-  foreach (taxonomy_get_vocabularies() as $vocab) {
-    if (variable_get('taxonomy_menu_show_'. $vocab->vid, TAXONOMY_MENU_NONE)) {
-      $path =  variable_get('taxonomy_menu_display_page', 'category') .'/'. $vocab->vid;
-      $items[$path] = array(
-        'access arguments'    => array('access content'),
-        'file'            => 'taxonomy_menu.inc',
-        'page callback'   => '_taxonomy_menu_page',
-        'title'           => t($vocab->name),
-        'weight'          => $vocab->weight
-      );
-
-      $tree = taxonomy_get_tree($vocab->vid);
-      $old_depth = -1;
-      $old_path = $path;
-
-      foreach ($tree as $term) {
-        if ($term->depth <= $old_depth) {
-          $slashes_to_remove = $old_depth - $term->depth + 1;
-          for ($i = 0; $i < $slashes_to_remove; $i++) {
-            $old_path = substr($old_path, 0, strrpos($old_path, '/'));
-          }
-        }
-        $path       = $old_path .'/'. $term->tid;
-        $old_depth  = $term->depth;
-        $old_path   = $path;
-
-        // Calculate the numbers of children nodes
-        $num = taxonomy_term_count_nodes($term->tid);
-
-        // If the number of children nodes of this term is
-        // zero and the Hide Empty Terms option is enabled,
-        // dont create the menu item
-        if (variable_get('taxonomy_menu_hide_empty', FALSE) == FALSE or $num != 0) {
-          $name = t($term->name);
-          if (variable_get('taxonomy_menu_display_num', FALSE) == TRUE) {
-            $name .= ' ('. $num .')';
-          }
-          $items[$path] = array(
-            'access arguments' => array('access content'),
-            'file'            => 'taxonomy_menu.inc',
-            'page callback'   => '_taxonomy_menu_page',
-            'description'     => t($term->description),
-            'title'           => $name,
-            'weight'          => $term->weight,
-          );
-        }
-      }
-    }
-  }
-
-  return $items;
+  return system_settings_form($form);
 }
 
-/**
- * Generates the breadcumb for nodes that
- * have a category listed as a menu
- *
- * @param
- *   Object. The node object
- * @param
- *   Array. The list of all taxonomy vocabs and
- *   terms that this node have and are also
- *   menus
- */
-function _taxonomy_menu_node_view(&$node, &$vocabs) {
-  foreach ($vocabs as $vid => $vocab) {
-    $path = variable_get('taxonomy_menu_display_page', 'category') .'/'. $vid;
-
-    $tree = taxonomy_get_tree($vid);
-    $old_depth = -1;
-    $old_path = $path;
-
-    // Generate the entire breadcumb
-    foreach ($tree as $term) {
-      if ($term->depth <= $old_depth) {
-        $slashes_to_remove = $old_depth - $term->depth + 1;
-        for ($i = 0; $i < $slashes_to_remove; $i++) {
-          $old_path = substr($old_path, 0, strrpos($old_path, "/"));
-        }
-      }
-      $path       = $old_path .'/'. $term->tid;
-      $old_depth  = $term->depth;
-      $old_path   = $path;
-
-      if ($term->tid == $vocab[0]) { //create all the breadcrumb items
-	$breadcrumb=array();
-	$tmpterm=$term;
-	$patharray=explode('/', $path);
-
-	while($tmpterm) { //create items for all the ancestors
-	  $breadcrumb[] = l($tmpterm->name, implode('/', $patharray));
-	  array_pop($patharray);
-	  if(isset($tmpterm->parents[0])) $tmpterm = taxonomy_get_term($tmpterm->parents[0]); 
-	  else unset($tmpterm); //we're done with ancestors
-	}
-
-	$vocabulary = taxonomy_vocabulary_load($term->vid);
-	$breadcrumb[] = l($vocabulary->name, implode('/', $patharray)); //add the vocabulary item
-	$breadcrumb[] = l(t('Home'), '<front>');
-
-	drupal_set_breadcrumb(array_reverse($breadcrumb));
-
-        // Quit after the first match.
-        return;
-      }
-    }
-  }
-}
-
-/**
- * Page callback that renders a node listing for the selected term.
- */
-function _taxonomy_menu_page() {
-  // Check if the Vocabulary ID is set
-  if ($vid = arg(1)) {
-
-    // Depending on what Output technique is used,
-    // show the nodes' list
-    if (variable_get('taxonomy_menu_show_'. $vid, TAXONOMY_MENU_NONE) == TAXONOMY_MENU_NORMAL) {
-      if ($tid = arg(2)) {
-        $tid = explode('/', $_GET['q']);
-        $tid = db_escape_string(array_pop($tid));
-
-        // Add the RSS feed
-        $feed = url('taxonomy/term/'. $tid .'/'.
-          (variable_get('taxonomy_menu_display_descendants', 1) ? 'all' : 0) .
-          '/feed');
-        drupal_add_feed($feed);
-
-        // Get the nodes
-        $result = taxonomy_select_nodes(array($tid), 'or',
-          variable_get('taxonomy_menu_display_descendants', 1) ? 'all' : 0);
-      }
-      else {
-        // If no arg(2), we're looking at just the vid. If
-        // display_descendants is on, grab all terms regardless
-        // of depth. If off, grab depth 0 terms.
-        $tree = taxonomy_get_tree($vid);
-        $descendants = variable_get('taxonomy_menu_display_descendants', 1);
-        foreach ($tree as $term) {
-          if ($descendants or $term->depth == 0) {
-            $tids[] = $term->tid;
-          }
-        }
-
-        // The requested terms have already been determined,
-        // so don't request descendants here.
-        $result = taxonomy_select_nodes($tids, 'or', 0);
-      }
-
-      // Render the selected nodes
-      $output = taxonomy_render_nodes($result);
-    }
-    elseif (variable_get('taxonomy_menu_show_'. $vid, TAXONOMY_MENU_NONE) == TAXONOMY_MENU_VIEW) {
-      // Get the last page argument
-      $tid = explode('/', $_GET['q']);
-      $tid = db_escape_string(array_pop($tid));
-
-      $arguments[] = $vid;
-
-      // Only add the Term ID if its not the Vocabulary ID
-      if ($vid != $tid) {
-        $arguments[] = $tid;
-      }
-
-      // Embed the views output into the page
-      $output = views_build_view('embed',
-        views_get_view(variable_get('taxonomy_menu_show_views_'. $vid, '')),
-        $arguments, FALSE, NULL);
-    }
-    elseif (variable_get('taxonomy_menu_show_'. $vid, TAXONOMY_MENU_NONE) == TAXONOMY_MENU_DEFAULT_TAX) {
-
-    }
-  }
-
-  // If no content found, return a "error" message
-  return empty($output) ? t('No content for this category.') : $output;
-}
Index: taxonomy_menu.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/taxonomy_menu/taxonomy_menu.info,v
retrieving revision 1.2
diff -u -p -r1.2 taxonomy_menu.info
--- taxonomy_menu.info	31 Jan 2008 16:51:55 -0000	1.2
+++ taxonomy_menu.info	5 Feb 2009 10:25:49 -0000
@@ -1,5 +1,5 @@
 ; $Id: taxonomy_menu.info,v 1.2 2008/01/31 16:51:55 brmassa Exp $
 core          = "6.x"
 dependency    = taxonomy
-description   = "Adds links to taxonomy terms to the global navigation menu."
+description   = "Adds links to taxonomy terms to a menu."
 name          = "Taxonomy Menu"
Index: taxonomy_menu.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/taxonomy_menu/taxonomy_menu.install,v
retrieving revision 1.2.2.1
diff -u -p -r1.2.2.1 taxonomy_menu.install
--- taxonomy_menu.install	8 Sep 2008 19:37:23 -0000	1.2.2.1
+++ taxonomy_menu.install	5 Feb 2009 10:25:49 -0000
@@ -8,18 +8,62 @@
  */
 
 /**
- * Delete all SQL tables and global variables
- * used by this module in other to let no garbage
- * behind
+ * Implementation of hook_uninstall().
  */
 function taxonomy_menu_uninstall() {
   // Delete variables
   foreach (taxonomy_get_vocabularies() as $vocabulary) {
-    variable_del('taxonomy_menu_show_'. $vocabulary->vid);
-    variable_del('taxonomy_menu_show_view_'. $vocabulary->vid);
+    variable_del('taxonomy_menu_vocab_'. $vocabulary->vid);
+    variable_del('taxonomy_menu_sync_'. $vocabulary->vid);
   }
   variable_del('taxonomy_menu_display_num');
   variable_del('taxonomy_menu_hide_empty');
-  variable_del('taxonomy_menu_display_page');
   variable_del('taxonomy_menu_display_descendants');
+
+  // remove table
+  drupal_uninstall_schema('taxonomy_menu');
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function taxonomy_menu_install() {
+  drupal_install_schema('taxonomy_menu');
+}
+
+/**
+ * Implementation of hook_schema().
+ */
+function taxonomy_menu_schema() {
+  $schema['taxonomy_menu'] = array(
+    'description' => t('Links a taxonomy term to a menu item'),
+    'fields' => array(
+      'mlid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => t('The taxonomy terms {menu_link}.mlid'),
+      ),
+      'tid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => t('tid that is linked to the mlid'),
+      ),
+      'vid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => t('vid for the tid'),
+      ),
+    ),
+    'primary key' => array('mlid','tid'),
+    'indexes' => array(
+      'vid' => array('vid'),
+    ),
+  );
+  return $schema;
 }
Index: taxonomy_menu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/taxonomy_menu/taxonomy_menu.module,v
retrieving revision 1.19.2.2
diff -u -p -r1.19.2.2 taxonomy_menu.module
--- taxonomy_menu.module	9 Sep 2008 15:00:07 -0000	1.19.2.2
+++ taxonomy_menu.module	5 Feb 2009 10:25:50 -0000
@@ -5,26 +5,290 @@
  * @author Jonathan Chaffer   <jchaffer@structureinteractive.com>
  * @author Bruno Massa        <http://drupal.org/user/67164>
  * @file taxonomy_menu.module
- * It Generates menu links for all taxonomy terms
+ * It Generates menu links for all selected taxonomy terms
  */
 
-// Some "magic numbers" revealed
-define('TAXONOMY_MENU_NONE',        0);
-define('TAXONOMY_MENU_NORMAL',      1);
-define('TAXONOMY_MENU_VIEW',        2);
-define('TAXONOMY_MENU_DEFAULT_TAX', 3);
-
-/**
+ /**
  * Implementation of hook_menu().
  *
- * Its the main function for this module.
+ * Old versions of taxonomy_menu would use the hook_menu() function to
+ * create menu items. This is bad practise. These items are now created using
+ * taxonomy_menu_rebuild_link_items(), which is invoked when a user submits
+ * the taxonomy edit form for their vocabulary. hook_menu() only contains a
+ * link to an administration menu.
  */
 function taxonomy_menu_menu() {
-  require_once(drupal_get_path('module', 'taxonomy_menu') .'/taxonomy_menu.inc');
-  return _taxonomy_menu_menu();
+  $items['admin/settings/taxonomy_menu'] = array(
+    'access arguments'    => array('administer site configuration'),
+    'description'         => t('Global configuration of taxonomy menu functionality.'),
+    'file'                => 'taxonomy_menu.inc',
+    'page callback'       => 'drupal_get_form',
+    'page arguments'      => array('taxonomy_menu_admin_settings'),
+    'path'                => 'admin/settings/taxonomy_menu',
+    'title'               => t('Taxonomy Menu settings'),
+    'type'                => MENU_NORMAL_ITEM,
+  );
+
+  return $items;
+}
+
+/**
+ * Implementation of hook_form_alter().
+ *
+ * Modify the form at admin/content/taxonomy/edit/vocabulary/xx. We add
+ * our taxonomy_menu options in here on a per-vocab basis.
+ */
+function taxonomy_menu_form_alter(&$form, $form_state, $form_id) {
+  if ($form_id == 'taxonomy_form_vocabulary') {
+    // choose a menu to add link items to.
+    $options = menu_get_menus();
+    array_unshift($options, '= DISABLED =');
+
+    $form['taxonomy_menu'] = array(
+      '#type' => 'fieldset',
+      '#collapsible' => TRUE,
+      '#title' => t('Taxonomy menu'),
+    );
+    $form['taxonomy_menu']['vocab_enabled'] = array(
+      '#type' => 'select',
+      '#title' => t('Select menu'),
+      '#default_value' => variable_get('taxonomy_menu_vocab_' . $form['vid']['#value'], 0),
+      '#options' => $options,
+      '#description' => t('With this option enabled, an entry will be created in the menu system for this vocabulary.')
+    );
+    $form['taxonomy_menu']['vocab_sync'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Syncronise changes to this vocabulary'),
+      '#default_value' => variable_get('taxonomy_menu_sync_' . $form['vid']['#value'], 0),
+      '#description' => t('Every time a term is added/deleted/modified, the corresponding menu link will be altered too.'),
+    );
+
+    // move the buttons to the bottom of the form
+    $form['delete']['#weight'] = 11;
+    $form['submit']['#weight'] = 10;
+
+    // add an extra submit handler to save these settings
+    $form['#submit'][] = 'taxonomy_menu_vocab_submit';
+  }
+}
+
+/**
+ * Submit handler for the extra settings added to the taxonomy vocab form.
+ *
+ * Check to see if the user has selected a different menu, and only rebuild
+ * if this is the case.
+ */
+function taxonomy_menu_vocab_submit($form, &$form_state) {
+  $vid = $form_state['values']['vid'];
+  $old_menu = variable_get('taxonomy_menu_vocab_' . $vid, 0);
+  $new_menu = $form_state['values']['vocab_enabled'];
+
+  // only rebuild if the menu option has changed.
+  if ($old_menu != $new_menu) {
+    variable_set('taxonomy_menu_vocab_' . $vid, $new_menu);
+    taxonomy_menu_rebuild_link_items($vid);
+  }
+
+  // syncronisation option
+  variable_set('taxonomy_menu_sync_' . $vid, $form_state['values']['vocab_sync']);
+}
+
+/**
+ * Implementation of hook_taxonomy().
+ *
+ * When a user inserts, alters or deletes taxonomy terms, we can keep
+ * the related menu synchronised to the changes without rebuilding the entire
+ * menu (which would delete all other customisations the user may have done).
+ */
+function taxonomy_menu_taxonomy($op, $type, $term = NULL) {
+  // only sync if taxonomy_menu is enabled for this vocab and the 'sync'
+  // option has been checked.
+  $menu_name = variable_get('taxonomy_menu_vocab_' . $term['vid'], 0);
+  $sync = variable_get('taxonomy_menu_sync_' . $term['vid'], 0);
+
+  if ($type == 'term' && $menu_name && $sync) {
+    // get the first parent
+    if (is_array($term['parent'])) {
+      foreach ($term['parent'] as $key => $val) {
+        $ptid = $key;
+        break;
+      }
+    }
+    else if (is_string($term['parent'])) {
+      $ptid = $term['parent'];
+    }
+
+    // turn the term into the correct $item array form
+    $item = array(
+      'tid' => $term['tid'],
+      'name' => $term['name'],
+      'description' => $term['description'],
+      'weight' => $term['weight'],
+      'vid' => $term['vid'],
+      'ptid' => $ptid,
+      'menu_name' => $menu_name,
+    );
+
+    switch ($op) {
+      case 'insert':
+        _taxonomy_menu_add_item($item);
+
+        $message = "Term '@term' has been added to taxonomy menu '@menuname'";
+        break;
+
+      case 'update':
+        // todo... actually update
+        $message = "Term '@term' has been updated in taxonomy menu '@menuname'";
+        break;
+
+      case 'delete':
+        // todo... actually delete
+        $message = "Term '@term' has been deleted from taxonomy menu '@menuname'";
+        break;
+    }
+    // report status
+    $message = t($message, array('@term' => $term['name'], '@menuname' => $menu_name));
+    drupal_set_message($message, 'status');
+
+    // rebuild the menus
+    menu_rebuild();
+  }
+}
+
+/**
+ * Remove all menu links for a given vocab and rebuild it completely.
+ */
+function taxonomy_menu_rebuild_link_items($vid) {
+  // delete all taxonomy_menu link items from this vocab
+  _taxonomy_menu_delete_all($vid);
+
+  // rebuild vocab
+  $menu_name = variable_get('taxonomy_menu_vocab_' . $vid, 0);
+  if ($menu_name) {
+    foreach (taxonomy_get_tree($vid) as $term) {
+      $item = array(
+        'tid' => $term->tid,
+        'name' => $term->name,
+        'description' => $term->description,
+        'weight' => $term->weight,
+        'vid' => $vid,
+        'ptid' => $term->parents[0],
+        'menu_name' => $menu_name,
+      );
+      _taxonomy_menu_add_item($item);
+    }
+    drupal_set_message(t('The taxonomy menu has been rebuilt.'), 'status');
+  }
+  else {
+    // no menu name is specified, so user has selected = DISABLED = from
+    // the taxonomy vocab form.
+    drupal_set_message(t('The taxonomy menu has been disabled.'), 'status');
+  }
+  menu_rebuild();
 }
 
 /**
+ * Add a taxonomy menu item.
+ *
+ * We use a custom data array $item as a parameter, instead of using a
+ * standard taxonomy $term object. This is because this function is also
+ * called from hook_taxonomy(), which doesn't have a $term object. Rather
+ * have one consistent method of passing the data.
+ *
+ * @param $item
+ *   array with the following key/value pairs:
+ *     'tid' => the term id
+ *     'name' => the term's name
+ *     'description' => term description, used as to build the title attribute
+ *     'weight' => term weight
+ *     'vid' => the vocabulary's id
+ *     'ptid' => the term's parent's term id
+ *     'menu_name' => the menu that the link item will be inserted into
+ */
+function _taxonomy_menu_add_item($item) {
+  // Calculate the number of children nodes
+  $num = taxonomy_term_count_nodes($item['tid']);
+
+  // If the number of children nodes of this term is zero and the
+  // 'Hide Empty Terms' option is enabled, don't create the menu item.
+  if (!($num == 0 && variable_get('taxonomy_menu_hide_empty', FALSE))) {
+    // option to display the number of associated nodes
+    if (variable_get('taxonomy_menu_display_num', FALSE)) {
+      $item['name'] .= " ($num)";
+    }
+
+    // build and save the item
+    $link = array(
+      'link_title' => $item['name'],
+      'link_path' => 'taxonomy/term/' . $item['tid'],
+      'menu_name' => $item['menu_name'],
+      'plid' => _taxonomy_menu_get_mlid($item['ptid']),
+      'options' => array('attributes' => array('title' => t($item['description']))),
+      'weight' => $item['weight'],
+      'module' => 'taxonomy_menu',
+    );
+    if ($mlid = menu_link_save($link)) {
+      db_query('INSERT INTO {taxonomy_menu} (mlid, tid, vid) VALUES (%d, %d, %d)', $mlid, $item['tid'], $item['vid']);
+      return $mlid;
+    }
+    else {
+      drupal_set_message(t('Could not save the menu link for the taxonomy menu'), 'error');
+      return FALSE;
+    }
+  }
+}
+
+/**
+ * Return the corresponding menu link id.
+ *
+ * @param $tid
+ *   the term's id
+ */
+function _taxonomy_menu_get_mlid($tid) {
+  return db_result(db_query('SELECT mlid FROM {taxonomy_menu} WHERE tid = %d', $tid));
+}
+
+/**
+ * Retrieve the term / menu relations for a vocab.
+ *
+ * @param $vid
+ *   vocabulary's id
+ * @return
+ *   array(tid => mlid)
+ */
+function _taxonomy_menu_get_menu_terms($vid) {
+  $result = db_query('SELECT mlid, tid FROM {taxonomy_menu} WHERE vid = %d', $vid);
+  $menu_terms = array();
+  while ($data = db_fetch_object($result)) {
+    $menu_terms[$data->tid] = $data->mlid;
+  }
+
+  return $menu_terms;
+}
+
+/**
+ * Delete all links associated with this vocab from both the taxonomy_menu
+ * table and the menu_link table.
+ *
+ * @param $vid
+ *   vocabulary's id
+ */
+function _taxonomy_menu_delete_all($vid) {
+  $menu_terms = _taxonomy_menu_get_menu_terms($vid);
+  if (!empty($menu_terms)) {
+    foreach ($menu_terms as $tid => $mlid) {
+      db_query('DELETE FROM {menu_links} WHERE mlid = %d', $mlid);
+    }
+    db_query('DELETE FROM {taxonomy_menu} WHERE vid = %d', $vid);
+  }
+}
+
+
+
+
+// from here down, unchecked code. from the old version. all appears to be working!
+
+/**
  * Implementation of hook_nodeapi().
  *
  * This hook enables the menu to be displayed in context during node views.
@@ -56,19 +320,65 @@ function taxonomy_menu_nodeapi(&$node, $
   }
 
   if ($op == 'view' and $a4 == TRUE and !empty($vocabs)) {
-    require_once(drupal_get_path('module', 'taxonomy_menu') .'/taxonomy_menu.inc');
     _taxonomy_menu_node_view($node, $vocabs);
   }
   elseif ($op == 'update' or $op == 'insert' or $op == 'delete') {
-      menu_rebuild();
+    menu_rebuild();
   }
 }
 
 /**
- * Implementation of hook_taxonomy().
+ * Generates the breadcumb for nodes that
+ * have a category listed as a menu
  *
- * Invalidates the menu cache on taxonomy changes.
+ * @param
+ *   Object. The node object
+ * @param
+ *   Array. The list of all taxonomy vocabs and
+ *   terms that this node have and are also
+ *   menus
  */
-function taxonomy_menu_taxonomy() {
-  menu_rebuild();
+function _taxonomy_menu_node_view(&$node, &$vocabs) {
+  foreach ($vocabs as $vid => $vocab) {
+    $path = variable_get('taxonomy_menu_display_page', 'category') .'/'. $vid;
+
+    $tree = taxonomy_get_tree($vid);
+    $old_depth = -1;
+    $old_path = $path;
+
+    // Generate the entire breadcumb
+    foreach ($tree as $term) {
+      if ($term->depth <= $old_depth) {
+        $slashes_to_remove = $old_depth - $term->depth + 1;
+        for ($i = 0; $i < $slashes_to_remove; $i++) {
+          $old_path = substr($old_path, 0, strrpos($old_path, "/"));
+        }
+      }
+      $path       = $old_path .'/'. $term->tid;
+      $old_depth  = $term->depth;
+      $old_path   = $path;
+
+      if ($term->tid == $vocab[0]) { //create all the breadcrumb items
+        $breadcrumb=array();
+        $tmpterm=$term;
+        $patharray=explode('/', $path);
+
+        while($tmpterm) { //create items for all the ancestors
+          $breadcrumb[] = l($tmpterm->name, implode('/', $patharray));
+          array_pop($patharray);
+          if(isset($tmpterm->parents[0])) $tmpterm = taxonomy_get_term($tmpterm->parents[0]);
+          else unset($tmpterm); //we're done with ancestors
+        }
+
+        $vocabulary = taxonomy_vocabulary_load($term->vid);
+        $breadcrumb[] = l($vocabulary->name, implode('/', $patharray)); //add the vocabulary item
+        $breadcrumb[] = l(t('Home'), '<front>');
+
+        drupal_set_breadcrumb(array_reverse($breadcrumb));
+
+        // Quit after the first match.
+        return;
+      }
+    }
+  }
 }
