I recently worked on a project in which we were undertaking quite a few improvements in SEO, one of which was to replace URL parameters with a more SEO friendly folder structure URL. So rather than http://www.domain.com/blog?cat="mycat"&sector="mysector", it should be http://www.domain.com/blog/mycat/mysector - much better right?

All the old URL's now needed a 301 redirect to the /blog page, we achived this using Drupal 8's and Symfony's event subscriber.

Basically during the execution of a Symfony application, event notifications are triggered. The application can then listen to these notifications and respond to them by executing any piece of code - and this is what I will document below.

Our folder/file structure was as follows, for the sake of this example we created a module called custom_redirect.

custom_redirect/
  -- custom_redirect.info.yml
  -- custom_redirect.services.yml
  /src
      /EventSubscriber
           -- CustomRedirects.php

 

#custom_redirect.info.yml

name: custom_redirect
description: Custom redirect using Event Subscriber
type: module
core: '8.x'

 

#custom_redirect.services.yml

services:
  custom_redirect.event_subscriber:
    class: Drupal\custom_redirect\EventSubscriber\CustomRedirects
    tags:
      - {name: event_subscriber}

 

<?php

// CustomRedirects.php

namespace Drupal\custom_redirect\EventSubscriber;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CustomRedirects implements EventSubscriberInterface {

  public function checkForRedirection(GetResponseEvent $event) {

    $path = $event->getRequest()->getRequestUri();
    // if the path starts with 'blog'
    if (strpos($path, '/blog') === 0) {
      // check for the get parameters 'cat' or 'sector'
      if ($event->getRequest()->query->get('cat') OR $event->getRequest()->query->get('sector')) {
        // redirect to our view, 'view.blog.page_1' is our route name
        $event->setResponse(new RedirectResponse(\Drupal::url('view.blog.page_1'), 301, []));
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    // 'checkForRedirection' is the name of our function
    $events[KernelEvents::REQUEST][] = array('checkForRedirection');
    return $events;
  }

}

 

For more on event subscribers see - https://symfony.com/doc/current/event_dispatcher.html & https://www.drupal.org/docs/8/creating-custom-modules/subscribe-to-and-dispatch-events