• Follow me on Twitter
  • Follow my Flickr stream
  • Follow me on Gatorpeeps
  • Add me to your Technorati favourites
  • Follow me on Zoopy

Custom URL rewrites in Wordpress — A Getting Started Guide

Hey every­one.
I’ve been tweet­ing quite a bit recently about cus­tom URL rewrites in Wordpress. After a few hours of trial and error, I’ve man­aged to get my spe­cific cus­tom URL rewrites work­ing. After read­ing through sev­eral tutori­als online (the major­ity of which used the same examples to explain only a por­tion the inform­a­tion I was look­ing for), here’s my tutorial– a get­ting star­ted guide to Custom URL rewrites in Wordpress.

The pro­cess

So, what exactly are we doing here? To put things in point form, this is the process:

  1. Create cus­tom rewrite rules
  2. Add our new vari­ables to the public_​query_​vars array
  3. Flush (and thus, regen­er­ate) all Wordpress rewrite rules
  4. Add our func­tions from steps 1, 2 and 3 into Wordpress via actions and filters

Right, so lets get down to it then.

Create cus­tom rewrite rules

Rewrite rules use a  token which is replaced by the neces­sary query vari­able. For example, we cre­ate a token called %token% which, using a reg­u­lar expres­sion, gets replaced by “id=”. This will be shown fur­ther below.

/​**
* create_​custom_​rewrite_​rules()
* Creates the cus­tom rewrite rules.
* return array $rules.
**/

func­tion create_​custom_​rewrite_​rules() {
global $wp_​rewrite;

/​/​ Define cus­tom rewrite tokens
$rewrite_​tag = ‘%exampletag%’;

/​/​ Add the rewrite tokens
$wp_rewrite->add_rewrite_tag( $rewrite_​tag, ‘(.+?)’, ‘car=’ );

/​/​ Define the cus­tom permalink struc­ture
$rewrite_​keywords_​structure = $wp_rewrite->root . “%pagename%/$rewrite_tag/”;
/​/​ $rewrite_​keywords_​structure = $wp_rewrite->root . “$slug/$rewrite_tag/”;

/​/​ Generate the rewrite rules
$new_​rule = $wp_rewrite->generate_rewrite_rules( $rewrite_​keywords_​structure );

/​/​ Add the new rewrite rule into the global rules array
$wp_rewrite->rules = $new_​rule + $wp_rewrite->rules;

return $wp_rewrite->rules;

} /​/​ End create_​custom_​rewrite_​rules()

Add our new vari­ables to the public_​query_​vars array

By default, Wordpress has an array of pub­lic query vari­ables which can be used within tem­plates and plu­gins. In order to access our query vari­ables (ie: the “id=” in the above example), the vari­able needs to be added to the pub­lic query vars array.

/**
* add_custom_page_variables()
* Add the custom token as an allowed query variable.
* return array $public_query_vars.
**/

function add_custom_page_variables( $public_query_vars ) {
$public_query_vars[] = 'car';

return $public_query_vars;

} // End add_custom_page_variables()

Flush all Wordpress rewrite rules

By flush­ing the rules, we are for­cing Wordpress to regen­er­ate it’s rules list, includ­ing our new rules in the rules set.

/**
* flush_rewrite_rules()
* Flush the rewrite rules, which forces the regeneration with new rules.
* return void.
**/

function flush_rewrite_rules() {

global $wp_rewrite;

$wp_rewrite->flush_rules();

} // End flush_rewrite_rules()

Add our func­tions from steps 1, 2 and 3 into Wordpress via actions and filters

Now that our func­tions have been cre­ated, we need to hook them into the vari­ous neces­sary pro­cesses within Wordpress. We do this using a com­bin­a­tion of actions and filters.

Our first action runs on ini­tial­iz­a­tion. This is where we flush the rewrite rules in Wordpress, caus­ing them to be regenerated.

The regen­er­a­tion brings us to action num­ber 2. This is where we cre­ate our cus­tom rewrite rule, hook it on to the global rewrites array and gen­er­ate the rules.

Our final line is our fil­ter where we add the new pub­lic query vari­able into the global public_​query_​vars array. We then later use this array to access the vari­able in our theme.

add_action( 'init', 'flush_rewrite_rules' );
add_action( 'generate_rewrite_rules', 'create_custom_rewrite_rules' );
add_filter( 'query_vars', 'add_custom_page_variables' );

