1

I have a WordPress blog that uses custom post types, which I'm creating using the WCK plugin. One of which is the post type shows. A permalink to a specific show, then, appears as:

http://my-website.com/wordpress/shows/show-slug/

This is all done through the current functionality of WP and the WCK plugin. However, I am trying to add another "level" of detailed information to be displayed on that single show page. For this, I am using the URL query variable item to designate this.

So, for example, if I want to view the list of episodes for a certain show, I could visit the URL:

http://my-website.com/wordpress/shows/show-slug/?item=episodes

These "items" vary per-show and are more or less arbitrary, but I already have the logic on the single-shows.php template to determine whether or not the item provided in the URL query is a valid one for that show.

Anyway, I want to use the rewrite functionality to make the URLs a little bit nicer, with the format:

http://my-website.com/wordpress/shows/show-slug/episodes

This is where I'm running into problems. Here is my PHP script in my theme's functions.php file to register that URL query var and the rewrite rule:

function shows_item_tag_registration() {
    global $wp; 
    $wp->add_query_var('item'); 
}

function shows_item_rule_registration($rules) {
    $newrules = array();
    $newrules['^shows/([^/]+)/([^/]+)/?$'] = 'index.php?pagename=shows/$matches[1]&item=$matches[2]';
    return $newrules + $rules;
}

add_filter( 'rewrite_rules_array','shows_item_rule_registration' );
add_action( 'init','shows_item_tag_registration' );

I am not flushing the rewrite rules myself, as I do not want to lose the rules being written by the Permalinks settings in the WP Admin. Instead, as you can see, I am adding my rule to the "current list" in the rewrite_rules_array filter. To apply changes, I re-save the Permalinks settings in the WP admin, and that seems to be doing the trick as far as that goes.

Frustratingly, it almost works, but when I try to visit the URL with the item at the end, like so:

http://my-website.com/wordpress/shows/show-slug/episodes

It simply redirects me to:

http://my-website.com/wordpress/shows/show-slug/

And removes the item from the query altogether. I found this Stack Exchange question that seemed pretty similar, but I was not able to resolve my issue with the answer from there.

2

Maybe you are not using the correct hooks nor the correct rewrite rule. You are rewriting to pagename, which is for pages. You should use name to get posts by slug.

add_filter('query_vars', 'cyb_add_query_vars');
function cyb_add_query_vars( $vars) {
   $vars[] = "item";
   return $vars;
}
add_action('init','cyb_add_rewrite_rules');
function cyb_add_rewrite_rules() {
    add_rewrite_rule( ''^shows/([^/]+)/([^/]+)/?$'' , 'index.php?post_type=shows&name=$matches[1]&item=$matches[2]' , 'top' );
}

You can also add a endpoint and use URLs like http://my-website.com/wordpress/shows/show-slug/item/episodes:

add_action('init','cyb_add_endpoint');
function cyb_add_endpoint() {
    add_rewrite_endpoint( 'item', EP_PERMALINK );
}

And don't forget to flush the rewirte rules. If you don't want to code the flush, visit the permalink settings page in wp-admin area, click on save and the rewrite rules will be flushed.

| improve this answer | |
  • Looks like that did it, thank you very much! I didn't add the endpoint because of how I wanted the final URLs to look, but your script above that did the trick. – William Thomas Jul 16 '14 at 19:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.