Custom URL parameters in template files

SETUP

I want to pull a query variable from the URL and use it on my single post template (single.php). For example: mysite.com/2011/07/29/testPost/?myvar=someValue

Read More

To do so, I added the custom query variable to functions.php like so:

add_filter('query_vars', 'parameter_queryvars' );

function parameter_queryvars( $qvars ) {
    $qvars[] = 'myvar';
    return $qvars;
}

Then in single.php and index.php I added the following code to test if the custom variable was set and echo a string if true. I also printed the contents of $wp_query->query_vars so I could see if my custom variable was there:

<?php
    global $wp_query;
    if( isset( $wp_query->query_vars['myvar'] )) {
        echo 'custom variable recognized';
    }
    print_r($wp_query->query_vars);
?>

PROBLEM

When I access a URL like mysite.com/2011/07/29/testPost/?myvar=someValue, which uses the single.php template, the echo command is not displayed and the output of print_r() shows that my ‘myvar’ is absent from the list of query_vars.

Output from single.php:

Array ( [p] => 0 [page] => 0 [year] => 2011 [monthnum] => 7 [day] => 29 [name] => testpost [error] => [m] => 0 [post_parent] => [subpost] => [subpost_id] => [attachment] => [attachment_id] => 0 [static] => [pagename] => [page_id] => 0 [second] => [minute] => [hour] => [w] => 0 [category_name] => [tag] => [cat] => [tag_id] => [author_name] => [feed] => [tb] => [paged] => 0 [comments_popup] => [meta_key] => [meta_value] => [preview] => [s] => [sentence] => [fields] => [category__in] => Array ( ) [category__not_in] => Array ( ) [category__and] => Array ( ) [post__in] => Array ( ) [post__not_in] => Array ( ) [tag__in] => Array ( ) [tag__not_in] => Array ( ) [tag__and] => Array ( ) [tag_slug__in] => Array ( ) [tag_slug__and] => Array ( ) [ignore_sticky_posts] => [suppress_filters] => [cache_results] => 1 [update_post_term_cache] => 1 [update_post_meta_cache] => 1 [post_type] => [posts_per_page] => 150 [nopaging] => [comments_per_page] => 50 [no_found_rows] => [order] => DESC [orderby] => wp_posts.post_date DESC )

However, when I access a URL like mysite.com/?myvar=someValue, which uses the index.php template, the echo command is output and you can see the first variable output by print_r() is the ‘myvar’ I am looking for:

Array ( [myvar] => someValue [error] => [m] => 0 [p] => 0 [post_parent] => [subpost] => [subpost_id] => [attachment] => [attachment_id] => 0 [name] => [static] => [pagename] => [page_id] => 0 [second] => [minute] => [hour] => [day] => 0 [monthnum] => 0 [year] => 0 [w] => 0 [category_name] => [tag] => [cat] => [tag_id] => [author_name] => [feed] => [tb] => [paged] => 0 [comments_popup] => [meta_key] => [meta_value] => [preview] => [s] => [sentence] => [fields] => [category__in] => Array ( ) [category__not_in] => Array ( ) [category__and] => Array ( ) [post__in] => Array ( ) [post__not_in] => Array ( ) [tag__in] => Array ( ) [tag__not_in] => Array ( ) [tag__and] => Array ( ) [tag_slug__in] => Array ( ) [tag_slug__and] => Array ( ) [meta_query] => Array ( ) [ignore_sticky_posts] => [suppress_filters] => [cache_results] => 1 [update_post_term_cache] => 1 [update_post_meta_cache] => 1 [post_type] => [posts_per_page] => 150 [nopaging] => [comments_per_page] => 50 [no_found_rows] => [order] => DESC [orderby] => wp_posts.post_date DESC )

QUESTION

Why would the custom query variable be properly set on an index.php page but not on single.php?

I have tested with all plugins off and tried with default permalinks, but got the same results.

Related posts

Leave a Reply

3 comments

  1. The global $wp_query object is not what you are looking for by the time you get to single.php. Instead use global $wp object. Try changing your code to this:

     global $wp;
     if (array_key_exists('myvar', $wp->query_vars) && isset($wp->query_vars['myvar'])){
        echo 'custom variable recognized';
     }
     print_r($wp->query_vars);
    
  2. I took the easy way out and just used something like this:

    $user_id = $_GET['user_id'];
    $user = new WP_User($user_id);
    

    In the template. Then I could call this template with a URL like http://site.com/profile/?user_id=4 and it works wherever. Not as “fully WordPress” as filters, but it works and is fairly clean.

  3. I’m working on the same problem, and I think we also need to use add_query_arg to embed the ?myvar=someValue into the new url that you want to call (like from inside an

    $url_with_param = add_query_arg( 'myvar', 'someValue', site_url('/index.php/') );
    <a href='$url_with_param'>Click Here</a>";

    The add_filter simply makes your myvar available for reading at the target using

    $wp_query->query_vars['myvar']

    I know this is not a complete solution but it’s an important step.