The scope of rewrite rules

By default, Wordpress rules are applied across all pages. Thus, the tag “%page­name%” is used in place of a spe­cific page slug. To use your rules on only a single page, replace “%page­name%” with a spe­cific page slug. You can either gen­er­ate this slug dynam­ic­ally or staticly.

That’s all, folks

And there you have it. A cus­tom rewrite rule in Wordpress. This post is inten­ded as a start­ing point for using cus­tom rewrite rules in Wordpress. There are vir­tu­ally infin­ite pos­sib­il­it­ies cre­ated when using rewrite rules (either one or many) and some really inter­est­ing plu­gins and func­tion­al­it­ies can come out of using rewrite rules.

Thanks must also go to Joe Hoyle who’s use of rewrite rules provided the inspir­a­tion for this tutorial.

If there’s any­thing that isn’t clear, please com­ment below and I’ll do my best to cla­rify and help.

Before I go… wouldn’t you like the files?

I thought you might. Click below to down­load the code writ­ten above (it’s been writ­ten into a class for easy imple­ment­a­tion in your projects).

Download the  “Custom URL rewrites in Wordpress — A Getting Started Guide” code example.

Related Posts

Comments
  1. Justin Slack Justin Slack says:

    Great tutorial nd very well-​​explained. I will def­in­itely find a num­ber of uses for this.

  2. Matty Matty says:

    Thanks Justin. I look for­ward to it. :)

    Please tweet some URLs where you use this tut. I’d be keen to see your imple­ment­a­tion of it. :)

    Cheers and thanks again,
    Matt.

  3. lite­motiv litemotiv says:

    accord­ing to this post (http://wordpress.org/support/topic/226529), flush_​rules() is quite expens­ive and shouldn’t be called on each init. newly gen­er­ated rules are stored in the data­base, so you only have to call it once when you intro­duce new rewrites.

    –lite

    p.s., i love your blog design!

  4. Matty Matty says:

    Hey lite,
    Thanks for the link and your very kind com­ments about my blog design. :)

    I’ll check into flush_​rules() and optim­ise the code accordingly.

    Cheers and thanks again,
    Matty.

  5. Brad Brad says:

    It would be nice if you fol­lowed this up with a real plu­gin example, and I “think” the add_​action( ‘init’, ‘flush_​rewrite_​rules’ ); needs to be add_​action( ‘admin-​​init’, ‘flush_​rewrite_​rules’ ); BUT I am not 100% cer­tain on that.

    Thanks

    –Brad

  6. Matty Matty says:

    Hi Brad,
    Thanks for your comment.

    I’ll look into the call to flush_​rewrite_​rules.

    I’ll be writ­ing a few more posts dis­cuss­ing cus­tom rewrite rules in Wordpress, how to work with them and a few advanced uses. These may be fol­lowed up with a plu­gin. ;)

    Cheers,
    Matt.

  7. Dan Smart Dan Smart says:

    The guid­ance given in the Wordpress Codex is to do it in ‘init’ rather than admin-​​init’, how­ever I may be not tak­ing into account per­form­ance with this.

    From: http://codex.wordpress.org/Query_Overview:

    “So if you want to modify rewrite rules, you will need to call $wp_rewrite->flush_rules() to force them to recal­cu­late. You’ll need to do this in your plugin’s init action, so that it hap­pens early enough in the process. ”

    Cheers…Dan

  8. Matty Matty says:

    @Dan Thanks for your com­ment, Dan. :)

    I don’t think using ‘init‘ or ‘admin-​​init‘ makes much of a dif­fer­ence. It means it’ll either run on init only when in the admin area or on init in gen­eral. Either way, init hap­pens and the func­tion doesn’t seem very intens­ive. Using ‘admin-​​init‘ could pos­sibly increase front-​​end per­form­ance though, as the func­tion would not be run­ning on the front-​​end. Not sure if the per­form­ance dif­fer­ence would be notice­able though.

    It looks, to me, like it’s a case of 6 of 1 or half a dozen of the other. Using either method, the func­tion will run at the init stage. :)

    Thanks for the link and quote. I find the Wordpress codex to be a use­ful resource which I use reg­u­larly. :)

    Cheers,
    Matt.

Leave a Reply

Designed and Developed by Matty | back to top