How to filter Drupal 8 menu by current language
Multilingual world
Categories
Drupal
Keywords
language

Menus are very specials in Drupal 8. 
They have become a blend of ConfigEntities holding MenuLinkContent - which are not (yet) ConfigEntities themselves. 
This is unfortunately source of many frustrations from developers when comes the time to actually work with menus. 

TL;DR

If you're in a hurry and do not want to read the full post, here is my solution to filter menu by language.

1) Install the module

composer require drupal/menu_manipulator

drush en menu_manipulator

2) Enable filtering in the configuration page

Go to Admin > Configuration > User Interface > Menu manipulator settings

That's it! 

Further details are explained below for developers - to use your own template_preprocess_menu() for instance. 

See module on Drupal.org

Scenario

Let's take this simple use case:

I have a menu with three links.
Each link has one language only (first link is in French, second link in Spanish and last one in English).

Expected results:
Only one link will be displayed on front end, depending on the current user's language. 

Actual results (in Drupal 8.4.x): 
All links are rendered, no matter the current language.
English speaking users actually see French and Spanish link content...

This issue has been discussed since April 7th, 2017:
https://www.drupal.org/project/drupal/issues/2466553#comment-12455018

So, how do we filter a Drupal Menu by the current user's language?

I have resolved this issue by creating a custom MenuLinkTreeManipulator service. I think this is the most sustainable way of solving this lack in core. Moreover, having a new MenuLinkTreeManipulator service that can be extended later is flexible. If others issues are raised later, we will be able to simply extend this method with new function.

Create a custom Menu manipulator

Here's how to create your own custom service to manipulate Menus in Drupal 8. 

  1. Create a custom module
  2. Create a custom plugin MenuLinkTreeManipulator
  3. Expose this as a service
  4. Load and filter menus

Detailed step by step

1) Create a custom module

[CODE]

2) ...

[CODE]

3) ...

[CODE]

 

Place menus wherever you want in your Drupal site without having to worry about the menu language. Menu Link items are now automatically filtered out based on the current user's language. 

 


Any questions/issues?

Please feel free to open a new ticket on the module page: https://www.drupal.org/project/menu_manipulator.