Redirect frontpage to the correct language

Created on 12 December 2016, over 7 years ago
Updated 1 May 2024, 2 months ago

In the D7 version, the user is redirected from / to either /nl or /en (when Dutch and English are enabled). In the D8 version, the redirect doesn't happen.

πŸ“Œ Task
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡³πŸ‡±Netherlands BarisW Amsterdam

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡§πŸ‡ͺBelgium beerendlauwers

    I wrote my own kernel request event subscriber for this that piggy backs off of the configuration form of the module:

    namespace Drupal\my_module\EventSubscriber;
    
    use Drupal\Core\Entity\EntityTypeManagerInterface;
    use Drupal\Core\Path\PathMatcherInterface;
    use Drupal\Core\Routing\TrustedRedirectResponse;
    use Drupal\Core\Url;
    use Drupal\language\Entity\ConfigurableLanguage;
    use Drupal\language\LanguageNegotiatorInterface;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\HttpKernel\Event\RequestEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    
    /**
     * Redirects to the relevant front page if no language code has been set.
     */
    class IpCountryDetectionSubscriber implements EventSubscriberInterface {
    
      /**
       * Drupal\Core\Entity\EntityTypeManagerInterface definition.
       *
       * @var \Drupal\Core\Entity\EntityTypeManagerInterface
       */
      protected EntityTypeManagerInterface $entityTypeManager;
    
      /**
       * The language negotiator.
       *
       * @var \Drupal\language\LanguageNegotiatorInterface
       */
      protected $negotiator;
    
      /**
       * Drupal\Core\Path\PathMatcherInterface definition.
       *
       * @var \Drupal\Core\Path\PathMatcherInterface
       */
      protected PathMatcherInterface $pathMatcher;
    
      /**
       * Constructs a IpCountryDetectionSubscriber.
       *
       * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
       *   The entity type manager.
       * @param \Drupal\language\LanguageNegotiatorInterface $negotiator
       *   The language negotiator manager service.
       * @param \Drupal\Core\Path\PathMatcherInterface $path_matcher
       *   The path matcher service.
       */
      public function __construct(EntityTypeManagerInterface $entity_type_manager,
                                  LanguageNegotiatorInterface $negotiator,
                                  PathMatcherInterface $path_matcher) {
        $this->entityTypeManager = $entity_type_manager;
        $this->negotiator = $negotiator;
        $this->pathMatcher = $path_matcher;
      }
    
      /**
       * Redirects to the relevant front page if no language code has been set.
       *
       * The relevant front page is determined by ip2country and the
       * language negotiation subscriber from ip_language_negotiation.
       *
       * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
       *   The Event to process.
       */
      public function onKernelRequest(RequestEvent $event): void {
        $request = $event->getRequest();
        $path = $request->getPathInfo();
    
        // Only redirect if we have no language information in the URL.
        if ($path !== '/') {
          return;
        }
    
        try {
          $method_id = 'ip-language-negotiation-ip';
          $languageEntity = NULL;
          if ($this->negotiator->isNegotiationMethodEnabled($method_id)) {
            $ipLanguageNegotiation = $this->negotiator->getNegotiationMethodInstance($method_id);
            $langcode = $ipLanguageNegotiation->getLangcode($request);
    
            // Fallback is English (Europe) if IP detection fails.
            if ($langcode === NULL) {
              $langcode = 'en';
            }
    
            $languageEntity = $this->entityTypeManager->getStorage('configurable_language')
              ->load($langcode);
          }
    
          if ($languageEntity instanceof ConfigurableLanguage) {
            $request_query = $request->query->all();
    
            $route_name = $this->pathMatcher->isFrontPage() ? '<front>' : '<current>';
            $url = Url::fromRoute($route_name, [], ['language' => $languageEntity]);
            $url->setOption('query', (array) $url->getOption('query') + $request_query);
    
            $response = new TrustedRedirectResponse($url->setAbsolute()
              ->toString());
            $event->setResponse($response);
          }
        }
        catch (\Throwable $exception) {
        }
      }
    
      /**
       * {@inheritdoc}
       */
      public static function getSubscribedEvents() {
        $events = [];
        $events[KernelEvents::REQUEST][] = ['onKernelRequest', 400];
        return $events;
      }
    
    }
    
    

    Service definition:

    my_module.kernel_request_subscriber:
        class: Drupal\my_module\EventSubscriber\IpCountryDetectionSubscriber
        arguments: [ '@entity_type.manager', '@language_negotiator', '@path.matcher' ]
        tags:
          - { name: event_subscriber }
    
Production build 0.69.0 2024