Please can someone help with this. I have a very simple site and taxonomy. The taxonony is:

1) News
1.1) US
1.2) Europe
1.3) Rest of World

2) Sport
2.1) Football
2.2) Baseball

etc.

Whenever I create a new node you can only select one taxonomy term. For instance News-Rest of World.

In this case the term is Rest of World and the parent is News.

My primary links are simply driven off the taxonomy eg, by linking to taxonomy/term/3/all where term 3 is News. This displays a list of all the nodes filed under US, Europe of Rest of World. Using either theme_links or displaying the primary links as a menu block I can generate an active class allowing me to highlight the primary link the tab falls under

The problem is when I click on a single node. This node will have been filed under "Rest of World" but when I display the full node the primary link loses its tab.

I have developed a workaround to query the database to find the parent and I can overide theme_links() to highlight the tab. The query code is stored in the page-node.tpl.php file and is:

		 			<?php $result = db_result(db_query("SELECT tid FROM {term_node} WHERE nid = $node->nid"));?>
		 			
		 			<?php $result2 = db_result(db_query("SELECT h.parent, d.tid FROM {term_data} d INNER JOIN {term_hierarchy} h ON d.tid = h.tid WHERE d.tid = $result")); ?>
		 			<?php $result3 = db_result(db_query("SELECT name, tid FROM {term_data} WHERE tid = $result2")); ?>
					<?php $active = "taxonomy/term/".$result2."/all"; ?>

However, this doesn't feel a particularly elegant solution. I have been told by a few people that you should be able to do this in Drupal 6 without resorting to this hack fix. Hunting around I say the theme_menu_item() applied an "active-trail" class, which may work.

I have no idea how to implement this (presumably through the menu block) so if any of you know how this works or have any other solutions that would be most helpful.

Thanks
Jon

Comments

mcjim’s picture

johnbeamer’s picture

That module only works for Drupal 5. This is the best solution I have found for D6. Any improvements welcome ...

mcjim’s picture

I'm no mean coder, but I had a look at this a little more because it's a recurring issue.
Try this in your template.php:

function phptemplate_menu_item_link($link) {
	$active = FALSE;
  if (empty($link['options'])) {
    $link['options'] = array();
  }
	// Check the link_path is type taxonomy/term/tid
	$cat = explode('/', $link['link_path']);
  if ($cat[0] == 'taxonomy' && $cat[1] == 'term' && is_numeric($cat[2])) {
		if ($cat[2] == variable_get('temp_node_tid', FALSE)) {
			$active = TRUE;
			// Clean up variable as we only want it to apply once
			variable_del('temp_node_tid');
		}
	}
  // Append active class.
  if ($active) {
    if (isset($link['options']['attributes']['class'])) {
      $link['options']['attributes']['class'] .= ' active';
    }
    else {
      $link['options']['attributes']['class'] = 'active';
    }
  }
  return l($link['title'], $link['href'], $link['options']);
}

with this in a module:

function YOURMODULENAME_nodeapi(&$node, $op, $a3 = NULL, $page = FALSE) {
  if ($op == 'view' && $page == TRUE) {
    $node_taxonomy = reset($node->taxonomy);
    $tid = $node_taxonomy->tid;
    variable_set('temp_node_tid', $tid);
    
    // Generate the entire breadcumb
    $parents = array_reverse(taxonomy_get_parents_all($tid));
    $breadcrumb_items[] = (l(t('Home'), NULL));
    
    foreach ($parents as $parent) {
      $path = 'taxonomy/term/'. $parent->tid .'/all';
      $breadcrumb_items[] = l(t($parent->name), $path);
    }    
    drupal_set_breadcrumb($breadcrumb_items);
  }
}

I'll leave it to you to tidy it up!

johnbeamer’s picture

That's a helpful bit of code -- thanks.

I have a question on this bit of code:

  // Append active class.
  if ($active) {
    if (isset($link['options']['attributes']['class'])) {
      $link['options']['attributes']['class'] .= ' active';
    }
    else {
      $link['options']['attributes']['class'] = 'active';
    }

It seems as though you are doing the same thing irrespective of whether $active is true or false. If true you are appending active, if false you are replacing the class with active -- how does that help?

I actually ended up tackling the issue a slightly different way. Here is the detail for those interested: http://drupal.org/node/216763

mcjim’s picture

The if-else inside the if($active) simply adds a space in front of "active" if there are already other classes.

johnbeamer’s picture

McJim -- if $active was false why would you want to set the class to "active"?

mcjim’s picture

$active == false doesn't add anything. There's no else.

johnbeamer’s picture

Thanks. My error -- I misread the code. Appreciate the help.