1

We are replacing a website with a new version. The domain is the same, but URL aliases in the new website are different.

In many cases, I can use an old alias to calculate its corresponding new alias. There are many thousands of old aliases, so I don't want to just use the Redirect module. I know how to write the calculations and how to check if a calculated new alias exists.

I need to know at what point I can intercept each incoming URL to calculate a new alias.

I also need to know how to redirect to the calculated new alias if it exists.

Concrete example:

A book chapter on the old site is at example.com/recent/secrets-to-success/10-knowing-when-to-quit. This chapter on the new site is at example.com/secrets-to-success/knowing-when-quit. The difference is (a) we no longer add the recent subfolder, (b) we've removed chapter numbers from chapter titles, and (c) we've changed which words are ignored when an alias is auto-generated.

When someone uses an old alias, I want to intercept it, calculate the new alias, check if it exists, and redirect to it if it does. This is only one example. There are several other ways of calculating, so there's some trial and error involved. But I know how to take care of that.

6
  • 2
    Sounds like a job for the redirect module.
    – No Sssweat
    Commented Jan 24, 2020 at 7:22
  • 2
    By this description you don't need access to Drupals DB at all, this is just a one fixed part changing to another fxed part, I'd recommend batmans answer using .htaccess.
    – Hudri
    Commented Jan 24, 2020 at 8:12
  • 1
    I agree with @Hudri: Changing old with new in a URL doesn't require any access to the database used from Drupal, except in the case old and new used in the question are placeholders, and the values you really use/need are taken from the database. If the latter is the case, you should edit the question to explain that, since the simplification simplified too much.
    – avpaderno
    Commented Jan 24, 2020 at 8:53
  • 2
    It would be better to provide an example that better matches your actual requirements. The specifics of those may well determine what the best approach to take is
    – Clive
    Commented Jan 24, 2020 at 12:04
  • Thanks to @kiamlaluno for taking the time to help me see that I needed to fix my question. I have done so. Commented Jan 24, 2020 at 15:59

3 Answers 3

4

This solution is based on a suggestion by @4k4 at Redirect from within controller always goes to home page.

My custom module is named rsc.

In modules/custom/rsc the file rsc.services.yml includes the following:

services:
  rsc.event.Redirect404:
    class: Drupal\rsc\EventSubscriber\rscRedirect404
    tags:
      - {name: event_subscriber}

In modules/custom/rsc/src/EventSubscriber the file rscRedirect404.php contains the following:

<?php
namespace Drupal\rsc\EventSubscriber;

use Drupal\Core\EventSubscriber\HttpExceptionSubscriberBase;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;

class rscRedirect404 extends HttpExceptionSubscriberBase {

  protected function getHandledFormats() { // required
    return ['html'];
  }

  public function on404(GetResponseForExceptionEvent $event) {

    $path = \Drupal::request()->getPathInfo();
    $path = [code to modify the path from old site to new site]

    if (($url = \Drupal::service('path.validator')->getUrlIfValid($path))) {
      $event->setResponse(new RedirectResponse(URL::fromUserInput($path)->toString()));
    }
  }
}

With this in place, I see 404 redirects before they get passed to the default handler. If I do the $event->setResponse(), the user is redirected as I specify. If not, normal processing occurs.

In reality, the line that says [code to modify the path from old site to new site] is multiple lines where I do several trial-and-error tests to figure out the correct new URL, but everything else is just as I'm using it.

3

This has nothing to do with drupal. Need to edit the .htaccess file

RewriteEngine On
RewriteRule ^test/(.*)$ /new/$1 [R=301,L]

This will redirect example.com/test/1 to example.com/new/1

1
  • Thanks for this comment. It highlights a weakness in my description which I have now corrected. A solution that works for me requires me to have access to the Drupal database when I calculate the redirection, but I hadn't said this. I gave you +1 for helping me fix my description. Commented Jan 24, 2020 at 3:59
2

For example, what was example.com/old-style-alias might now be example.com/a-very-different-alias.

Redirect module is exactly what you need.

This can automatically add a redirect when you change the node's alias or you can manually add them to the redirect list, which gets saved to the DB.

1
  • thanks for your kind suggestion. I already use the Redirect module, but since all content has already been moved to the new site with modified aliases, I don't think I can use the automatic feature. There are many thousands of nodes with changed aliases, so adding them manually would take a long time. This is why I'm trying to find a solution for redirecting using code I can control. Or am I missing a feature of Redirect? I've added a "concrete example" to my original post that may help explain. Commented Jan 25, 2020 at 17:13

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.