WordPress: Creating Custom Permalinks for Plug-Ins

Over the last week or so, I’ve been working to develop a new WordPress plug-in that sets up bi-monthly archives (to be generated for the first and fifteenth of the month by default). As part of that process, I needed to create custom permalinks to display these new archives. Unfortunately, the amount of information available on this matter is fairly limited. I had to gather information from a few different places and then use some of my own experience to finalize the process.

It’s entirely possible that there’s a better way to handle this situation, but this is what I was able to do.

To start with, I used the instructions found in the WP Codex explaining how to create custom permalinks for plug-ins. Basically, they boil down to the following actions:

  1. Add a filter as part of the rewrite_rules_array() function
    • This function inserts a new rewrite rule. The only parameter of the function is an array of the existing rules. You will then create a new array item with the regex to parse as the key of the new item and the replacement structure as the value of the new array item. Then, return the updated array.
  2. Add a filter as part of the query_vars() function
    • This function inserts a new query variable. The only parameter of this function is an array of the existing query variables. Within this function, you need to push your new variable key into this array and return the updated array.
  3. Add a filter as part of the init() function
    • This function simply flushes the existing rewrite rules so that your new rule will be applied. Within this function, simply globalize the $wp_rewrite variable and invoke the flush_rules() method of that object.

Although these steps are not 100% necessary, WordPress will send a 404 header with the page if they haven’t already been done. Obviously, if all of your pages are returning 404 errors, Google won’t index them, so that is probably not a desired outcome.

The next thing you need to do is figure out how to access the new variable you created. I’m sure there’s a way to access that new variable through existing WordPress methods, but I couldn’t figure out where and how to do so. Therefore, I resorted to simply using the PHP superglobal server variable “REQUEST_URI” ($_SERVER['REQUEST_URI']) and parsing it to find the variable. In my case, the permalink structure starts with the word “issue” (because the bi-monthly archive plug-in is essentially creating issues of a magazine) followed by a slash and then a date in YYYY-MM-DD format. Therefore, my function looks like the following:

function parse_issue_permalink() {
// Parse the URL and handle the permalink
if( strstr( $_SERVER['REQUEST_URI'], '/issue/' ) ) {
$qstr = explode( '/', $_SERVER['REQUEST_URI'] );
while( count($qstr) && !isset($_GET['issue']) ) {
$d = array_pop($qstr);
$d = explode('-',$d);
if(count($d) == 3 && is_numeric($d[0]) && is_numeric($d[1]) && is_numeric($d[2])) {
$_GET['issue'] = implode('-',$d);
}
}
}
}
add_action('init','parse_issue_permalink');

Notice that I invoke this function as part of the WordPress init() function.

The function shown above will parse the URL, find the variable we want and then store it in the $_GET superglobal array.

If that’s all you want to do, then you should be finished. However, in my case, I also needed to update the title of each page based on the value of the variable. Therefore, inside of the parse_issue_permalink() function, I created another function that updates the title of the page. The updated parse_issue_permalink() function is shown below:

function parse_issue_permalink() {
// Parse the URL and handle the permalink
if( strstr( $_SERVER['REQUEST_URI'], '/issue/' ) ) {
$qstr = explode( '/', $_SERVER['REQUEST_URI'] );
while( count($qstr) && !isset($_GET['issue']) ) {
$d = array_pop($qstr);
$d = explode('-',$d);
if(count($d) == 3 && is_numeric($d[0]) && is_numeric($d[1]) && is_numeric($d[2])) {
$_GET['issue'] = implode('-',$d);
}
}
}
function edit_issue_title( $title, $sep ) {
if(isset($_GET['issue'])) {
$title = APDate($_GET['issue']) . ' ' . $sep . ' ';
}
return $title;
}
add_filter('wp_title', 'edit_issue_title', 10, 2);
}
add_action('init','parse_issue_permalink');

If you find the need to create custom permalinks for a WordPress plug-in, hopefully the information in this article will help. If you have any suggestions on improving the process, please feel free to share it in the comments.

6 Responses

  • I know exactly how you feel. This is something that I am working on right now. If you are going to work with seo then you must have this information. This was a great resource! I have bookmarked this page. Thanks.

  • lorenzo

    I am trying to create a URL structure where I have seasonal issues (summer2010, fall2010, etc) as a kind of permalink – regardless of when I add articles. I mean if I add content in July 2011, but I somehow designate it as part of the Winter 2008 isssue, it’ll show up when you enter foo.com/winter-2008. I can’t find info on this anywhere?

    • In that case, I would recommend either simply using the issue name as the “category” for the posts (for instance, you would create a “category” called “Winter 2008” and assign all of the appropriate articles to that category) or setting up a custom taxonomy for the issue names. Some good information about WordPress custom taxonomies can be found at NetTuts+.

  • lorenzo

    Thank you Curtis! Is using categories vs. creating a custom taxonomy considered bad form? If custom taxonomies are’ best practice’ I’ll take a stab at what NeTuts+ offers in the way of information.

    • If you’re not already using the categories taxonomy for another reason (for instance, if your articles are divided up into separate sections within each issue), I honestly wouldn’t worry about trying to create a custom taxonomy. The custom taxonomies come in handy when you’re already using the “Tags” and/or “Categories” for other reasons.

  • lorenzo

    What I’m looking for is a way to define the URL using a specific category. For example…

    http://www.foo.com/issue/winter2011
    http://www.foo.com/issue/spring2011

    …and in categories I have a parent category called ‘issue’ and child categories for each issue (e.g. winter2011) with ‘issue’ as the parent.

    The issue is how to define that in WordPress Permalink. I’ve tried a few plug-ins (Hikari Category Permalink, Custom Field Taxonomies) but still don’t have it. Any clues?!