Custom Page Routing in WordPress

WordPress is an excellent platform, however if you want to customize the site to do more than categories and tags it can be a little confusing. We know from SEO best practices that it is important to have proper URL structure. An easy way is to also use the URL to identify class and method. For example:

This URL structure works well for search engines and also allow a simple way to route the request if the class is Members, the method is profile and chuck as a property.

There are a few of ways to do this:

  1. modify .htaccess
  2. create a bunch of sub directories
  3. modify index.php to route
  4. create a plugin to do this

Yup, the best way is #4. We can do this WHILE following wordpress conventions AND not creating a problem for upgrading wordpress core. The difficult part with doing this is to find the right spot to intercept the wordpress routing. After a bit of trial and error, I found the best spot to be the ‘template_redirect’ action.

Create a plugin file in wp-content/plugins/ and in that file add the following line.

add_action( 'send_headers', 'site_router');

This tells wordpress that we will insert a function called site_router before the template redirection.

We need to do a few of things at this point. First we need to prevent wordpress from responding a 404. Then you can reroute to a method of the specified class.

Use this as an example to get you going.
function site_router() {
global $route,$wp_query,$window_title;
$bits =explode("/",$_SERVER['REQUEST_URI']);
$route->class = $bits[1];
$route->method = $bits[2];
$route->prop1 = $bits[3];
$route->prop2 = $bits[4];
$route->prop3 = $bits[5];
$route->prop4 = $bits[6];
if ( $wp_query->is_404 ) {
$wp_query->is_404 = false;
include(get_template_directory() . path_to_classes . $route->class . ".php" ); // replace path_to_classes with the actual directory where you keep your class files
/* at the end of your classfile include, you can create the object as $myObject = new Class */
$myObject->$route->method($route->prop1); // after calling the method, you can set a property in the object for the template
$template = locate_template($myObject->template);
$window_title = $myObject->window_title;
if ($template) {

  • Dena

    but the variable $wp_query->is_404 is not set in plugin so what to do?

  • François Létocart

    Change add_action( ‘send_headers’, ‘site_router’);

    to be add_action( ‘wp’, ‘site_router’);