in hook_menu():

  $items['tagadelic/chunk/%tagadelic_vocs'] = array(
    'title' => 'Tags',
    'page callback' => 'tagadelic_page_chunk',
    'page arguments' => array(2),
    'access callback' => 'user_access',
    'access arguments' => array('access content'),
    'type' => MENU_SUGGESTED_ITEM,

however, when visiting admin/build/menu-customize/navigation those suggested items do not show.

I am not sure how this is supposed to be done in D6.

#9 tagadelic283198.patch1.35 KBvladimir.dolgopolov
Members fund testing for the Drupal project. Drupal Association Learn more


beginner’s picture

For comparison purposes, this is how it was done in D5:

    foreach (taxonomy_get_vocabularies($type = NULL) as $vocabulary) {
      $items[] = array(
        'title' => $vocabulary->name,
        'path' => "tagadelic/chunk/$vocabulary->vid",
        'callback' => 'tagadelic_page_chunk',
        'access' => user_access('access content'),
        'type' => MENU_SUGGESTED_ITEM);
beginner’s picture

I had the same problem with directory.module.
The solution is to completely restore most of the D5 code which, in this case, is completely valid for D6.
Don't use the wildcard loader.

Here is the valid D6 code for directory.module:

  $vocabularies = taxonomy_get_vocabularies();
  foreach ($vocabularies AS $vid => $vocabulary) {
    $items['directory/vocabulary/' . $vocabulary->vid] = array(
      'title' => t('Directory for !vocabulary-name', array('!vocabulary-name' => $vocabulary->name)),
      'page callback' => 'directory_vocabulary_page',
      'page arguments' => array(2),
      'access arguments' => array('access content'),
      'type' => MENU_SUGGESTED_ITEM,
Crell’s picture

Did you actually create a tagadelic_vocs_load() function? The menu system kinda needs that if you're going to declare a menu hook that way. Although you probably want vocabulary_load() instead (which may or may not exist yet; not sure off hand).

A foreach loop inside a D6 menu handler is 99% of the time the WRONG way to do it.

beginner’s picture

I noticed this bug with my own module (directory.module). I knew that tagadelic has a similar menu structure and that's why I checked it out.

I was using core taxonomy_vocabulary_load() function (used with the wildcard). The code worked fine as a callback. The problem is that there is no menu item ready to be enabled, like it is supposed to do.

This is the code I had just after upgrading to D6:

  $items['directory/vocabulary/%taxonomy_vocabulary'] = array(
    'title callback' => 'directory_vocabulary_title',
    'title arguments' => array(2),
    'page callback' => 'directory_vocabulary_page',
    'page arguments' => array(2),
    'access arguments' => array('access content'),
    'type' => MENU_SUGGESTED_ITEM,

As I said, it worked nice as a MENU_CALLBACK, but did not fulfill its function as MENU_SUGGESTED_ITEM.

The HEAD version of directory.module uses the code in #2, which works as intended.

So, if the foreach loop is wrong, how do I get MENU_SUGGESTED_ITEM without it?

tagadelic has exactly the same problem.

earnie’s picture


beginner’s picture

Here is the official way to fix this particular bug.

> In most cases, you DO want to remove the foreach() loop you had in D5.

there, I fixed for you :)

> Within D6, it is ALMOST NEVER NEEDED TO HAVE a loop, recursively declaring several
> well defined menu items, e.g. one item for each vocabulary. When you have
> such a loop, DO use the wildcard loader.

there, I fixed for you :)

You forgot about the distinction of router items and menu links. You will want to use a single router item and save several links with menu_link_save as you see fit.


Karoly Negyesi

Thanks to karoly for the feedback.

vladimir.dolgopolov’s picture

Sorry but I didn't quite get what to do with MENU_SUGGESTED_ITEM and a wildcard loader here.

Bèr Kessels’s picture

Interesting. I did not test tagadelic on 6 myself, because I havo no 6 sites yet. It may have skipped past the people who reviewed the upgrades, though.

Lets solve this fast!

vladimir.dolgopolov’s picture

1.35 KB

Here is the patch.
It enabled menu items like in D5, but using menu_link_maintain() function.
Not sure it it a good solution so the menu item enabled by default.
But menu_link_maintain() does not include a mechanism to enable/disable a link.

vladimir.dolgopolov’s picture

Status: Active » Needs review

oops, forgot to change status.

Bèr Kessels’s picture

Status: Needs review » Needs work

I am not very enthusiastic about the solution with menu_link_maintain(). AFAIK we should be able to fix this within the hook_menu very simple.

kurosevic’s picture

hopefully this one can be explained to me. I'm upgrading a module, and a function in it is getting flagged for its use of the foreach loop, but i dont really understand whats happening in the function, so i'm not sure how to approach getting rid of the foreach.

function &ninjitsu_newsletter_get_issue_drop_down_data() {
  $issue_vocab_id = variable_get('ninjitsu_newsletter_issue_vid',  '');
  $vtree = taxonomy_get_tree($issue_vocab_id);
  $drop_down_data = array();
  foreach ($vtree as $issue) {
    $nodes = taxonomy_select_nodes(array($issue->tid));
    while ($nnode = db_fetch_object($nodes)) {
      $nnode = node_load($nnode);
      // only display issues that have nodes of the correct type
      if ($nnode->type == variable_get('ninjitsu_newsletter_main_node_type',  'newsletter')) {
        $drop_down_data[$issue->tid] = $issue->name . ' - ' . $nnode->title;
  return $drop_down_data;
Bèr Kessels’s picture

Closing "needs work" that has been open for a long time, without anyone working on it.

Bèr Kessels’s picture

Status: Needs work » Closed (won't fix)