1

On my Drupal 8 multilingual project, I have made a custom controller which create a basic page, but I can't figure out which parameter I must use in the routing. Is this _locale?

This is the definition of the route.

custom.route:
path: '{_locale}/portail'
defaults:
  _content: '\Drupal\my_module\Controller\DisplayController::display'
requirements:
_access: 'TRUE

This is the code I am using in the controller class.

public function display(Request $request, $locale) {
    var_dump($locale);die;
}

3 Answers 3

4

The language is detected and the prefix removed before routing. So you have a static route without parameter and in the controller you can get the prefix from the language manager:

  $langcode = $this->languageManager()->getCurrentLanguage()->getId();
2
  • 2
    Yes, this answers to both How do I define a route in a multi-lingual site? and How do I get the language set for a page returned from my controller?
    – apaderno
    Dec 26, 2017 at 10:01
  • Not sure this is what the OP is asking; but my guess would be he is asking how to do a multilingual route (with multilingual paths)? Which I suspect is sadly not possible in D8.
    – liquidcms
    Jan 25, 2021 at 23:02
1

To those like @liquidcms wondering how to do a multilingual path : you can make as many routes as languages, to the same controller.

custom.route.lang_one:
  path: '/path/in/this/language'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyController::method'
  requirements:
    _permission: 'access content'

custom.route.lang_two:
  path: '/path/in/that/other/language'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyController::method'
  requirements:
    _permission: 'access content'

And then you check the language in the controller as already mentioned by @4k4.

0

One controller with a single route, different paths in different languages:

my_module.routing.yml

custom.route:
  path: '/path-english'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyController::method'
  requirements:
    _permission: 'access content'

This works for english (default language), but say we want /path-deutsch in German. We need to manipulate the path using a PathProcessor.

Set up the service in my_module.services.yml:

services:
  my_module.path_processor:
    class: Drupal\my_module\Path\PathProcessor
    arguments: ['@language_manager']
    tags:
      - { name: path_processor_inbound, priority: 50 }
      - { name: path_processor_outbound, priority: 50 }

The class is inmy_module/src/Path/PathProcessor.php:

<?php

namespace Drupal\my_module\Path;

use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Symfony\Component\HttpFoundation\Request;

/**
 * Rewrites inbound and outbound paths.
 */
class PathProcessor implements InboundPathProcessorInterface, OutboundPathProcessorInterface {

  /**
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   */
  public function __construct(LanguageManagerInterface $language_manager) {
    $this->languageManager = $language_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function processInbound($path, Request $request) {
    if ($this->languageManager->getCurrentLanguage()->getId() === 'de' && $path === '/path-deutsch') {
      return '/path-english';
    }

    return $path;
  }

  /**
   * {@inheritdoc}
   */
  public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
    if ($path === '/path-english') {
      if ($options['language']->getId() === 'de') {
        return '/path-deutsch';
      }
    }

    return $path;
  }

}

processInbound rewrites the German path in the request to the route used by the controller.

processOutbound ensures that any generated links in a German context use the correct German path. (This doesn't work if you use two separate controller routes.)

// Will return '/path-deutsch'.  
$url = Url::fromRoute('custom.route', ['language' => 'de'])->toString();

This means that the language switcher block etc. will automatically use the correct path.

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.