Broken wordpress pages; a short primer on plugins

Posted by Doug on March 01, 2009
Technology

If you use the rewrite hooks to create new permalinks on your blog and found that it broke your paging on those pages (a misnomer, because the paging may have never worked), I have the solution! But first, the problem.

I used the Custom Field Taxonomies plugin (see previous post) to create a new set of permalinks on my NYC Facades blog. Their syntax is “index.php?custfield=value”; if you enter such a URL with the name of a custom field on the left, it will do a search and display only those posts with given value. However, if you want to make permalinks like “/custfield/value/”, then you could, as I did, insert code like this:

//----------------------------------------------------------
// rewrite and permalink
//----------------------------------------------------------

// based on http://codex.wordpress.org/Custom_Queries
add_filter( ‘query_vars’, ’street_queryvars’ );

// these are the only tags I will allow, but it could be pulled dynamically from the DB
function street_queryvars( $qvars )
{
$qvars[] = ‘avenue’;
$qvars[] = ’street’;
$qvars[] = ’style’;
$qvars[] = ‘use’;
return $qvars;
}

add_action(’init’, ‘geotags_flush_rewrite_rules’);

function geotags_flush_rewrite_rules()
{
global $wp_rewrite;
$wp_rewrite->flush_rules();
}

add_action(’generate_rewrite_rules’, ‘geotags_add_rewrite_rules’);

// if we see any of our tags, put them as arguments so WP recognizes it as OK
function geotags_add_rewrite_rules( $wp_rewrite )
{
$new_rules = array(
‘(avenue|street|style|use)/([^/]+)/?$’ => ‘index.php?’ . $wp_rewrite->pre\
g_index(1) . ‘=’ . $wp_rewrite->preg_index(2) );

$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}

At the end of the code, $new_rules is creating the permalinks I like. However, it has the effect of throwing away the pagination, to fix this, you have to add a second rule; change that $new_rules line like so:


$new_rules = array(
'(avenue|street|style|use)/([^/]+)/?$' => 'index.php?' . $wp_rewrite->pre\
g_index(1) . '=' . $wp_rewrite->preg_index(2),
'(avenue|street|style|use)/([^/]+)/page/(\d+)/?$'
=> 'index.php/?paged=' . $wp_rewrite->preg_index(3) . '&' . $wp_rewrit\
e->preg_index(1) . '=' . $wp_rewrite->preg_index(2) );

Note that the paged variable is now getting set, and wordpress is happy!

Let me go off on a tangent here. After fiddling with all this, I understand better how the entire wordpress system works. Now, this may be documented somewhere, for example on the Plugin API doc page, but I haven’t read it carefully enough to know that. The key insight for me — and this is obvious when you give it a few seconds’ thought — is that code execution, e.g. plugins goes in a particular sequence, namely,

  1. Code that’s in “main” and gets run when php starts.
  2. Wordpress – any hooks
  3. Template and post code

Stupidly obvious, right? Well, if you start putting code about $wp_query in #1, you’re going to get garbage; wordpress has not yet begun to process! Anything that you want to rely on wordpress for during a processing stage has to happen in #2. The list of hooks are linked from the Plugin API page, and a useful reference (I went poking around for some others that exist in the INCLUDE/query.php file, but aren’t available for general consumption). The upshot of all this is: write your plugin so it does the heavy lifting with hooks, assuming it is meant to change the way posts are received. Of course, if it is meant for the stage 3 processing, write it however you like; there’s no timing problem there.

No comments yet.

Leave a comment

WP_Big_City