Page queried instead of a custom taxonomy

When I try to get an archive for a custom taxonomy, WP searches for a page and doesn’t find anything.

The Setup

My code from the functions.php:

Read More
add_action( 'init', 'register_store_taxonomy' );

function register_store_taxonomy()
{
    $args = array (
        'hierarchical'      => TRUE
    ,   'label'             => 'Store'
    ,   'public'            => TRUE
    ,   'query_var'         => 'store'
    ,   'rewrite'           => TRUE
    ,   'show_in_nav_menus' => TRUE
    ,   'show_ui'           => TRUE
    );
    register_taxonomy(
            'store'
        ,   array ( 'post', 'page' )
        ,   $args
        );
}

Now I have a post tagged with store itunes. Clicking on the link to /store/mac-store/ should list all post in this taxonomy. And it does! On a local server (Win7).
On the staging server (Debian with mostly identical settings), however, I get the 404 page (and the 404 status header).

There are no pages with similar names or slugs, not even in trash. I’ve refreshed the permalinks several times. No active plugins. I tried Google but couldn’t find anything useful.

Debugging

I added the following code to my functions.php to track the error:

add_action( 'wp_footer', 'dump_query' );
function dump_query()
{
    if ( current_user_can( 'edit_posts' ) )
    {
        pre_dump( $GLOBALS['wp_query'] );
    }
}

function pre_dump( $var, $print = TRUE )
{
    $out = '<pre class="vardump">' . htmlspecialchars( var_export( $var, TRUE ) ) . '</pre>';

    if ( ! $print )
        return $out;

    print $out;
}

Output local, working query

WP_Query::__set_state(array(
   'query_vars' => 
  array (
    'store' => 'itunes',
    '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' => false,
    'suppress_filters' => false,
    'cache_results' => true,
    'update_post_term_cache' => true,
    'update_post_meta_cache' => true,
    'post_type' => '',
    'posts_per_page' => 10,
    'nopaging' => false,
    'comments_per_page' => '50',
    'no_found_rows' => false,
    'taxonomy' => 'store',
    'term' => 'itunes',
    'order' => 'DESC',
    'orderby' => 'wp_posts.post_date DESC',
  ),
   'tax_query' => 
  WP_Tax_Query::__set_state(array(
     'queries' => 
    array (
      0 => 
      array (
        'taxonomy' => 'store',
        'terms' => 
        array (
          0 => 'itunes',
        ),
        'include_children' => true,
        'field' => 'slug',
        'operator' => 'IN',
      ),
    ),
     'relation' => 'AND',
  )),
   'post_count' => 1,
   'current_post' => -1,
   'in_the_loop' => false,
   'comment_count' => 0,
   'current_comment' => -1,
   'found_posts' => '1',
   'max_num_pages' => 1,
   'max_num_comment_pages' => 0,
   'is_single' => false,
   'is_preview' => false,
   'is_page' => false,
   'is_archive' => true,
   'is_date' => false,
   'is_year' => false,
   'is_month' => false,
   'is_day' => false,
   'is_time' => false,
   'is_author' => false,
   'is_category' => false,
   'is_tag' => false,
   'is_tax' => true,
   'is_search' => false,
   'is_feed' => false,
   'is_comment_feed' => false,
   'is_trackback' => false,
   'is_home' => false,
   'is_404' => false,
   'is_comments_popup' => false,
   'is_paged' => false,
   'is_admin' => false,
   'is_attachment' => false,
   'is_singular' => false,
   'is_robots' => false,
   'is_posts_page' => false,
   'is_post_type_archive' => false,
   'parsed_tax_query' => true,
   'query' => 
  array (
    'store' => 'itunes',
  ),
   'request' => ' SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1  AND ( wp_term_relationships.term_taxonomy_id IN (135,134,133,132,131,130,129,128,125) ) AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 7 AND wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10',
   'posts' => 
  array ( /* cut out */),
   'queried_object' => 
  stdClass::__set_state(array(
     'term_id' => '124',
     'name' => 'iTunes',
     'slug' => 'itunes',
     'term_group' => '0',
     'term_taxonomy_id' => '125',
     'taxonomy' => 'store',
     'description' => '',
     'parent' => '0',
     'count' => '1',
  )),
   'queried_object_id' => 124,
))

Output staging server, broken query

