I would like to add <br> tag or &nbsp; character to html menu, but when I type Home <br> Page, it does display as plain text, but I want to break that words by two lines.

How can I modify my template.php file with hooks, to allow html tags in menu titles?

  • Are all the links in menu the same as that? – Alex Gill Nov 28 '12 at 12:23
  • Some links are, some not. For example for "About" page, I don't need separate anything. – Lado Lomidze Nov 28 '12 at 12:26
  • 1
    You could certainly do this on the theme level using hook_menu_link but you would have to use a conditional to be specific about which links you want to add <br> to. – Alex Gill Nov 28 '12 at 12:37
  • Why can't I just parse and allow that only tag? – Lado Lomidze Nov 28 '12 at 12:44
  • 1
    Well, i've found a solution .. I added $output = str_replace('&lt;br&gt;', '<br>', $output); line to the function api.drupal.org/api/drupal/includes!menu.inc/function/… and it worked – Lado Lomidze Nov 28 '12 at 12:59

Maybe your problem can be solved using the Menu HTML module. It seems to have been designed to solve issues such as the one you describe.

This very simple module adds a checkbox to the menu item edit form and allows the admin to add html to the menu item title. The idea is to use this for external links for which you want to display a logo of the visited site or simply to add strong on some words.


Actually it depends on which menus you want to change, but for main and secondary menus you should be able to add this to your theme_preprocess_page function :

function yourtheme_preprocess_page(&$variables, $hook) {
    foreach ($variables['main_menu'] as &$link) {
        $link['html'] = TRUE;

for secondary menu replace ['main_menu'] by ['secondary_menu']

  • Is there a way to do this in a generic way, i.e. not relying on specific template changes? Thanks. – Gabriel R. Sep 27 '13 at 10:03

Other method in template.php, for main_menu in the example below:

function THEMENAME_links__system_main_menu($vars) {
  foreach ($vars['links'] as &$link) {
    $link['html'] = TRUE;
  return theme_links($vars);

In template.php of your theme. This allows html in all menu links.

function THEMENAME_menu_link(array $variables) {
  foreach($variables as &$variable) {
    $variable['#localized_options']['html'] = TRUE;
  return theme_menu_link($variables);
  • can the person who gave -1 explain why? – Hans Rossel Jul 14 '18 at 9:23

I found this to work perfectly when added to your (sub-)theme's template.php, with YOURTHEMENAME replaced by your (sub-)theme's name:

function YOURTHEMENAME_link($variables) {
  $variables['options']['html'] = TRUE;
  return '<a href="' . check_plain(url($variables['path'], $variables['options'])) . '"' . drupal_attributes($variables['options']['attributes']) . '>' . ($variables['options']['html'] ? $variables['text'] : check_plain($variables['text'])) . '</a>';

It is an override of the theme_link() function defined in drupal/includes/theme.inc; only the $variables['options']['html'] = TRUE; line was added.

Source: https://www.drupal.org/node/112352#comment-5890386


Did not want to use the Menu HTML as you need to check mark each menu link.

Here is how I did it programmatically:

function THEMENAME_preprocess_menu_link(array &$variables) {
  $element = &$variables['element'];
  foreach ($element as $value) {
    if (strpos($element['#title'], '<div class="test">') === false) {
      $element['#title'] = '<div class="test">' . $element['#title'] . '</div>';
      $element['#localized_options']['html'] = TRUE;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.