Nick Lewis covered how to assign unique CSS Ids for menus in the navigation block in a recent article.

In this article, I describe how to do the same for the primary and secondary links.

With some modifications, this technique can also be used to manipulate the  primary and secondary links in other ways.

First, in the template.php of your theme, add this function. If there is no template.php file, then create one.

function phptemplate_menu_links($links) {
return _phptemplate_callback('menu_links', array(
'links' => $links,
));
}

Then, create a file called menu_links.tpl.php in your theme directory.

<?php
if (!count($links)) {
return '';
}
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];

$output = "<ul class=\"links-$level\">\n";

foreach ($links as $index => $link) {
$css_id = str_replace(' ', '_', strip_tags($link));

$output .= '<li';

if (stristr($index, 'active')) {
$output .= ' class="active"';
}

$output .= ' id="' . $css_id . '">'. $link ."</li>\n";
}

$output .= '</ul>';

print $output;

Finally, in the page.tpl.php file, you add this where you want the primary or secondary links to appear:

    <?php if (isset($primary_links)) : ?>
<div id="nav-primary">
<?php print theme('menu_links', $primary_links) ?>
</div>
<?php endif; ?>

And

    <?php if (isset($secondary_links)) : ?>
<div id="nav-secondary">
<?php print theme('menu_links', $secondary_links) ?>
</div>
<?php endif; ?>

Now each of the items will have a unique id and you add the ids in the style.css file. 

Comments

Sat, 2006/09/02 - 18:28

Just a note, that for the next 5.0 release of Drupal, this is actually built in. I wrote a patch to do just this and it's been committed. Classes are also added to all hook_links() too.

More details: http://drupal.org/node/64292#menu-links

Tue, 2007/02/27 - 14:03

How can i add a li class to the first level of a menu in a navigationblock ?
Example: menu1, menu2, menu3,... should have the class "primary".

Tue, 2007/09/11 - 17:52

The following line doesn't work:
$css_id = str_replace(' ', '_', strip_tags($link));

It always shows up as id="Array".

i replaced it with the following and the IDs were given the names of the links
$css_id = $link['title'];

Thu, 2008/11/13 - 05:32

Thankx a lot, although this is an old topic I still needed something like this.

Above code still gave an array for the links name. I fixed it with this code:
$output .= ' id="' . $css_id . '">'. $link['title'] ."

\n";

------Full Code

<?php
if (!count($links)) {
return '';
}
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];

$output = "

    \n";

    foreach ($links as $index => $link) {
    $css_id = $link['title'];

    $output .= '

  • '. $link['title'] ."
  • \n";
    }

    $output .= '

';

print $output;

Is your Drupal or Backdrop CMS site slow?
Is it suffering from server resources shortages?
Is it experiencing outages?
Contact us for Drupal or Backdrop CMS Performance Optimization and Tuning Consulting