Wordpress Custom URLs for Plugins

Wordpress supports custom URL rewrites for search engine friendly URLs, but the fact is they can be a real pain in the ass for WP plugin authors. As is evidenced by the plethora of confused posts out there desperately seeking help with add_rewrite_rule() and add_rewrite_tag(), slapping a few new rules and custom querystring variables in your plugin’s functions.php just doesn’t always cut it.

Custom URLs for Wordpress Plugins


Take the following scenario: you have a custom plugin for displaying products on a Wordpress site, but there are thousands of products. Obviously you don’t want to use WP posts or pages to add every single product, so you probably have a unique interface for product management somewhere. Heck, maybe you’re even fetching the product info from a 3rd party source.

WP purists will whine that if it can work with built-in Wordpress posts and pages, then itshould work with posts and pages. I disagree. Many websites get started with WP and want to expand beyond the limitations of the WP platform - that shouldn’t require an intensive migration of design, categories, posts, and everything else they have created, assuming they are happy with the WP platform for their blogging and basic CMS needs. But anyway, that’s a conversation for a different time.

That said - if your plugin doesn’t just piggyback the built-in posts and pages format, and you don’t want to create custom taxonomies that tie you in to the WP mechanisms, the solution might be to roll your own basic rules.

Setting up Custom URLs


Since many plugins are developed that work outside the scope of Wordpress pages, plugin authors can use custom templates with template_redirect(). This is an easy way to create a unique interface for your plugin that you can do pretty much anything with.

But, let’s say you want to use a custom URL for your interface, and also need to access the URL variables from your custom template. For example, imagine you need an URL format like this:

http://mysite.com/items/big-yellow-raincoat/

Wouldn’t it be nice to call that URL, have the query string variables “items” and “big-yellow-raincoat” parsed out and automatically redirect to your custom template?

Wordpress has a whole slew of functions for custom URL rewriting, but they all tend to work around the existing structure of Wordpress page and post types.

After endless experimentation with add_rewrite_rule() and add_rewrite_tag(), as well as custom handling of $wp->query_vars and everything else in between, I have settled on a very simple implementation to essentially take control of the custom URLs and pass it along to a plugin interface.

Coding a Custom URL Handler


First, the basic approach is to set up a custom function for parsing the current URL.

function my_url_handler()
{
// Manually parse the URL request
if(!empty($_SERVER[‘REQUEST_URI’]))
{
$urlvars = explode(‘/‘, $_SERVER[‘REQUEST_URI’]);
}
}



The above function my_url_handler() basically takes the current request URL from$_SERVER[‘REQUEST_URI’] and splits it up on the forward slashes. Then we can do WHATEVER WE WANT with it.

So, after running this, the $urlvars array will contain the elements from our URL in the example above:

[0] => ‘items’,
[1] => ‘big-yellow-raincoat’



Typically, the first element in the URL contains important information about our “view” (or the interface that will process the request). Then the second element will contain the data - in this case, a unique ID string.

So, we can expand our function to check for these elements and then set our $_REQUEST variables explicitly, where they can then be accessed from the rest of our plugin just like they were passed by a browser.

function my_url_handler()
{
// Manually parse the URL request
if(!empty($_SERVER[‘REQUEST_URI’]))
{
$urlvars = explode(‘/‘, $_SERVER[‘REQUEST_URI’]);
}

// Check for querystring variables
if((!empty($urlvars[1])) && (!empty($urlvars[2])))
{
    $_REQUEST['myview'] = $urlvars[1];

    if($urlvars[1] == 'item')
    {
        // Set the $_REQUEST vars
        $_REQUEST['myid'] = $urlvars[2];

        // Redirect to custom plugin template for "item" view
        add_action('template_redirect', 'my_custom_item_template');
    }

    // ... handle multiple types of URL by checking $urlvars[1] here
}

}


There! Now our little function parses the URL, checks the first element to determine our view, then sets the view and URL data in the $_REQUEST array ($_REQUEST is an associative array that contains all the HTTP request variables GET, POST and COOKIE). It then registers the template_redirect for our custom template for that view.

The final step is just to add a hook to parse_request for the new function, generally add the end of your plugin’s functions.php file:

add_action(‘parse_request’, ‘my_url_handler’);



Now, when your custom plugin template runs, you can just access the variables in $_REQUEST to get the unique ID, view, etc.

The next steps are filtering the page titles to ensure that you don’t see “Page Not Found” in the browser title, and further testing to make sure that WP doesn’t spit any 404’s out because it couldn’t find your content. However, that’s a subject for another post.

This method is simple, clean, and requires virtually no built-in WP methods. Wordpress purists may be seething in a fit of rage right now, and if that’s the case I invite them all to seriously improve Wordpress custom URL handling for plugin authors.

refer: