1

I have this function in my functions.php of a localhost build:-

function custom_rewrite() {
    add_rewrite_rule('.*', 'http://example.com/', 'top');
}

add_action('init', 'custom_rewrite');

As far as I understand, this should redirect any page to example.com. But it's not working. The page loads as normal with no redirect. I've tried flushing after adding the rule, but no joy.

Obviously, I don't actually want to redirect all pages like this, but I'm trying to get a basic rewrite working before fine-tuning it to my needs. But I can't even get over this first hurdle!

I've followed countless tutorials online and can't get any of them to work. Is there a prerequisite for using add_rewrite_rule? And if not, anybody have any idea why this won't work? Is it because I'm in a localhost environment?

Any advice would be greatly appreciated!

EDIT

I followed Jack's advice and changed my rewrite rule to:-

add_rewrite_rule('.*', 'index.php?page_id=81', 'top');

But I'm still not having any luck. I also tried changing the .* catch all to an actual existing pagename like so:-

add_rewrite_rule('^testpage/?', 'index.php?page_id=81', 'top');

And still no redirect.

The page with ID 81 exists as does 'testpage'. Im stumped. Should rewrite rules work on a localhost build? Any further illumination anybody can offer?

3
  • 1
    Rewrite rules should point to index.php. Have you checked the official codex page for this function? It's pretty straight forward.
    – Johansson
    Oct 16, 2017 at 19:25
  • I didn't realise it was explicit. That would explain a lot! Thanks for the education Jack. So, is it impossible using the rewrite API to redirect to a page thats not part of the wordpress install? For example, if I had a "test.php" file in the wordpress root. Oct 17, 2017 at 11:31
  • The Rewriting API is for rewriting URLs, not redirecting. So the URL won't change. You're just telling WordPress that /testpage/ should load page_id 81, but the URL will stay /testpage/. But I tried add_rewrite_rule('^testpage/?', 'index.php?page_id=501', 'top'); (where 501 is an ID that exists on my install) and it worked fine, loading that page's content and template. Make sure you're flushing rewrite rules though. It won't work unless you do. Oct 17, 2017 at 12:30

1 Answer 1

3

Expanding on my comment:

The Rewriting API is for rewriting URLs, not redirecting. So the URL won't change. You're just telling WordPress that /testpage/ should load page_id 81, but the URL will stay /testpage/.

Regardless, I tried the below, (where 501 is an ID that exists on my install) and it worked fine, loading that page's content and template:

function wpse_283104_rewrite() {
    add_rewrite_rule('^testpage/?', 'index.php?page_id=501', 'top');
}
add_action( 'init', 'wpse_283104_rewrite' );

Make sure you're flushing rewrite rules though. It won't work unless you do.

If you just want to do redirects, then .htaccess or a plugin is probably the way to go.

If you really want to use a rewrite rule for a redirect, then what you need to do is rewrite the URL to set a custom query var, then check that query var in the template_redirect hook, and perform a redirect.

First up, we'll create a custom query var called wpse_283104_redirect. A query var is a query string that WordPress recognises. We need to tell WordPress to see?wpse_283104_redirect=1in a rewrite so that we can check it later. This is done by filtering thequery_vars` array:

function wpse_283104_query_vars( $vars ) {
    $vars[] = 'wpse_283104_redirect';

    return $vars;
}
add_filter( 'query_vars', 'wpse_283104_query_vars' );

Next is the rewrite rule:

function wpse_283104_rewrite() {
    add_rewrite_rule( '^testpage/?', 'index.php?wpse_283104_redirect=1', 'top' );
}
add_action( 'init', 'wpse_283104_rewrite' );

Now /testpage/ will load the homepage, but since we registered wpse_283104_redirect we can see if we're on /testpage/ (or whatever the rewritten URL is) with [get_query_var()][2].

So inside the template_redirect hook we'll perform this check and redirect:

function wpse_283104_redirect() {
    if ( get_query_var( 'wpse_283104_redirect' ) == '1' ) {
        wp_redirect( 'http://example.com' );
        exit;
    }
}
add_action( 'template_redirect', 'wpse_283104_redirect' );
4
  • If you’re just redirecting away, there’s no reason to wait until template_redirect. After query parsing but before the query is run will save you a trip to the database.
    – Milo
    Oct 17, 2017 at 13:09
  • Fair call, what hook would you suggest, init? Oct 17, 2017 at 13:35
  • Thanks Jacob. That all makes sense. I would rather use the htaccess file but I need to change these rewrites dynamically, so im not sure regular writing to the htaccess is a good idea. Hence my experiments with rewrite API. Your idea to use a query to trigger a redirect sounds feasible. Im going to give it a go... Oct 17, 2017 at 15:59
  • @JacobPeattie init is too early, I think parse_query is the earliest action you could hook.
    – Milo
    Oct 18, 2017 at 3:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.