1

How can I add custom classes for links into main menu in Drupal 8. This is template for my main menu called menu--main.html.twig

{% import _self as menus %}
{{ menus.menu_links(items, attributes, 0) }}

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    {% if menu_level == 0 %}
        <ul{{ attributes.addClass('main-nav') }}>

        {% for item in items %}
        <li{{ item.attributes.addClass('main-nav__item') }}>
            {{ link(item.title, item.url) }}
            {% if item.below %}
                {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
            {% endif %}
        </li>
        {% endfor %}
    {% else %}
        <ul class="main-nav__sub js-nav-submenu ">

        {% for item in items %}
        <li{{ item.attributes.addClass('main-nav__sub-item') }}>
            {{ link(item.title, item.url) }}
            {% if item.below %}
                {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
            {% endif %}
        </li>
        {% endfor %}
    {% endif %}
    </ul>
  {% endif %}
{% endmacro %}

And I need to achieve this result:

<ul class="main-nav">
  <li class="main-nav__item"><a class="main-nav__link main-nav__link--active" href="index.html">Úvod</a></li>
  <li class="main-nav__item"><a class="main-nav__link js-nav-submenu-toggler" href="#">O škole</a>
    <ul class="main-nav__sub js-nav-submenu">
      <li class="main-nav__sub-item"><a class="main-nav__sub-link" href="#">Aktuality</a></li>
      <li class="main-nav__sub-item"><a class="main-nav__sub-link " href="pedagogovia.html">Pedagógovia</a></li>
      <li class="main-nav__sub-item"><a class="main-nav__sub-link" href="#">Dokumenty</a></li>
      <li class="main-nav__sub-item"><a class="main-nav__sub-link " href="historia.html">História</a></li>
    </ul>
  </li>
  <li class="main-nav__item"><a class="main-nav__link" href="#">Informácie o štúdiu</a></li>
  <li class="main-nav__item"><a class="main-nav__link" href="#">Fotogaléria</a></li>
  <li class="main-nav__item"><a class="main-nav__link " href="kontakt.html">Kontakt</a></li>
</ul>

My problem is that I don't know how to set custom class for <a href=""> tags. Is there any way how can do it using link() function. In Drupal 7 is l() function but attributes aren't similar. l() has also third attribute with possibility to add options. Is it true, that link($title, $url) accepts only 2 parameters? Because I can't find the way how to send options for link($title, $url). I don't insit on link() function, so if there is some better way please let me know. I'm open to new ideas :)

Thanks

4 Answers 4

2

Just incase someone stumbles upon this, Martin's solve above breaks URL fragments as it overrides the URL options completely. The better approach is here:

{{ link(item.title, item.url.setOption('attributes', {'class' : 'main-nav__link'})) }}
1
  • Can we done this using theme_preprocess_menu()?
    – Guru
    Jan 12, 2016 at 9:49
2

Just replace

{{ link(item.title, item.url) }}

by

{{ link(item.title, item.url, { 'class':['main-nav__link']}) }}
1
  • Yes this is the correct answer, this is the declartion for the Drupal twig extension link. Drupal\Core\Template\TwigExtension:getLink($text, $url, $attributes = [])
    – m.khamash
    Dec 28, 2015 at 10:08
1

I finally solved it using next syntax in Twig template

{{ link(item.title, item.url.setOptions({'set_active_class' : TRUE, 'attributes' : {'class' : 'main-nav__link'}})) }}
1
  • For some reason this does not work on RC4. I test it out on RC2 and it works in fine. This is what it show Twig_Sandbox_SecurityError: Calling "setOptions" method on a "Drupal\Core\Url" Nov 14, 2015 at 10:49
0

file name /var/www/html/drupal/themes/theme_name/templates/navigation/menu.html.twig

we are checking menu name in if condition {% if menu_name ==’account’ %}

below is the whole code you may copy and replace it

  {#
  /**
   * @file
   * Theme override to display a menu.
   *
   * Available variables:
   * - menu_name: The machine name of the menu.
   * - items: A nested list of menu items. Each menu item contains:
   *   - attributes: HTML attributes for the menu item.
   *   - below: The menu item child items.
   *   - title: The menu link title.
   *   - url: The menu link url, instance of \Drupal\Core\Url
   *   - localized_options: Menu link localized options.
   *   - is_expanded: TRUE if the link has visible children within the current
   *     menu tree.
   *   - is_collapsed: TRUE if the link has children within the current menu tree
   *     that are not currently visible.
   *   - in_active_trail: TRUE if the link is in the active trail.
   */
  #}
  {% import _self as menus %}

  {#
    We call a macro which calls itself to render the full tree.
    @see http://twig.sensiolabs.org/doc/tags/macro.html
  #}
  {{ menus.menu_links(items, attributes, 0,menu_name) }}


  {% macro menu_links(items, attributes, menu_level,menu_name) %}
    {% import _self as menus %}
    {% if items %}

      {% if menu_level == 0 %}
            {% if menu_name =='account' %}
                <ul{{ attributes.addClass('') }}>
            {% endif %}

            {% if menu_name =='main' %}
                <ul{{ attributes.addClass('menu nav navbar-nav') }}>
            {% endif %}

      {% else %}
              <ul{{ attributes.addClass('menu nav navbar-nav') }}>
      {% endif %}
      {% for item in items %}
        {%
          set classes = [
            'menu-item',
            item.is_expanded ? 'menu-item--expanded',
            item.is_collapsed ? 'menu-item--collapsed',
            item.in_active_trail ? 'menu-item--active-trail',
          ]
        %}
        <li{{ item.attributes.addClass(classes) }}>
          {{ link(item.title, item.url) }}
          {% if item.below %}
            {{ menus.menu_links(item.below, attributes, menu_level + 1) }}
          {% endif %}
        </li>
      {% endfor %}
      </ul>
    {% endif %}
  {% endmacro %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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