function theme_links

You are here

7 theme.inc theme_links($variables)
4.6 theme.inc theme_links($links, $delimiter = ' | ')
4.7 theme.inc theme_links($links, $delimiter = ' | ')
5 theme.inc theme_links($links, $attributes = array('class' => 'links'))
6 theme.inc theme_links($links, $attributes = array('class' => 'links'))

Returns HTML for a set of links.

Parameters

$variables: An associative array containing:

  • links: An associative array of links to be themed. The key for each link is used as its CSS class. Each link should be itself an array, with the following elements:

    • title: The link text.
    • href: The link URL. If omitted, the 'title' is shown as a plain text item in the links list.
    • html: (optional) Whether or not 'title' is HTML. If set, the title will not be passed through check_plain().
    • attributes: (optional) Attributes for the anchor, or for the <span> tag used in its place if no 'href' is supplied. If element 'class' is included, it must be an array of one or more class names.

    If the 'href' element is supplied, the entire link array is passed to l() as its $options parameter.

  • attributes: A keyed array of attributes for the UL containing the list of links.
  • heading: (optional) A heading to precede the links. May be an associative array or a string. If it's an array, it can have the following elements:

    • text: The heading text.
    • level: The heading level (e.g. 'h2', 'h3').
    • class: (optional) An array of the CSS classes for the heading.

    When using a string it will be used as the text of the heading and the level will default to 'h2'. Headings should be used on navigation menus and any list of links that consistently appears on multiple pages. To make the heading invisible use the 'element-invisible' CSS class. Do not use 'display:none', which removes it from screen-readers and assistive technology. Headings allow screen-reader and keyboard only users to navigate to or skip the links. See http://juicystudio.com/article/screen-readers-display-none.php and http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.

Related topics

18 theme calls to theme_links()
garland_preprocess_page in themes/garland/template.php
Override or insert variables into the page template.
garland_preprocess_page in themes/garland/template.php
Override or insert variables into the page template.
garland_preprocess_page in themes/garland/template.php
Override or insert variables into the page template.
locale_block_view in modules/locale/locale.module
Implements hook_block_view().
page.tpl.php in modules/system/page.tpl.php
Default theme implementation to display a single Drupal page.

... See full list

File

includes/theme.inc, line 1685
The theme system, which controls the output of Drupal.

Code

function theme_links($variables) {
  $links = $variables['links'];
  $attributes = $variables['attributes'];
  $heading = $variables['heading'];
  global $language_url;
  $output = '';

  if (count($links) > 0) {
    $output = '';

    // Treat the heading first if it is present to prepend it to the
    // list of links.
    if (!empty($heading)) {
      if (is_string($heading)) {
        // Prepare the array that will be used when the passed heading
        // is a string.
        $heading = array(
          'text' => $heading,
          
          // Set the default level of the heading.
          'level' => 'h2',
        );
      }
      $output .= '<' . $heading['level'];
      if (!empty($heading['class'])) {
        $output .= drupal_attributes(array('class' => $heading['class']));
      }
      $output .= '>' . check_plain($heading['text']) . '</' . $heading['level'] . '>';
    }

    $output .= '<ul' . drupal_attributes($attributes) . '>';

    $num_links = count($links);
    $i = 1;

    foreach ($links as $key => $link) {
      $class = array($key);

      // Add first, last and active classes to the list of links to help out themers.
      if ($i == 1) {
        $class[] = 'first';
      }
      if ($i == $num_links) {
        $class[] = 'last';
      }
      if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page())) && (empty($link['language']) || $link['language']->language == $language_url->language)) {
        $class[] = 'active';
      }
      $output .= '<li' . drupal_attributes(array('class' => $class)) . '>';

      if (isset($link['href'])) {
        // Pass in $link as $options, they share the same keys.
        $output .= l($link['title'], $link['href'], $link);
      }
      elseif (!empty($link['title'])) {
        // Some links are actually not links, but we wrap these in <span> for adding title and class attributes.
        if (empty($link['html'])) {
          $link['title'] = check_plain($link['title']);
        }
        $span_attributes = '';
        if (isset($link['attributes'])) {
          $span_attributes = drupal_attributes($link['attributes']);
        }
        $output .= '<span' . $span_attributes . '>' . $link['title'] . '</span>';
      }

      $i++;
      $output .= "</li>\n";
    }

    $output .= '</ul>';
  }

  return $output;
}

Comments

If using the suggestion above to add class "element-invisible" to the menu heading, you must specify the 'level' attribute as well, as it does not default to 'h2' when heading is an array.

e.g.

