Changing Primary Links to Images
On my site, I wanted to use images instead of text for the primary tabs, so I came up with a method to do so. You'll want to look for where the primary links are generated in page.tpl.php. The default is this:
<?php if (is_array($primary_links)) : ?>
<ul id="primary">
<?php foreach ($primary_links as $link): ?>
<li><?php print $link?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>And you'll want to replace it with this snippet:
<?php if(is_array($primary_links)) : ?>
<ul id="primary">
<?php
$l2i['pattern'] = '$(<a.*>)(.*)(</a>)$ie';
$l2i['themepath'] = url($directory);
$l2i['replacement'] = "\"\\1\".'<img src=\"$l2i[themepath]/icon_'.str_replace(' ','_',strtolower('\\2')).'.png\" alt=\"\\2\" />\\3'";
foreach ($primary_links as $link) {
print "<li>".preg_replace($l2i['pattern'],$l2i['replacement'],$link)."</li>\n";
}
unset($l2i);
?>
</ul>
<?php endif; ?>The images should be stored in your themes directory. You should make your icon names be in the format of "icon_menu_item.png", where "Menu Item" is the title of the Link. Here's some more examples:
Pictures - "icon_pictures.png"
Graphic Design - "icon_graphic_design.png"
Basically, you'll want to make the title lowercase, change the spaces to underscores, and wrap it with "icon_" and ".png".