WP_Query::__set_state(array(
   'query_vars' => 
  array (
    'page' => 0,
    'pagename' => 'itunes',
    'error' => '',
    'm' => 0,
    'p' => 0,
    'post_parent' => '',
    'subpost' => '',
    'subpost_id' => '',
    'attachment' => '',
    'attachment_id' => 0,
    'name' => 'itunes',
    'static' => '',
    '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 (
    ),
    'ignore_sticky_posts' => false,
    'suppress_filters' => false,
    'cache_results' => true,
    'update_post_term_cache' => true,
    'update_post_meta_cache' => true,
    'post_type' => '',
    'posts_per_page' => 10,
    'nopaging' => false,
    'comments_per_page' => '50',
    'no_found_rows' => false,
    'order' => 'DESC',
    'orderby' => 'wp_posts.post_date DESC',
  ),
   'tax_query' => 
  WP_Tax_Query::__set_state(array(
     'queries' => 
    array (
    ),
     'relation' => 'AND',
  )),
   'post_count' => 0,
   'current_post' => -1,
   'in_the_loop' => false,
   'comment_count' => 0,
   'current_comment' => -1,
   'found_posts' => 0,
   'max_num_pages' => 0,
   'max_num_comment_pages' => 0,
   'is_single' => false,
   'is_preview' => false,
   'is_page' => false,
   'is_archive' => false,
   'is_date' => false,
   'is_year' => false,
   'is_month' => false,
   'is_day' => false,
   'is_time' => false,
   'is_author' => false,
   'is_category' => false,
   'is_tag' => false,
   'is_tax' => false,
   'is_search' => false,
   'is_feed' => false,
   'is_comment_feed' => false,
   'is_trackback' => false,
   'is_home' => false,
   'is_404' => true,
   'is_comments_popup' => false,
   'is_paged' => false,
   'is_admin' => false,
   'is_attachment' => false,
   'is_singular' => false,
   'is_robots' => false,
   'is_posts_page' => false,
   'is_post_type_archive' => false,
   'parsed_tax_query' => true,
   'query' => 
  array (
    'page' => '',
    'pagename' => 'store/itunes',
  ),
   'request' => ' SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND (wp_posts.ID = '0') AND wp_posts.post_type = 'page'  ORDER BY wp_posts.post_date DESC ',
   'posts' => 
  array (
  ),
   'queried_object' => NULL,
   'queried_object_id' => 0,
))

I feel that I miss something obvious, but I’m lost right now.

So my questions are: How can I make WP search the taxonomy archive? Why does it work on one server, but not on the other?

Update

Permalinks are set to /%year%/%postname%/ on both servers and I flushed the rewrite rules on init per:

$GLOBALS['wp_rewrite']->flush_rules();

Update 2

using the Rewrite Analyzer plugin from @Jan Fabry I compared the rules on my local installation and on the staging server. On the latter, the rules are absent.

Rewrite rules local

store/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$            store: ([^/]+)
           feed: (feed|rdf|rss|rss2|atom)
store/([^/]+)/(feed|rdf|rss|rss2|atom)/?$             store: ([^/]+)
           feed: (feed|rdf|rss|rss2|atom)
store/([^/]+)/page/?([0-9]{1,})/?$            store: ([^/]+)
          paged: ([0-9]{1,})
store/([^/]+)/?$              store: ([^/]+)

Do I really have to add the rules manually? Usually register_taxonomy() should do that, shouldn’t it?

Workaround

Bah! I used a workaround to add the missing rewrite rules per functions.php:

add_action( 'init', 'add_taxrules_manually' );
function add_taxrules_manually()
{
    $tax           = 'store';
    $rewrite_rules = get_option( 'rewrite_rules' );

    if ( isset ( $rewrite_rules[ $tax . '/([^/]+)/?$' ] ) )
    {
        return;
    }

    $new_rules = array (
        $tax . '/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?' . $tax . '=$matches[1]&feed=$matches[2]',
        $tax . '/([^/]+)/(feed|rdf|rss|rss2|atom)/?$'      => 'index.php?' . $tax . '=$matches[1]&feed=$matches[2]',
        $tax . '/([^/]+)/page/?([0-9]{1,})/?$'             => 'index.php?' . $tax . '=$matches[1]&paged=$matches[2]',
        $tax . '/([^/]+)/?$'                               => 'index.php?' . $tax . '=$matches[1]',
    );

    $update = array_merge( $new_rules, $rewrite_rules );
    update_option( 'rewrite_rules', $update );
}

Important: The new rules must come before the page rules. Changing the order of arguments in array_merge() will not fix it.

The question is still open, because I just have to understand what happens here.

Related posts

Leave a Reply

1 comment