Creating Custom Permalinks in WordPress

This tutorial forms (the final) part of our series of tutorials for creating an custom add-on for Events Manager called “Styles”, where we will be able to select from a list of styles during event registration. In our previous tutorial we created our own custom event pages for our Styles.

For those that don’t know, permalinks are those pretty formatted links you see on websites such as this page you’re reading (I hope)! They’re more commonly known as SEO-Friendly or clean urls.

WordPress allows you to run your site with permalinks turned off or on. It also automatically handles redirections if you switch from non-permalinks to a permalinks site. For example, the page http://wp-events-plugin.com/?p=442 is the non-permalink equivalent of what you see in your address bar.

In this tutorial, we’ll be continuing our extension of our custom Events Manager add-on. We previously created our custom styles pages and now we need to add permalinks to the mix so that the pages don’t have ugly urls like mysite.com/eventspage/?styles_page=1 whilst the rest of your site doesn’t.

This tutorial sort of doubles as a wordpress tutorial (although I found the codex tutorial most helpful when creating permalinks in Events Manager) as this principle could be adapted to work for any plugin. This doesn’t use any plugin-specific functions whatsoever.

Creating the rewrite rules

Firstly, we’ll have to add some rewrite rules to the array. We’ll hook into the rewrite_rules_array filter and add our own rules to the $rules array. For the purposes of this example, we’ll assume our events page is located at our imaginary site mysite.com/events/ What we want to acheive is the following:

  • mysite.com/events/styles/ – displays the list of styles and upcoming events
  • mysite.com/events/style/id#/ – displays the single style name with this id and its upcoming events
add_filter('rewrite_rules_array','my_em_styles_rewrite_rules_array');
function my_em_styles_rewrite_rules_array($rules){
	//get the slug of the event page
	$events_page_id = get_option ( 'dbem_events_page' );
	$events_page = get_post($events_page_id);
	$my_em_rules = array();
	if( is_object($events_page) ){
		$events_slug = $events_page->post_name;
		$my_em_rules[$events_slug.'/styles$'] = 'index.php?pagename='.$events_slug.'&styles_page=1'; //styles list
		$my_em_rules[$events_slug.'/style/(\d+)$'] = 'index.php?pagename='.$events_slug.'&style_id=$matches[1]'; //single style
	}
	return $my_em_rules + $rules;
}

The first four lines involve retrieving the url of the events page and deciding to add our rules only if there is a valid events page. Lines 8 and 9 are the redirection rules, which use regex to identify when we access style pages.

$my_em_rules[$events_slug.'/styles$'] = 'index.php?pagename='.$events_slug.'&styles_page=1'; //styles list
$my_em_rules[$events_slug.'/style/(\d+)$'] = 'index.php?pagename='.$events_slug.'&style_id=$matches[1]'; //single style

The first line will only catch our styles list page. Since we don’t need to obtain any information from here, we’ll just add an extra querystring variable called styles_page and set it to 1.

The second line handles requests for specific style pages. The (\d+) bit will catch the id number and when we pass $matches[1] into the style_id querystring variable it will be replaced by the actual number in the requested url. If this stuff confuses you, you should read up more on regex and the preg_match php function

Register your querystring variables

That was the hard part… the rest is a piece of cake! Now that we’ve added our rewrite rules, we also need to register the new GET parameters we just created, as they will not be made available to the $wp_query object, which can have various adverse implications.

add_filter('query_vars','my_em_styles_query_vars');
function my_em_styles_query_vars($vars){
	array_push($vars, 'style_id','styles_page');
    return $vars;
}

All we’re doing here is pushing our variable names into the $vars array, and passing it back onto the query_vars filter.

Flush the rewrite rules

Next, we need to tell WordPress to flush the old permalink rules and rebuild them so they include our new permalink structures. To do that, we could use the following:

function my_em_rewrite_flush(){
	global $wp_rewrite;
   	$wp_rewrite->flush_rules();
}
add_action('init','my_em_rewrite_flush');

For the purposes of our example add-on, we will not need this, because Events Manager flushes rewrite rules on activation/deactivation. Do bear in mind that this shouldn’t be called on every page load (the above is an example only), only when there is a change to the permalink rules.