0

Logic

  • I have a page template at /blog that contains a "public" blog.
  • I have a page template at /members that is members area.

If a user enters the URL /members/blog I want to catch this in the template_redirect hook and load up a custom template that shows a "private" blog

Problem

Before template_redirect is called /members/blog is re-written to /blog so I can't load the private blog page.

There is nothing in the rewrite rules that says to do this.

6
  • is /members/blog a page?
    – Milo
    Commented Aug 22, 2015 at 15:58
  • No. I wrote this code a while ago so it's not best practice. But I normally catch it in template_direct and do a php include and turn 404 error off
    – ptimson
    Commented Aug 22, 2015 at 16:01
  • What's happening is that whenever WordPress encounters a 404, it tries to query for something close. You can see it in this function redirect_guess_404_permalink. It finds your blog page and redirects there. The simplest solution is to just add a page so it doesn't 404.
    – Milo
    Commented Aug 22, 2015 at 16:08
  • Cheers @Milo that's what I needed to know :) I guess the hacky solution would be to hook into that and stop it guessing if URL begins with /members/blog
    – ptimson
    Commented Aug 22, 2015 at 16:11
  • If you wanted to do that, I think conditionally disabling redirect_canonical is what you'd need to do. If you search around for that you might find something. The action is added in wp-includes/default-filters.php.
    – Milo
    Commented Aug 22, 2015 at 16:16

1 Answer 1

1

So the problem was redirect_guess_404_permalink was detecting a 404 error and 'guessed' /members/blog to be /blog

My hacky solution was to hook into the status error check (Stop Wordpress from "guessing" redirects for nonexistent URLs) and if URL parts match then unset the guessed solution

function blog_no_redirect_guess_404_permalink( $header ){
    global $wp_query;

    if( is_404() ) {
        // Get Request URL Parts
        $url = parse_url($_SERVER['REQUEST_URI']);
        $path = explode('/', $url['path']);
        $path = array_filter($path);
        $path = array_merge($path, array());
        // If matches /members/blog then unset 'guess'
        if (strtolower($path[0]) == 'members' && strtolower($path[1]) == 'blog') {
            unset( $wp_query->query_vars['name'] );
        }
    }

    return $header;
}
add_filter( 'status_header', 'blog_no_redirect_guess_404_permalink' );
1
  • I had the same issue, but found what I needed to do was simply give a lower priority to my template_redirect action. Commented Jan 9, 2016 at 21:46

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.