How to intercept a WordPress page request

WordPress logoHave you ever wanted to write a plugin that sits between a request for a WordPress page (or post) and the fulfillment of that request? In order to do so, use the pre_get_posts action hook which passes a WP Query object as a parameter to your plugin function. This action is called early in the request flow, before any headers or content has been sent to the browser. So you can probe or modify the query object in order to create your own custom behavior.

As an example, I wanted to redirect all requests that come in for http://justinsomnia.org/random/ to a random post from my blog. Note the random link in my nav bar above. Here’s how you might do that:

<?php
/*
Plugin Name: Random Link
*/

add_action('pre_get_posts', 'random_link');

function random_link($query)
{
  if ($query->get('pagename') == 'random') {
    global $wpdb;

    $sql = "select $wpdb->posts.ID
            from $wpdb->posts
            where post_password = ''
            and post_type = 'post'
            and post_status = 'publish'
            order by rand()
            limit 1";

    $post_id = $wpdb->get_var($sql);
    $permalink = get_permalink($post_id);

    header("Location: " . $permalink, true, 302);
    exit;
  }
}

The result is a pretty serendipitous (and addictive) way to surf my archives.