Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to create some custom pages for my theme that don't appear in the Page listing in wp-admin.

I have the following class which intercepts the url.

class jtvRewrite {

var $path = '';

function __construct($path) {

    $this->path = $path;

    register_activation_hook( __file__, array($this, 'activate') );

    // Write rules -> Add query vars -> Recalculate rewrite rules
    add_filter('rewrite_rules_array', array($this, 'create_rewrite_rules'));
    add_filter('query_vars',array($this, 'add_query_vars'));

    add_filter('admin_init', array($this, 'flush_rewrite_rules'));
    add_action('template_redirect', array($this, 'template_redirect_intercept') );
}

function activate() {
    global $wp_rewrite;
    $this->flush_rewrite_rules();
}

function create_rewrite_rules($rules) {
    global $wp_rewrite;
    $newRule = array($this->path . '/(.+)' => 'index.php?' . $this->path . '='.$wp_rewrite->preg_index(1));
    $newRules = $newRule + $rules;
    return $newRules;
}

function add_query_vars($qvars) {
    $qvars[] = $this->path;
    return $qvars;
}

function flush_rewrite_rules() {
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

function template_redirect_intercept() {
    global $wp_query;
    if ($wp_query->get($this->path)) {
        $this->output($wp_query->get($this->path));
        exit;
    }
}

function output( $output ) {
    global $wp_query;

    if (file_exists( TEMPLATEPATH . '/' . $this->path . '/' . $output . '.php' )) {
        include( TEMPLATEPATH . '/' . $this->path . '/' . $output . '.php' );
        exit;
    } else {
        return $wp_query->is_404();
    }
}

}
$member = new jtvRewrite('member');

However, if I run is_home() on this page it returns true. That makes sense since behind the rewrite is /index.php?member=profile.

Is there something I can throw in there that makes it not home? The reason being I have another functions which adds something to the front page on is_home().

Secondly, I've got return $wp_query->is_404(); in there if the theme file is not available (i.e. the page doesn't exist) but on a non existent url just a blank page is returned (WP_DEBUG true return nothing).

Any idea how to send the 404 correctly?

Edit with solution:

Otto suggested adding $wp_query->is_home = false to template_redirect_intercept() - which worked a treat. And then I've made the output function check if a function exists based upon the path that was originally requested. If that function exists (see below) it calls it. That function provides the redirect. If it doesn't the 404 is set.

This way I can use the class jtvRewrite as much as I like for each new template file I add.

function template_redirect_intercept() {
    global $wp_query;
    if ($wp_query->get($this->path)) {
        $wp_query->is_home = false; // set is_home parameter to false

        if (! $this->output($wp_query->get($this->path)))
            $wp_query->set_404();
    }
}

function output( $output ) {
    global $wp_query;

    $function = 'jtv_rewrite_action_' . $this->path . '_' . $output;

    if (function_exists($function)) {
        $function();
        exit;
    } else {
        return false;
    }
}

Then I can use the following function to fire off to the correct template file:

$member = new jtvRewrite('member');

/**
 * Provide the theme template file
 */
function jtv_rewrite_action_member_profile() {

include( TEMPLATEPATH . '/member/profile.php' );

}
share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

Conditional variables are based on the main page query ($wp_query). If you want is_home() to be false, then you need to manually set it to false ($wp_query->is_home = false) or override the main query such that it's not true anymore. Probably you'd do that in your template_redirect_intercept function there, or in the individual page templates you're making using query_posts().

For your second problem, you have two main issues.

  1. template_redirect_intercept is exiting indiscriminately. It doesn't care what the return value of the output function call is.

  2. Returning the results of "is_404" is probably useless since the main query thinks it's returning the home page, not a 404. What you want to do here is to call $wp_query->set_404() if the page is supposed to not exist, then return something that will cause template_redirect_intercept to not exit. You want that function to return in that case, thus allowing the normal 404 handler to take over.

share|improve this answer
    
Thanks @Otto. I've made some changes and added them to my original question. –  deadlyhifi Nov 22 '11 at 13:52
    
If anyone has any more suggestions to make it more efficient then chime in. I like efficiency ;) –  deadlyhifi Nov 22 '11 at 13:53
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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