images in the menu
I came up with another solution.
Its almost doing the same thing but im also checking to se if the menu elm is active, and i put it inside my template.php file
The images is placed in: THEME_NAME/images/menu/
normale menu files: menu_1.gif, menu_2.gif ... etc
active menu files:menu_1_active.gif, menu_2_active.gif ... etc
template.php:
function phptemplate_menu_links($links) {
if (!count($links)) {
return '';
}
$i="1";
foreach ($links as $index => $link) {
//image
if (stristr($index, "active")) {
$img = '<a href="$1" title="$2"><img src="'.base_path() . path_to_theme().'/images/menu/menu_'. $i .'_active.gif" alt="$3"></a>';
}else{
$img = '<a href="$1" title="$2"><img src="'.base_path() . path_to_theme().'/images/menu/menu_'. $i .'.gif" alt="$3"></a>';
}
$output .= preg_replace('/<a href="(.*?)" title="(.*?)">(.*?)<\\/a>/i', $img, $link);
$output .= "\n";
$i++;
}
return $output;
}
call the menu inside page.php
if (isset($primary_links)) {print phptemplate_menu_links($primary_links);
}
enjoy :)
/morten.dk *king of Denmark*
Another solution
I modified the approach in http://drupal.org/node/110199 so that I can replace a menu name with an arbitrary image as follows:
In template.php, instead of rewriting theme_menu_item_link(),
rewrite theme_menu_links() as follows:
<?php
function phptemplate_menu_links($links) {
if (!count($links)) {
return '';
}
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];
$output = "<ul class=\"links-$level\">\n";
foreach ($links as $index => $link) {
$output .= '<li';
if (stristr($index, 'active')) {
$output .= ' class="active"';
}
if (strpos($link['title'], '<img') === 0) {
$output .= ">". l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, TRUE) ."</li>\n";
}
else {
$output .= ">". l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']) ."</li>\n";
}
}
$output .= '</ul>';
return $output;
}
?>
Icons in Primary Links
This is another solution that allows to add images to the primary links. This is a combined solution from a few posts and themes. Also, I tested it on Drupal 5.7 - works OK.
1. FIRST SOLUTION: add images as a background
1a. Add the below code to template.php (template.php is located inside the themes/theme_you_are_using/):
<?php// allows to display icons with the primary links
function primary_links_add_icons() {
$links = menu_primary_links();
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];
$output = "<ul class=\"links-$level\">\n";
if ($links) {
foreach ($links as $link) {
$link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
$cssid = str_replace(' ', '_', strip_tags($link));
$output .= '<li id="'.$cssid.'">' . $link . '</li>';
};
$output .= '</ul>';
}
return $output;
}
?>
1b. Change primary links code in the page.tpl.php (page.tpl.php is located inside the themes/theme_you_are_using/)
Original code in Zen themes (code may vary from theme to theme but basically we are looking for $primary_links var)
<?php if ($primary_links): ?><div id="primary">
<?php print theme('links', $primary_links); ?>
</div> <!-- /#primary -->
<?php endif; ?>
Change to
<?php<!-- changed to display primary links with icons-->
<?php if ($primary_links): ?>
<div id="primary">
<?php print primary_links_add_icons(); ?> //name of the function must match the name used above in template.php
</div> <!-- /#primary -->
<?php endif; ?>
?>
1c. Add to the styles.css (style.css is located inside the themes/theme_you_are_using/)
li#Articles_and_Stories a{display: block;
background: url(../images/icons/articles_and_stories.gif) no-repeat top center;
}
li#Assess_Skills a{
display: block;
background: url(../images/icons/assess_skills.gif) no-repeat top center;
}
li#Do_Activities a{
display: block;
background: url(../images/icons/do_activities.gif) no-repeat top center;
}
Where "Articles_and_Stories", "Assess_Skills", "Do_Activities" are the primary links menu items with titles like "Articles and Stories", "Assess Skills", "Do Activities". Remember to add _ between the words used in the menu title to create a proper css code.
2. SECOND SOLUTION: add images using img src tag (which gives more options to manipulate the layout)
2a. Add the below code to template.php (template.php is located inside the themes/theme_you_are_using/):
function primary_links_add_icons() {$links = menu_primary_links();
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];
$output = "<ul class=\"links-$level\">\n";
if ($links) {
foreach ($links as $link) {
$link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
$cssid = str_replace(' ', '_', strip_tags($link));
$output .= '<li id="'.$cssid.'"><img src="'. path_to_theme() .'/images/icons/'. $cssid.'.gif">' . $link . '</li>';
};
$output .= '</ul>';
}
return $output;
}
In my case, icons are store in the current themes directory, in images/icons/ folder and have extension .gif but that can be changed by changing the line
$output .= '<li id="'.$cssid.'"><img src="'. path_to_theme() .'/images/icons/'. $cssid.'.gif"><br />' . $link . '</li>';2b. Change primary links code in the page.tpl.php (page.tpl.php is located inside the themes/theme_you_are_using/) - use the same code as listed above under 1b.
3. THIRD SOLUTION: very much like the 2nd, but allows the image to be clickable
I used the original code posted at the top of the page and modified it to include both link title and image.
3a. Add the below code to template.php (template.php is located inside the themes/theme_you_are_using/):
function primary_links_add_icons() {$links = menu_primary_links();
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];
$output = "<ul class=\"links-$level\">\n";
$l2i['pattern'] = '$(<a.*>)(.*)(</a>)$ie';
$l2i['replacement'] = "\"\\1\".'<img src=\"'. path_to_theme() .'/images/icons/'.str_replace(' ','_',strtolower('\\2')).'.gif\" alt=\"\\2\" />\\2\\3'";
if ($links) {
foreach ($links as $link) {
$link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
$output .= '<li>'. preg_replace($l2i['pattern'],$l2i['replacement'],$link) .'</li>';
};
$output .= '</ul>';
}
return $output;
}
In my case, icons are store in the current themes directory, in images/icons/ folder and have extension .gif but that can be changed by changing the line
$l2i['replacement'] = "\"\\1\".'<img src=\"'. path_to_theme() .'/images/icons/'.str_replace(' ','_',strtolower('\\2')).'.gif\" alt=\"\\2\" />\\2\\3'";3b. Change primary links code in the page.tpl.php (page.tpl.php is located inside the themes/theme_you_are_using/) - use the same code as listed above under 1b.
4. FOURTH SOLUTION: display icons (images) but no text
4a. Add the below code to template.php (template.php is located inside the themes/theme_you_are_using/):
function primary_links_icons_only() {$links = menu_primary_links();
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];
$output = "<ul class=\"links-$level\">\n";
$l2i['pattern'] = '$(<a.*>)(.*)(</a>)$ie';
$l2i['replacement'] = "\"\\1\".'<img src=\"'. path_to_theme() .'/images/icons/'.str_replace(' ','_',strtolower('\\2')).'.gif\" alt=\"\\2\" />\\3'";
if ($links) {
foreach ($links as $link) {
$link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
$output .= '<li>'. preg_replace($l2i['pattern'],$l2i['replacement'],$link) .'</li>';
};
$output .= '</ul>';
}
return $output;
}
4b. Add code to the page.tpl.php or, if you are using CCK module and want to display those links only on certain type of pages (for example, only on title pages and you created Title Pages template, add this code in node-title_pages.tpl.php, located inside the themes/theme_you_are_using/)
<?php<!-- changed to display primary links with icons but no text-->
<?php if ($primary_links): ?>
<div id="primary">
<?php print primary_links_icons_only(); ?> //name of the function must match the name used above in template.php
</div> <!-- /#primary -->
<?php endif; ?>
?>
Instead of doing the
Instead of doing the preg_replace for option 4, can't you just use option 1 and wrap the link in a span tag. Then, in your CSS set the span tag so that it doesn't display. This is what they do on the csszengarden website to replace words with images using straight CSS. So, for your function, it'd be something like:
<?php// allows to display icons with the primary links
function primary_links_add_icons() {
$links = menu_primary_links();
$level_tmp = explode('-', key($links));
$level = $level_tmp[0];
$output = "<ul class=\"links-$level\">\n";
if ($links) {
foreach ($links as $link) {
$link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
$cssid = str_replace(' ', '_', strip_tags($link));
$output .= '<li id="'.$cssid.'"><span class="menu-hidden-text">' . $link . '</span></li>';
};
$output .= '</ul>';
}
return $output;
}
?>
And then for the CSS it would be:
.menu-hidden-text {display: hidden; }Thanks,
Shane