Custom query_var causes displaying posts archive on front page

I’m having an issue which is caused by custom query var named date I’ve added using query_vars hook. When date parameter is present in the front page URL (https://example.com/?date=23.08.2016), WordPress is loading posts archive instead of just front page. When other random params are added to the link (https://example.com/?foo=bar) or no params are present, front page is loaded correctly the static page I defined.

Posts page in the backend is different than front page.

I added custom query var using following code:

my_query_vars( $vars ) {
    $vars[] = 'date';
    return $vars;
}

add_filter( "query_vars", "my_query_vars" );

Any idea why such a thing happens?

1 Answer
1

After detailed debugging of WP::parse_request() and WP_Query::parse_query() I found out that unset( $query_vars['date'] ); in 'request' filter helps.

It basically unsets date query var before WP_Query::parse_query() is invoked so is_home() returns false.

add_filter( 'request', function( $query_vars ) {
        global $wp_query, $wp;

        if ( ! $wp_query->is_main_query() ) {
            return $query_vars;
        }

        $qv_keys = array_keys( $wp->query_vars );

        if ( ! ( in_array( 'product_cat', $qv_keys, true )
           || in_array( 'product_tag', $qv_keys, true )
           || in_array( 'post_type', $qv_keys, true ) && 'product' === $wp->query_vars['post_type']
           || in_array( 's', $qv_keys, true )
        ) ) {
            unset( $query_vars['date'] );
        }

        return $query_vars;
} );

Explanation:

Posts archive loads when WP_Query::$is_home = true so I traced back places where this value is set and in brief I think it’s like this:

  1. $this->query_vars['post_type'] and $this->query_vars['name'] are not set in this condition as date query var is not assigned with any post type.
  2. In result after many operations WP_Query::$is_singular is set to false here
  3. And it leads to WP_Query::$is_home = true.

Leave a Comment