1

I created a custom taxonomy for my custom post types.

function create_states_hierarchical_taxonomy() {
  $labels = array(
    'name' => _x( 'States', 'taxonomy general name' ),
    'singular_name' => _x( 'State', 'taxonomy singular name' ),
    'search_items' =>  __( 'Search States' ),
    'all_items' => __( 'All States' ),
    'parent_item' => __( 'Parent State' ),
    'parent_item_colon' => __( 'Parent State:' ),
    'edit_item' => __( 'Edit State' ), 
    'update_item' => __( 'Update State' ),
    'add_new_item' => __( 'Add New State' ),
    'new_item_name' => __( 'New State Name' ),
    'menu_name' => __( 'States' ),
  );    

// Now register the taxonomy

  register_taxonomy('states',array('post'), array(
    'hierarchical' => true,
    'labels' => $labels,
    'show_ui' => true,
    'show_admin_column' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'states' ),
  ));

}

I have 3 custom post types. They are all similar. This is one of them.

// Speech Language Pathologists custom post
function create_pathologists() {
    $labels = array (
        'name' => 'Pathologists',
        'singular_name' => 'Pathologist',
        'add_new' => 'Add SLP',
        'all_items' => 'All SLPs',
        'add_new_item' => 'Add SLP',
        'edit_item' => 'Edit SLP',
        'new_item' => 'New SLP',
        'view_item' => 'View SLP',
        'search_item' => 'Search SLPs',
        'not_found' => 'No SLPs found',
        'not_found_in_trash' => 'No SLPs found in trash',
        'parent_item_colon' => 'Parent Item'
    );
    $args = array (
        'labels' => $labels,
        'public' => true,
        'show_in_menu' => true,
        'has_archive' => true,
        'publicly_queryable' => true,
        'query_var' => true,
        'rewrite' => array(
            'slug' => 'pathologists/%states%',
            'with_front' => false,
        ),
        'capability_type' => 'post',
        'hierarchical' => false,
        'supports' => array (
            'title',
            'editor',
            'excerpt',
            'thumbnail',
            'revisions',
        ),
        'taxonomies' => array ('states', 'post_tag'),
        'exclude_from_search' => false
    );
    register_taxonomy_for_object_type( 'states', 'create_schools' );
    register_taxonomy_for_object_type( 'post_tag', 'create_schools' );
    register_post_type('pathologists', $args);  
}
add_action( 'init', 'create_pathologists' );

I filter my permalink to have it display the taxonomy name after custom post type name and before the post name.

add_filter('post_type_link', 'pathologists_permalink_structure', 10, 4);
function pathologists_permalink_structure($post_link, $post, $leavename, $sample)
{
        $post = get_post($id);  
    if ( false !== strpos( $post_link, '%states%' ) ) {
        $state_term = get_the_terms( $post->ID, 'states' );
        $post_link = str_replace( '%states%', array_pop( $state_term )->slug, $post_link );
    }
    return $post_link;
}
flush_rewrite_rules();

So, for example, I have a post named "test" under pathologists, and "alabama" categoty. The permalink would look like this:

http://sitename/pathologists/alabama/test/

So I can access any page without any problems, but when it comes to displaying all the posts of specific custom post type by state WP uses default archive.php and displays all the posts of the specific state from all the custom post types.

use of default archive.php

I looked into the solution presented by Pieter Goosen, but anything I try, won't give me the right result.

All the possible files I tried utilize are:

  • archive-pathologists.php
  • states.php
  • alabama.php
  • states-alabama.php
  • taxonomy-states.php

taxonomy-states.php is the closest I could get so far. At least it uses the right template. But instead of showing me all the state posts from a single custom post type it shows me 3 names of the specialists I put in a custom post field for a Custom Post Type UI plugin I tried to utilized first. The plugin is deleted with all the posts and types.

use of custom template taxonomy-states.php

I, also, tried to use category_template to make my content show on the specific page I want but no success either.

I feel like the solution to a problem is super close, but I can't figure it out anymore. Please, help me.
The live version of the problem is here

  • You may need to visit the Settings >> Permalinks page after adding new custom post-types / taxonomies to get them to load on the frontend. – admcfajn Jul 19 at 5:13
  • I saw this fix somewhere, but re-setting permalinks from admin page doesn't help either. – Viacheslav Nazarenko Jul 19 at 5:48
1

The problem in your code is the lack of proper rules.

You add 'rewrite' => 'CPT/%states%' in register_post_type() arguments. This causes that the rules generated for pathologists post type begins with pathologists/%states%/ and the address pathologists/alabama/ (pathologists/{term}/) will not be matched. More importantly, all posts from the custom category are displayed regardless of the type, because the rules do not set the post type.

Here you will find similar question, the only difference is the order of elements, you have {cpt}/{term}, in the question is {term}/{ctp}.

The code below will add rewrite rules you need. When you add or remove a term of states taxonomy, the rules must be regenerate (use filters created_term, delete_{$taxonomy}).

add_action('init', 'se343186_rewrite_rules__states', 15);

function se343186_rewrite_rules__states()
{
    $cpts = ['pathologists', 'other_cpt'];
    $tax_slug = 'states';
    foreach ($cpts as $cpt)
    {
        add_rewrite_rule( '^'. $cpt. '/([^/]+)(?:/(.+?))?/page/?([0-9]{1,})/?$',
            'index.php?taxonomy='.$tax_slug.'&'.$tax_slug.'=$matches[1]&'.$cpt.'=$matches[2]&paged=$matches[3]&post_type='.$cpt,
            'top'
        );
        add_rewrite_rule( '^'. $cpt. '/([^/]+)/(.+?)(?:/([0-9]+))?/?$',
            'index.php?taxonomy='.$tax_slug.'&'.$tax_slug.'=$matches[1]&'.$cpt.'=$matches[2]&page=$matches[3]&post_type='.$cpt,
            'top'
        );
        add_rewrite_rule( '^'. $cpt. '/([^/]+)(?:/([0-9]+))?/?$',
            'index.php?taxonomy='.$tax_slug.'&'.$tax_slug.'=$matches[1]&paged=$matches[2]&post_type='.$cpt,
            'top'
        );
    }
}
  • Can I clarify a few things? You define a new variable $cpts but then use $cpt is this a typo? In $cpt you have 'alabama', but I have 50 states + Washington DC. Does it mean I need to add 50 more functions like this? Is there another way to specify a state name there as a parameter? Does 'other_cpt' needs to be replaced by the real custom post type name? I have 3 custom post types which use same taxonomy. – Viacheslav Nazarenko Jul 19 at 22:25
  • Sorry, I missed the foreach loop. Disregard my $cpt vs $cpts question – Viacheslav Nazarenko Jul 19 at 22:34
  • Never mind, I was able to figure things out. That magic spell worked as expected and I am able to display posts under cpy/category without using custom template. It just uses default archive.php. Thank you so much! – Viacheslav Nazarenko Jul 19 at 23:00
  • Sorry, in $ctps should be pathologists and the other 2 custom post types. – nmr Jul 20 at 4:55

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.