8.5.x theme.inc template_preprocess_links(&$variables)
8.0.x theme.inc template_preprocess_links(&$variables)
8.1.x theme.inc template_preprocess_links(&$variables)
8.2.x theme.inc template_preprocess_links(&$variables)
8.3.x theme.inc template_preprocess_links(&$variables)
8.4.x theme.inc template_preprocess_links(&$variables)
8.6.x theme.inc template_preprocess_links(&$variables)

Prepares variables for links templates.

Default template: links.html.twig.

Unfortunately links templates duplicate the "active" class handling of l() and LinkGenerator::generate() because it needs to be able to set the "active" class not on the links themselves (<a> tags), but on the list items (<li> tags) that contain the links. This is necessary for CSS to be able to style list items differently when the link is active, since CSS does not yet allow one to style list items only if it contains a certain element with a certain class. I.e. we cannot yet convert this jQuery selector to a CSS selector: jQuery('li:has("a.is-active")')


array $variables: An associative array containing:

  • links: An array of links to be themed. Each link should be itself an array, with the following elements:

    • title: The link text.
    • url: (optional) The \Drupal\Core\Url object to link to. If omitted, no anchor tag is printed out.
    • 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.
  • set_active_class: (optional) Whether each link should compare the route_name + route_parameters or href (path), language and query options to the current URL, to determine whether the link is "active". If so, an "active" class will be applied to the list item containing the link, as well as the link itself. It is important to use this sparingly since it is usually unnecessary and requires extra processing. For anonymous users, the "active" class will be calculated on the server, because most sites serve each anonymous user the same cached page anyway. For authenticated users, the "active" class will be calculated on the client (through JavaScript), only data- attributes are added to list items and contained links, to prevent breaking the render cache. The JavaScript is added in system_page_attachments().
  • 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').
    • attributes: (optional) An array of the CSS attributes 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 'visually-hidden' 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.

See also





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


function template_preprocess_links(&$variables) {
  $links = $variables['links'];
  $heading =& $variables['heading'];
  if (!empty($links)) {

    // Prepend the heading to the list, if any.
    if (!empty($heading)) {

      // Convert a string heading into an array, using a <h2> tag by default.
      if (is_string($heading)) {
        $heading = [
          'text' => $heading,

      // Merge in default array properties into $heading.
      $heading += [
        'level' => 'h2',
        'attributes' => [],

      // Convert the attributes array into an Attribute object.
      $heading['attributes'] = new Attribute($heading['attributes']);
    $variables['links'] = [];
    foreach ($links as $key => $link) {
      $item = [];
      $link += [
        'ajax' => NULL,
        'url' => NULL,
      $li_attributes = [];
      $keys = [
      $link_element = [
        '#type' => 'link',
        '#title' => $link['title'],
        '#options' => array_diff_key($link, array_combine($keys, $keys)),
        '#url' => $link['url'],
        '#ajax' => $link['ajax'],

      // Handle links and ensure that the active class is added on the LIs, but
      // only if the 'set_active_class' option is not empty.
      if (isset($link['url'])) {
        if (!empty($variables['set_active_class'])) {

          // Also enable set_active_class for the contained link.
          $link_element['#options']['set_active_class'] = TRUE;
          if (!empty($link['language'])) {
            $li_attributes['hreflang'] = $link['language']

          // Add a "data-drupal-link-query" attribute to let the
          // drupal.active-link library know the query in a standardized manner.
          if (!empty($link['query'])) {
            $query = $link['query'];
            $li_attributes['data-drupal-link-query'] = Json::encode($query);

          /** @var \Drupal\Core\Url $url */
          $url = $link['url'];
          if ($url
            ->isRouted()) {

            // Add a "data-drupal-link-system-path" attribute to let the
            // drupal.active-link library know the path in a standardized manner.
            $system_path = $url

            // @todo System path is deprecated - use the route name and parameters.
            // Special case for the front page.
            $li_attributes['data-drupal-link-system-path'] = $system_path == '' ? '<front>' : $system_path;
        $item['link'] = $link_element;

      // Handle title-only text items.
      $item['text'] = $link['title'];
      if (isset($link['attributes'])) {
        $item['text_attributes'] = new Attribute($link['attributes']);

      // Handle list item attributes.
      $item['attributes'] = new Attribute($li_attributes);

      // Add the item to the list of links.
      $variables['links'][$key] = $item;