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've built a complete MVC framework that integrates perfectly well into Wordpress. This framework also provides a simple to intermediate implementation of a ReST interface (the real one with hypermedia formats and links between answers and pages, not just the GET/POST/PUT/DELETE part)

I created a custom post type that when created automatically binds to my framework and all urls to access the REST interface work fine until i have to get out of the traditionnal page based url.

For example:

GET http://mysite.com/json/order/2/

That one works fine because the %page% variable gets the 2 into it because it fits the normal permalink structure wordpress uses. Where it starts to get complex is when i want the following url to respond:

GET http://mysite.com/json/ticket/32jrfks923841j3k/

This time around, the 32jrfks923841j3k is not a number thus the permalink with the %page% variable is not triggering. My goal isn't all that complicated, i just don't know how to make it work but i want that my pages (The json custom post type only preferably) allow the second url to work. I don't care where this data is going as i have my own custom facility to read URLs in my framework and i will extract it by myself...

It's very important that i do not get redirected, thus mod_rewrite or the rewrite api can probably not be used, this is because ReST by default uses the METHOD to detect what to do, if someone POST to an url, it has to stay like that and respond, not get redirected or else the POST gets lost...

Thanks

share|improve this question
    
-Note i also have identifiers with special characters such as "047-203-2013-01-28-0" in them –  Mathieu Dumoulin Jan 28 '13 at 20:59
add comment

1 Answer 1

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...

share|improve this answer
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.