Don’t override query vars with query_posts arguments

Quite often, i find in themes custom queries to customize the content displayed on a page. These themes use either ‘query_posts’ or ‘WP_Query’ to achieve that. For example, the code below allows to exclude posts of some categories from homepage.

if (is_home()) {
  $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
  $build_homepage_query = array (
    'paged'=> $paged,
    'category__not_in' => $theme->get_option('homepage_exclude_categories'),
    'posts_per_page' => $theme->get_option('homepage_posts_per_page')
  );
  query_posts($build_homepage_query);
}

The author of this code took care to not override the query var ‘paged’, not to break the pagination. But if there are some other query vars in the initial query, there are not included in the custom query. All is great when the developper makes his tests because, on a fresh WordPress install, there is no other query vars in the inital query for the homepage.

However, in the case of a multilingual website, the query does contain a new query var ‘lang’ to allow the content to be filtered by language. And the custom query above does not contain the query var ‘lang’, so the code above will not play nicely on multilingual websites.

So a better code is proposed below to keep *all* query vars from the initial query (not only the query var ‘paged’ ) and to modify *only* the query vars needed for the customization purpose.

if(is_home()) {
  $build_homepage_query = array (
    'category__not_in' => $theme->get_option('homepage_exclude_categories'),
    'posts_per_page' => $theme->get_option('homepage_posts_per_page')
  );
  $build_homepage_query = array_merge($GLOBALS['wp_query']->query_vars, $build_homepage_query); // don't reset other query_vars!
  query_posts($build_homepage_query);
}

Picture illustrating the article by Alexas_Fotos and licensed under CC0 Public Domain.