Experiments in WordPress routing 02

Adding some routing to the mix.

No more routing

I’ve previously hooked into the do_parse_request hook to serve views in place of using WordPress routing system and I’m left to my own devices when it comes to routing.
The current version of the code (see on GitHub) does nothing in this sense but trying to match a /my-route path and then returning some logging information.
WordPress routing system will always end up creating a WP_Query object initialized according to the current request and there are no easy ways to tap into that system without having to use it all; it makes sense as that’s the way WordPress is meant to work.
Inside the do_parse_request hook I’m not in a bad position at all though: WordPress has completely loaded, it’s ready to run and its array of functions and classes is ready for me to use.

Klein

I’ve tried solving the routing issue developing something but have seen no point in re-inventing the wheel.
The klein.php router library is small and neat, tested and performing albeit requiring PHP 5.3.
While the current version of it was too big a chunk to swallow, its version .1.20 proved way smaller and easier to port to PHP 5.2.
Out of this small back-compatibility effort is born the klein52 library. Any magic and punch it packs was made possible by the original author (Chris O’Hara) and the contributors of the original project.
This tool available it’s time for some more experimenting; I’ve modified the plugin code as follows:


/**
     * Plugin Name: theAverageDev Routes
     * Plugin URI: http://theAverageDev.com
     * Description: Routing for WordPress
     * Version: 1.0
     * Author: theAverageDev
     * Author URI: http://theAverageDev.com
     * License: GPL 2.0
     */

    require 'vendor/autoload_52.php';

    /**
     * Routes
     */
    function route_hello_world() {
        echo 'Hello World!';
    }

    /**
     * Parse request
     */
    add_filter( 'do_parse_request', 'tad_routes_do_parse_request', 1, 3 );
    function tad_routes_do_parse_request( $continue, WP $wp, $extra_query_vars ) {
        respond( '/', 'route_hello_world' );
        dispatch();
        die();
    }


Leaving alone the usual Composer based setup I’m using the modified version of the klein52 router library to return the customary “Hello World!” message.
Nothing surprising here and the result is the expected one. Hello World message

Dynamic routes

Using a router makes sense only if the library is put to good use so I will try to define a route that will return the json version of a post accepting a dynamic ID number:


  /**
     * Plugin Name: theAverageDev Routes
     * Plugin URI: http://theAverageDev.com
     * Description: Routing for WordPress
     * Version: 1.0
     * Author: theAverageDev
     * Author URI: http://theAverageDev.com
     * License: GPL 2.0
     */

    require 'vendor/autoload_52.php';

    /**
     * Support methods
     */
    function _json_post( $request, $response ) {
        $post_id = $request->param( 'id' );
        $post    = get_post( $post_id );
        if ( empty( $post ) ) {
            echo json_encode( [ 'Error' => 'Not a valid post ID' ] );
        } else {
            echo( json_encode( $post ) );
        }
    }

    /**
     * Routes
     */
    function route_posts() {
        respond( 'GET', '/[i:id]/json', '_json_post' );
    }

    /**
     * Parse request
     */
    add_filter( 'do_parse_request', 'tad_routes_do_parse_request', 1, 3 );
    function tad_routes_do_parse_request( $continue, WP $wp, $extra_query_vars ) {
        with( '/posts', 'route_posts' );
        dispatch();
        die();
    }

Now this gets interesting: honoring PHP 5.2 syntax I’m setting up a GET route on /posts/[id]/json that should return the json version of a post or an error version should a post with that ID not be found.
Entering the /posts/1/json path will return what I expect Post json version while querying for a non-existent post ID will return the error message Post json error

Possibilities

This trivial application of the concept shows me that I can use WordPress back-end possibilities as I would normally do while completely de-coupling it from the front-end.
This opens up an approach to WordPress as a back-end only tool, and a very good one at that, while not abandoning it.
The current version of the plugin is on GitHub and comes ready to be used.