2

I've generated three different custom post types (e.g. books, movies, games). I've also created a custom taxonomy for all of them (e.g. genre).

What I need are archives for the taxonomy based on the post types. For example: "books-genre", "movies-genre"...

Is there any solution to do that? Now I've only the taxonomy archive for "genre".

5

Here is a complete example made possible using add_rewrite_rule(). The basic setup for this example is documented first, then we'll get to the real part of the solution using add_rewrite_rule().

Taxonomy and Post Type registration

Register the genre taxonomy and the book, movie, and game post types (note that the singular version of each of these names is being used in this example because it's considered a best practice).

// Create taxonomy: genre for post types: book, movie, and game
// https://codex.wordpress.org/Function_Reference/register_taxonomy
add_action( 'init', 'wpse247013_register_taxonomies', 0 );
function wpse247013_register_taxonomies() {
    $args = [
        'public'            => true,
        'hierarchical'      => false,
        'label'             => __( 'Genres', 'textdomain' ),
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => 'genre',
        'rewrite'           => [ 'slug' => 'genres' ],
    ];

    register_taxonomy( 'genre', [ 'book', 'movie', 'game' ], $args );
}

// Create post types: movie, book, and game
// https://developer.wordpress.org/reference/functions/register_post_type/
add_action( 'init', 'wpse247013_register_post_types' );
function wpse247013_register_post_types() {
    $book_args = [
        'label'              => __( 'Books', 'textdomain' ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => [ 'slug' => 'books' ],
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'supports'           => [ 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ],
        'taxonomies'         => [ 'genre' ],
    ];
    register_post_type( 'book', $book_args );

    $movie_args = [
        'label'             => __( 'Movies', 'textdomain' ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => [ 'slug' => 'movies' ],
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'supports'           => [ 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ],
        'taxonomies'         => [ 'genre' ],
    ];
    register_post_type( 'movie', $movie_args );

    $game_args = [
        'label'             => __( 'Games', 'textdomain' ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => [ 'slug' => 'games' ],
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'supports'           => [ 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ],
        'taxonomies'         => [ 'genre' ],
    ];
    register_post_type( 'game', $game_args );
}

Basic URL Examples

Based on the setup above, we'll get these URLs out of the box:

Post type archive URLs

Single post type URLs

Taxonomy Term archive URLs

Handle rewrite rules

Rewrite rules must be added in order to limit a particular genre term to a single post type. An additional rule is needed for pagination for each post type.

/**
 * Add rewrite rules for genre terms limited to book, movie, and game post types.
 * Pagination issue fix via http://wordpress.stackexchange.com/a/23155/2807
 * @link https://codex.wordpress.org/Rewrite_API/add_rewrite_rule
 */
function wpse247013_rewrite_rules() {
    // Book Genres
    add_rewrite_rule( '^books/book-genres/([^/]+)/?$',
            'index.php?taxonomy=genre&post_type=book&term=$matches[1]', 'top' );

    // Book Genres pagination
    add_rewrite_rule( '^books/book-genres/([^/]+)/page/([0-9]+)?$',
            'index.php?post_type=book&genre=$matches[1]&paged=$matches[2]', 'top' );

    // Movie Genres
    add_rewrite_rule( '^movies/movie-genres/([^/]+)/?$',
            'index.php?taxonomy=genre&post_type=movie&term=$matches[1]', 'top' );

    // Movie Genres pagination
    add_rewrite_rule( '^movies/movie-genres/([^/]+)/page/([0-9]+)?$',
            'index.php?post_type=movie&genre=$matches[1]&paged=$matches[2]', 'top' );

    // Game Genres
    add_rewrite_rule( '^games/game-genres/([^/]+)/?$',
            'index.php?taxonomy=genre&post_type=game&term=$matches[1]', 'top' );

    // Game Genres pagination
    add_rewrite_rule( '^games/game-genres/([^/]+)/page/([0-9]+)?$',
            'index.php?post_type=game&genre=$matches[1]&paged=$matches[2]', 'top' );
}
add_action( 'init', 'wpse247013_rewrite_rules', 10, 0 );

Make sure to flush the rewrite rules by visiting Settings > Permalinks after adding this code to your plugin or theme. If you're using a plugin, you can flush the rules programmatically using register_activation_hook.

Custom URLs

The rewrite rules added above will enable the following new URLs:

  • WOW! I will test it in the next days! Thank you very much for this answer ;) – Cray Nov 28 '16 at 13:30
  • You got it, keep me posted! – Dave Romsey Nov 28 '16 at 19:49
  • works like a charm ;) – Cray Nov 30 '16 at 14:34
  • one last question: is it ok to use only the term "genres" in the URL (without book-, movie- or game-)? I've tried it and it's working. But I'm not sure if maybe there are problems I don't see?! (For example: add_rewrite_rule( '^movies/genres/....) – Cray Nov 30 '16 at 16:06
  • Yes, that should be fine. I tested this setup, and the the URLs under Basic URL Examples and Custom URLs in my answer still worked correctly. – Dave Romsey Nov 30 '16 at 22:48
1

You can register taxonomy dynamically like this,

add_action('init',function(){

    $postType = array( 'books','movies','games' );

    foreach ( $postType as $k => $cpt ) {

        $tax_slug = strtolower( $cpt ) . '-genre';

        register_taxonomy(
            $tax_slug,
            strtolower( $cpt ),
            array(
                    'label' => 'Genre',
                    'rewrite' => array( 'slug' => $tax_slug ),
                    'hierarchical' => true,
                )
        );
    }
});
  • Thanks for your answer! But how could I use this as archive or link to an archive page? – Cray Nov 22 '16 at 14:37
  • OK. I've tried your solution and added the code to my functions.php. Unfortunately it's not what I need. The code adds an extra taxonomy to my already existing one. – Cray Nov 22 '16 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.