Custom taxonomy listing page when no term set (all terms)

What you want is an index page for custom taxonomies. There is a ticket for that, but it’s not clear what is the most obvious thing to show on this page: 1) a list of all posts attached to any term of that taxonomy, or 2) a list of all terms of this taxonomy? Remember that category is also a taxonomy, but it is assumed that all posts fall under at least one category (with Uncategorized as the default). In that case, option 1 would be the same as the regular post query, and option 2 might make more sense.

The related issue of an index page for custom post types will be fixed in the upcoming 3.1 release.

I tried something myself, and instead of interfering with the request hook, I think the better way to do this is adding a new rewrite rule and modifying the query:

add_action( 'init', 'wpse4663_init' );
function wpse4663_init()
{
    // The custom taxonomy rewrite rules end up at the top of the rewrite array
    register_taxonomy(
        'wpse4663',
        array( 'post' ),
        array(
            'label' => 'WPSE 4663',
        )
    );

    // So there probably is no danger in adding this specific rewrite rule there too
    // We re-use the existing `taxonomy` query var, but with no `term`
    // We clean this up in `parse_query`, otherwise get_posts() complains
    // You could make this work for all taxonomies (categories, tags, ...) by doing this repeatedly
    // But then it's probably better to do this in the `rewrite_rules_array` filter
    add_rewrite_rule( 'wpse4663(/page/([0-9]+))?/?$', 'index.php?taxonomy=wpse4663&paged=$matches[2]', 'top' );
}

add_filter( 'parse_query', 'wpse4663_parse_query' );
function wpse4663_parse_query( &$wp_query )
{
    // is_tax is only true if both a taxonomy and a term are set, otherwise is_home is true
    // But we don't want that: is_tax and is_archive should be true, is_home should be false
    if ( !$wp_query->is_tax && $taxonomy_query = $wp_query->get( 'taxonomy' ) ) {
        foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) {
            if ( $t->query_var && $taxonomy_query == $t->query_var ) {
                // Make sure the conditional tags work, so the right template is loaded
                $wp_query->is_tax = true;
                $wp_query->is_archive = true;
                $wp_query->is_home = false;

                // Make is_tax($taxonomy) work
                $wp_query->queried_object = $t;
                $wp_query->queried_object->taxonomy = $taxonomy;

                // If term is null, get_terms (query.php line 2043) will get all terms of this taxonomy
                $wp_query->set( 'term', null );
                break;
            }
        }
    }
}

Leave a Comment