WordPress: adding a new template file

We’ve developed a site using WordPress as teh base of an ecommerce site using the excellent eshop plugin. During the development we needed to create a page that would display posts based on a post meta value. Essentially we wanted to display posts based on price range. The site user would get to that page using a drop down from the sidebar. So far so good. Generating a list of posts using a custom query is straightforward. The issue we had was telling WordPress that there was a new template file that had nothing to do with categories, tags, taxonomies, posts, pages or anything else WordPress is aware of.

Two things needed doing

  • set up URL that WordPress will listen to
  • load a specific template when then URL is requested

The URL we wanted to use was

/price-range/[lowPrice]-[highPrice]/

where [lowPrice] and [highPrice] are placeholders for the lowest price and the highest price in the range respectively.

The WordPress rewrite rules take URLs of the format

/category/stuffedtoys

and turn them into

/index.php?category=stuffedtoys

which are then processed by the WordPress system, the appropriate template loaded and the posts displayed.

If you add a new taxonomy or custom post type WordPress takes care of setting up the rules. To manually add  a rule we follow the usual WordPress process of defining a function and adding an action to the theme’s functions.php file. The following function and add_action will set up a new rewrite rule to rewrite our price-range URLs. The

function createRewriteRules()

{

global $wp_rewrite;

$keytag = ‘%price-range%’;

$wp_rewrite->add_rewrite_tag($keytag, ‘([^/]+)’, ‘price-range=’);

$keywords_structure = $wp_rewrite->root . “price-range/$keytag/”;

$keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure);

$wp_rewrite->rules = $keywords_rewrite + $wp_rewrite->rules;

return $wp_rewrite->rules;

}

add_action(‘generate_rewrite_rules’, ‘createRewriteRules’);

Further details are in the WordPress Codex of what these methods do.

Now we need to tell WordPress to load our new template, price-range.php, whenever the it sees the GET, or query, variable price-range is set.

First tell WordPress that there is a new query variable it needs to be a aware of by adding the function below and the add_filter to the theme’s functions.php.

function add_query_vars($aVars)

{

$aVars[] = “price-range”;

return $aVars;

}

add_action(‘generate_rewrite_rules’, ‘createRewriteRules’);

Now we can tell WordPress to load the new template if query variable price-range is set. Again add the add_action and function to the theme’s functions.php

function priceRange()

{

$priceRange = get_query_var(‘price-range’);

if ($priceRange != ”)

{

add_filter(‘body_class’,’priceRangeBodyClass’);

include(TEMPLATEPATH.’/price-range.php’);

exit;

}

}

function priceRangeBodyClass()

{

return array(‘archive’);

}

add_action(‘template_redirect’,’priceRange’);

Note that without the if statement WordPress would load this template for every request.

One final thing is that WordPress automatically adds a class to the HTML body tag based on what WordPress thinks is the type of page (category, archive, single post, etc) defaulting to the home class if it can’t decide. The add_filter inside the if statement calls a function that overrides any previously set class and sets it to ‘archive’ – which as displaying products by price range is a type of archive worked for this product. The class, however, could be set to anything. Note that the function returns an array so multiple classes could be set.

To summarise

  • We’ve added a rewrite rule mapping /price-range/[range] to /index.php?price-range=[range]
  • We’ve told WordPress that there is a new query variable to listen for, price-range
  • When price-range is set, then word price should load the template price-range.php and override the default body tag class.
  1. No comments yet.

  1. No trackbacks yet.