<?php
print theme('links__system_main_menu', //... snip
'heading' => array(
    
'text' => t('Main menu'),
    
'level' => 'h2', //This is required when 'heading' is specified as an array
    
'class' => array(
                     
'element-invisible',
                     ),
    ),
?>

If you want to theme the links itself, override theme_link() or adjust array $main_menu.

Using this theme function, you can take advantage of Drupal's core inline link styling by specifying the proper classes (links and inline) in your attributes array.

From recurly.admin.inc of http://drupal.org/project/recurly:

<?php
print theme('links', array(
 
'links' => $operations,
 
'attributes' => array('class' => array('links', 'inline')),
));
?>

You can theme links in more specific context http://drupal.org/update/modules/6/7#theme_links_with_context

It's subtle, but anything that needs to be passed as an option to the l() link should be part of the link array, e.g.:

<?php
 
// $node = a given node object.
  // $term = a specific term object.
 
$links[] = array(
   
'href'  => 'node/' . $node->nid,
   
'title' => $term->name,
   
'query' => array('tag' => $term->tid),
  );
 
// This will end up as e.g.:
  // <li><a href="node/123?tag=456">termname</a></li>
?>

Be awesome if weight was variable so that you could order the links dynamically. Also be cool if title accepted renderable arrays so you could nest children such as images etc.

The function does not work as expected. Doing the following gives a blank screen without errors.

<?php
function MyModule_test()
{
   
$linklist = array(
 
'item1' => array( 'title' => '1st Item', 'href' => 'one' ),
 
'item2' => array( 'title' => '2nd Item', 'href' => 'two' ),
 
'item3' => array( 'title' => '3rd Item'),
             array(
'title' => '4th Item', 'href' => 'four' ),
 
'item5' => '',
 
'item6' => array( 'title' => '6th Item', 'href' => 'six' )
);

print

theme('links', $linklist);
}
?>

I am putting up a working example because the wording in documentation is impossible to understand without actually seeing the code.

<?php
function inventory_test()
{
 
$linklist = array(
 
'item1' => array( 'title' => '1st Item', 'href' => 'one' ),
 
'item2' => array( 'title' => '2nd Item', 'href' => 'two' ),
 
'item3' => array( 'title' => '3rd Item'),
             array(
'title' => '4th Item', 'href' => 'four' ),
 
'item5' => '',
 
'item6' => array( 'title' => '6th Item', 'href' => 'six' )
);
   
print
theme('links', array(
 
'links' => $linklist,
 
'attributes' => array('class' => array('links', 'inline'))));
}  
?>

The wording might be a little programmer-centric, but it does not flag the 'attributes' part of the array as optional -- hence, it is required.

Thanks for posting your success though!

The addition of the class="active" provided by theme_links() and l() is based on $_GET['q'] which is the standard URL, e.g. node/XX.

If you are creating a list of links with URL aliases, you'll need to pass them through drupal_get_normal_path() first so that they are converted to the standard URL. Then the match will occur and the class="active" will be added.

<?php
//vocabulary Categories
$vid = 2;
//get terms
$terms = taxonomy_get_tree($vid, $parent = 0, $max_depth = NULL, $load_entities = FALSE);

foreach (

$terms AS $term) {
 
$links[$term -> tid] = array(
   
'title' => $term -> name,
   
'href' => 'categories/' . $term -> name,
   
'attributes' => array('class' => array('category'), 'title' => $term -> name),
  );
}

$attributes =array('class' => 'menu-categories');
$heading = array('text' => t('Categories'), 'level' => 'h2', 'class' => 'menu-categories-title');

print

theme_links(array('links' => $links, 'attributes' => $attributes, 'heading' => $heading));
?>

When in a context of hook_node_preprocess we can use the next code:

<?php
  $variables
['content']['links'] = array(
   
'#theme' => 'links',
   
'#links' => array(
      array(
       
'title' => t('Foo'),
       
'href' => 'foo',
       
'attributes' => array('class' => array('foo_class')),
      ),
      array(
       
'title' => t('Bar'),
       
'href' => 'bar',
       
'attributes' => array('class' => array('bar_class')),
      ),
    ),
   
"attributes" => array('class' => array('foo_bar_class')),
  );
?>

The penultimate line in the above is incorrect - 'attributes' should be '#attributes'.

So, should read:

<?php
  $variables
['content']['links'] = array(
   
'#theme' => 'links',
   
'#links' => array(
      array(
       
'title' => t('Foo'),
       
'href' => 'foo',
       
'attributes' => array('class' => array('foo_class')),
      ),
      array(
       
'title' => t('Bar'),
       
'href' => 'bar',
       
'attributes' => array('class' => array('bar_class')),
      ),
    ),
   
"#attributes" => array('class' => array('foo_bar_class')),
  );
?>

Otherwise, a good example of working through the render api.

There is no way to set attributes to the li-tag. It is not flexible.

In my case i need to create programmatically a menu block, looks like the standard menu in Drupal.
And the difference is in

<li class="leaf">

You have to dance with a tambourine to get results.

I have used theme_item_list in order to alter the <li> classes.