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 -%}
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.

  • Thanks! but I think it's not good solution for SEO? – wakh.ru Apr 28 '17 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. – 4k4 Apr 28 '17 at 14:45
  • you are right and your solution working so thank you again! – wakh.ru Apr 28 '17 at 14:50
  • What do you think about my update? – wakh.ru Apr 28 '17 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. – 4k4 Apr 29 '17 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.

  • 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 Apr 27 '17 at 20:23
  • This is probably only something that theme maintainer can solution, then. – Kevin Apr 27 '17 at 23:46

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.