Redirect deleted pages

Don’t know enough about htaccess, but you could use routes. In your route, you can check if the page exists, if so, go to the page, and if not, redirect wherever.

1 Like

Oh, that’s excellent. I’ll give it a try.

You could even pass a message from the route to the template if the user requested an invalid page, something along the lines: “The event you requested does no longer exist. Maybe you are interested in one of our upcoming events…”

OK, this is what I have so far, but it doesn’t appear to be doing anything. Maybe you’ll see something obvious:

c::set('routes', array(
  array(
      'pattern' => 'events/(:num)/(:any)',
      'action' => function($numPlaceholder, $anyPlaceholder) {
          $page = site()->index()->find($anyPlaceholder);
          if ($page != '') {
              return site()->visit($page);
          } else {
              return site()->visit('/events');
          }
      }
  )
));

What is a correct path to an event page? Is the num part of the URI?

 $page = page('events/ . $numPlaceholder . DS . $anyPlaceholder);
          if (!$page) {
              return site()->visit('events');
          } else {
              return $page;
          }

They are currently in year-based subfolders, so it would be something like /events/2017/cloudnativeconkubecon-north-america.

Oh, whoops. Looks like that DOES work. Turns out I had my routes declaration with my previous route repeated in my localhost config, which means it cleared the new one from the main config out.

@texnixe related: instead of “visit” could I do “redirect” or something? Right now it keeps the old URL, which I guess is OK, but ideally we want Google to realize it’s redirected, and we don’t want the end user to get confused as to why that URL is showing the full events list.

Edit: Oh, duh, use go() instead of site()->visit().

Have you considered Redirecty - Redirects plugin for Kirby 2.1.0+ ?

Seems like it would require manually entering a redirect for each event, which is too much work.

You could simple use go() with an HTTP code or return a Response object

2 Likes

On a recent project, where the client previously had a Shopify website, we did a manual list of old URLs and used Kirby router to handle the redirections:

<?php // site/plugins/redirect/redirections.php

return [
    '2015/event-name' => 'events',
    '2016/event-name-2' => 'events',
    // ...
];
<?php // site/plugins/redirect/redirect.php

kirby()->set('route', [
    'pattern' => 'events/(:any)',
    'method'  => 'GET',
    'action'  => function($event) {
        $redirections = include(__DIR__ . DS . 'redirections.php');

        if (array_key_exists($event, $redirections)) {
            return redirect::to($redirections[$event], 301);
        }

        return site()->visit("events/$event");
    }
]);

I tried to slightly adapt it to your use case, but since you are always redirecting to the same page, you can simplify it more.

To keep the redirection list updated, I would use a page delete hook, check if the page is an event, then to write it’s URI to the redirections.php file automatically.

This is fine if you want to redirect individual URLs to different targets, but for the above use case keeping a redirect list is not necessary at all. Just out of curiosity, how would the hook know where to redirect to unless you specify this manually somewhere (where, in the page you are about to delete?).

@pedroborges, thanks for the input, and this may be something worth coming back to for future things. For this one, though, the route method suggested by Sonja is perfect.

Also, I don’t generally use the panel, especially for things like deleting old events, so relying on a panel hook for something like this wouldn’t really work.

Got it.

In my use it was a list of ~40 pages so the client did it manually for the URLs the didn’t have a match on the new website. What I suggested using the page delete hook would only work on Matthew’s use case, since all deleted pages would redirect to the same page.

In cases where I have a fixed list of pages that should redirect somewhere else, I usually do this in the .htaccess or ideally in the server configuration. This is preferable to routes, because PHP doesn’t have to kick in first.

In the current case, there is probably no pattern nor a fixed list that you could use, so I think a route is the only way to achieve this.

Using the page delete hook instead of htaccess could make sense in some situations, just because it would be automatic instead of requiring the user to go manually enter something in htaccess after deleting it. However, I’m not entirely sure where that would be advantageous as opposed to just using the generic route method above.

The only use case for this that I can think of would be if you redirect those deleted pages to individual targets that you would save in the page before you delete it, so that the delete hook could fetch that information and add it to the redirect list. You wouldn’t be able to do this with a generic route. But I don’t know if that would be a a feasible workflow.

I actually just had a good use case for this.

You post an article and then realize there’s an embarrassing typo in the URL slug. You don’t want a generic redirect because you want it to link to the correct version of the page, and you don’t want someone to have to dig into .htaccess to fix it.

So, you create a new one, update a redirect field or something in the old one, and then when you delete the old one, have it add it to the redirect list with the contents of the redirect field.

This actually would be cool if it was built into Kirby where you could change the slug of a page and have it automagically redirect the old version.

1 Like

You could actually use a panel.page.move hook to achieve this, it get’s the old and new page object. So this would allow you to create such an auto-magic redirect.

2 Likes