Custom permalink to make a page respond properly

I found the answer by tracing through the wordpress code, wasn’t easy, this code is really a complete mess but hell, i made it through…

The solution comes in 3 different parts:

  1. Register your custom post type / Custom permalink structure
  2. Generate your custom rules / Overwrite existing rules
  3. Overide the redirect canonical filter to prevent redirection when you have a custom permalink structure with optional parts

Portion #1, custom post type/permalink registration

Use register_post_type() to register a custom post type or use add_permalink() to add a simple permalink, in my case i used a custom post type to store my webservice endpoints as pages and i use special rewrite rules to redirect the traffic there:

add_action('init', 'register_cpt_jsonwebservice');
function register_cpt_jsonwebservice() {
    register_post_type( 'json', $args ); //See the definition of $args in the codex
}

Portion #2, Generate the special rewrite rules to redirect complex traffic to my pages handled by my custom post type

Using add_rewrite_tag, we can create the jsonid rewrite tag that will be read by the request parser, then reconfigure the permastruct to support an additional %jsonid% which is totally unorthodox, there are probably better ways to do that. The magic ends with a special rule that i add to the rewriter, this rule allows me to call pages with the url “/data///” and will redirect the traffic to the json custom type automaticaly.

add_action('generate_rewrite_rules', 'register_crr_jsonwebservice');
function register_crr_jsonwebservice($wp_rewrite) {

    //Add the jsonid tag
    add_rewrite_tag('%jsonid%', '([0-9a-zA-Z\-]+)', 'jsonid=');

    //Reconfigure the json permastruct to add the json id, cannot be done normaly i think, i need to investigate register_post_type function
    $wp_rewrite->extra_permastructs['json']['struct'] = '/json/%json%/%jsonid%/';

    //Add the special data rules at the top
    add_rewrite_rule('data/([^/]+)(/([a-zA-Z0-9\-]*))?$', 'index.php?post_type=json&name=$matches[1]&jsonid=$matches[3]', 'top');

}

Portion #3, prevent nasty canonical redirections

WordPress will always try to redirect the user to the page url that maps to the request. Thus, if /data/trips/ doesn’t correspond to /json/trips/ is configured for the custom post type, it will force a redirect to the right place, obviously crashing our party because ReST requires us not to redirect when POSTing, PUTing or DELETEing.

To this end, if you filter out on “redirect_canonical” you can intercept requests to redirect on your custom post type and thus prevent those nasty redirects crashing your ReST interface:

add_filter('redirect_canonical', array($this, 'register_crr_jsonwebservice_redirect_canonical'));
function register_crr_jsonwebservice_redirect_canonical($redirect_url)
{
    if(strpos($redirect_url, '%jsonid%') !== false)
    {
        return '';
    }
    return $redirect_url;
}

Thats all folks…