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 to a random post from my blog. Note the random link in my nav bar above. Here’s how you might do that:

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);

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


It might make sense to put the WP query inside of your if statement to check the page name before doing a database query. That way we’re not querying the database for a random post on every single page hit that isn’t to /random.

Very true, oversight on my part. Fixed.


Email (optional)

Blog (optional)