2

My Q is equal as Remove link from active page in menu

I need the active page in my menu not to be a link.

So let's say I'm on the services page, I need my menu structure to look like this:

<ul class="menu">
    <li class="first leaf"><a href="/mysite/">home</a></li>
    <li class="leaf">services</li>
    <li class="leaf"><a href="/mysite/portfolio">portfolio</a></li>
    <li class="leaf"><a href="/mysite/contact">contact</a></li>
</ul>

How can I do that in drupal 8?

Update what about this thing in my theme menu--main.html.twig?

{% if item.attributes.hasClass('active') %}
<span>{{ item.title }}</span>
{%- else -%}
{{ link(item.title, item.url) }}
{%- endif -%}

2 Answers 2

4

In D8 the handling of active links is split between php and js, so that the menus can be cached independently from the page they appear on. A solution in php or twig is only possible when you switch off caching of menus, but this is not good for performance. So a better approach is probably in javascript.

Remove the link tag by selecting the links with the class is-active:

mytheme/js/remove-active-links.js

(function ($, Drupal) {

  'use strict';

  Drupal.behaviors.removeActiveLinks = {
    attach: function (context) {

      $(context).find('a.is-active').contents().unwrap();

    }
  };

})(jQuery, Drupal);

You need to define a dependency on the core active-link.js, which sets the class is-active, so that your js file runs later:

mytheme/mytheme.libraries.yml

remove-active-links:
  version: 1.x
  js:
    js/remove-active-links.js: { }
  dependencies:
    - core/jquery
    - core/drupal
    - core/drupal.active-link

Background information

The js code above is the most basic solution, but it loads jQuery also for anonymous traffic, which is not a problem if you already use it.

If you want to avoid jQuery see ActiveLinkResponseFilter, which is a response subscriber adding the class is-active for anonymous requests.

You can then alter the result in a custom response subscriber with a lower priority, similar to the js code above.

5
  • Thanks! but I think it's not good solution for SEO?
    – wakh.ru
    Commented Apr 28, 2017 at 14:26
  • Don't think that's bad for SEO, but it doesn't matter, because googlebot crawls javascript for about 2 or 3 years now. And I think as drupal goes ahead with optimizing menu caching strategy with javascript it's best to follow the same path.
    – 4uk4
    Commented Apr 28, 2017 at 14:45
  • you are right and your solution working so thank you again!
    – wakh.ru
    Commented Apr 28, 2017 at 14:50
  • What do you think about my update?
    – wakh.ru
    Commented Apr 28, 2017 at 22:52
  • The class active is for the active trail, not for the active link. I put some background information in the answer for a php solution.
    – 4uk4
    Commented Apr 29, 2017 at 8:02
0

The HTML is generated by a twig template, you should see {% for item in items %} in one of your theme's menu templates, and then do a condition e.g. {% if item.in_active_trail %}. You could probably just check for item.in_active_trail in the item variable, but if that's not good enough, just use Kint (from the devel module) to figure out a variable that works for your situation.

2
  • My theme is "businessgroup zymphonies theme" and in links.html.twig i found this <ul{{ attributes }}> {%- for key, item in links -%} <li{{ item.attributes.addClass(key|clean_class) }}> {%- if item.link -%} {{ item.link }} {%- elseif item.text_attributes -%} <span{{ item.text_attributes }}>{{ item.text }}</span> {%- else -%} {{ item.text }} {%- endif -%} </li> {%- endfor -%} </ul>
    – wakh.ru
    Commented Apr 27, 2017 at 20:23
  • This is probably only something that theme maintainer can solution, then.
    – Kevin
    Commented Apr 27, 2017 at 23:46

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.