0

I recently moved content from Typo3 to WP with around 30.000 articles. Each article is having 3 or more urls which I store in custom text field.. each old url in new line.

I can programatically pair each stored old typo3 link to wordpress link but the question is how to manage 301 redirects without pasting some output to .htaccess.

My idea is something like:

  1. Call http://www.domain.tld/old-link/
  2. (normally this hits 404) wp compares requested old link with all meta fields "_old_urls" and if found
  3. 301 redirect and wp serves new url

Any idea how to do that?

2 Answers 2

0

Here is a trick, redirections in WP are complex. You can get 3 situations when they can happen.

  1. There is matched to your url rule, but no posts returned on wp_query from generated query_string.
  2. There is no rule that match your 404.
  3. Other Situations ( you wouldn't run into this on your own, so don't worry. )

Based on thi, 404 redirection can be triggered on 3 wp points.

  1. request
  2. wp_headers
  3. template_redirect

So you can use this as template for your redirection logic

add_filter( 'request', function( Wp_Query $wp_query ){
    if ( isset( $wp_query['error'] ) && 404 === intval( $wp_query['error'] ) ){
        // redirection logickgoes here...
    }
    return $wp_query;
});

add_filter( 'wp_headers', function( $headers, $wp ){
    if ( isset( $wp->query_vars['error'] ) && 404 === intval( $wp->query_vars['error'] ) ) {
        // redirection logic goes here...
    }
    return $headers;
}, 10, 2);

add_action( 'template_redirect', function( $params ){
    if ( is_404() ) {
        // redirection logic goes here.
    }  
});

These are a bit hacky ways to do redirection on 404 error, but this is what I come up when run into sites migration myself.

1
  • Idk why the conditions inside request and wp_headers always retuned false I was unable to determine the request. I ended up with some similiar solution. But thanks anyway!
    – 5ulo
    Apr 23, 2018 at 23:42
0

I ended up hooking 404_template. It's a bit slow comparing 30k articles but the 301 redirect works.

add_filter( '404_template', function( $tpl ) {

    $request = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING );

    if ( ! $request ) {
        return $tpl;
    }

    $args = array(
        'posts_per_page'   => 1,
        'orderby'          => 'ID',
        'order'            => 'DESC',
        'post_status'      => 'publish',
        'meta_query' => array(
            array(
                'key'     => 'old_urls',
                'value'   => $request,
                'compare' => 'LIKE',
            ),
        ),
    );

    $posts = get_posts( $args );
    $redir = get_permalink($posts[0]->ID);

    if ( $redir ) {
        wp_redirect( $redir, 301 );
        exit;
    }

    return $tpl;

}, -4000 );

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.