Querystring parameter getting lost in rewrite rule

I have successfully added a custom post type and the permalink structure works great. So, for instance, I’ve got a custom post type books, and the permalink to a book is /books/the-dictionary.

My single-book.php page template accepts a letter parameter to customize the content displayed on the page. I’d like to be able to link to this like /book/the-dictionary/q.

Read More

I’ve added the following to my theme’s functions.php file:

function my_init() {
    add_books_rewrite();

function add_books_rewrite() {
    add_rewrite_rule("books/([^/]+)/([^/])/?$", 'index.php?pagename=$matches[1]&letter=$matches[2]', "top");
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}
function add_books_query_vars($query_vars) {
    $query_vars[] = "letter";
    return $query_vars;
}
add_filter("init", "my_init");
add_filter("query_vars", "add_books_query_vars");

It took a few tries with using the flushing code above, manually going to the permalink settings page and saving, and fixing stupid errors in the regex, but eventually I was able to verify that the rewrite was added correctly by using Jan Fabry’s fabulous rewrite analyzer plugin.

confirmed in rewrite analyzer

So, from here I think it’s smooth sailing, right? Yeah…not exactly.

When I load up my site and go to books/the-dictionary/q, it does load the-dictionary content correctly, but it is losing the parameter. The thing that I find interesting is that if I load index.php?pagename=the-dictionary&letter=q, everything works great.

To retrieve the parameter, I have the following code:

global $letter;
echo $letter. " - global";
echo "<br>";
$current_letter = (isset($wp_query->query_vars["letter"]) ? $wp_query->query_vars["letter"] : "all");
echo $current_letter . " - query_vars";
echo "<br><br>";

I’ve also been looking at $_SERVER["QUERY_STRING"]. These are populated when I use index.php?pagename...&letter..., but not when I use /books/pagename/letter.

So, it seems like a few things are happening here. WordPress isn’t completely dropping the parameter since things work if I specify index.php with the appropriate querystring variables. This seems to indicate the rewrite rule isn’t working correctly. However, the Rewrite Analyzer plugin seems to say things are set up properly for what I’m going for.

I’m a bit confused at what I should be looking at here to fix the disconnect. Sorry if I’m missing something obvious. ):

Related posts

Leave a Reply

1 comment

  1. I think it’s probably your front end code that’s the problem.

    Try this:

    <?php
    if( $letter = get_query_var( 'letter' ) ) 
    {
            echo 'Current Letter: ' . $letter;
    }
    else
    {
            echo 'Current Letter: All';
    }