I've got a custom post type with hierarchical taxonomies. The permalink structure is as follows:
www.mysite.com/post_type/taxonomy_term -> works (tax archive page)
www.mysite.com/post_type/taxonomy_term/post_name -> works (post page)
www.mysite.com/post_type/taxonomy_term/taxonomy_sub_term -> 404 error (sub tax archive page)
www.mysite.com/post_type/taxonomy_term/taxonomy_sub_term/post_name -> works (post page)
Custom post type function with the important settings (output from CPT UI):
$args = array(
"has_archive" => true,
"hierarchical" => false,
"rewrite" => array(
"slug" => "diensten",
"with_front" => false
),
"taxonomies" => array( "dienst_categorie" ),
);
register_post_type( "diensten", $args );
Taxonomy function with the important settings (output from CPT UI):
$args = array(
"hierarchical" => true,
"rewrite" => array(
'slug' => 'diensten',
'with_front' => false,
'hierarchical' => true,
),
);
register_taxonomy( "dienst_categorie", array( "diensten" ), $args );
With some custom code based on this website I've come to the following code:
function resources_cpt_generating_rule( $wp_rewrite ) {
$rules = array();
$post_type_diensten = 'diensten';
$terms_diensten = get_terms( array(
'taxonomy' => 'dienst_categorie',
'hide_empty' => false,
) );
foreach ( $terms_diensten as $term ) {
if ( $term->parent > 0 ) {
$pterm = get_term( $term->parent, 'dienst_categorie' );
// The line below doesn't work as expected.
$rules[ 'diensten/' . $pterm->slug . '/' . $term->slug . '/?$' ] = 'index.php?taxonomy=dienst_categorie&term=' . $term->slug;
$rules[ 'diensten/' . $pterm->slug . '/' . $term->slug . '/([^(/)]*)$' ] = 'index.php?post_type=' . $$post_type_diensten . '&' . $post_type_diensten . '=$matches[1]&name=$matches[1]';
} else {
$rules[ 'diensten/' . $term->slug . '/([^/]*)$' ] = 'index.php?post_type=' . $post_type_diensten . '&' . $post_type_diensten . '=$matches[1]&name=$matches[1]';
}
// This line works, but is not dynamic.
$rules[ 'diensten/zonwering/zonweringreparaties/?$' ] = 'index.php?taxonomy=dienst_categorie&term=zonweringreparaties';
}
}
add_filter( 'generate_rewrite_rules', 'resources_cpt_generating_rule' );
function change_link( $permalink, $post ) {
if ( 'diensten' === $post->post_type ) {
$resource_terms = get_the_terms( $post, 'dienst_categorie' );
if ( ! empty( $resource_terms ) ) {
foreach ( $resource_terms as $term ) {
if ( 'featured' === $term->slug ) {
continue;
}
if ( $term->parent > 0 ) {
$pterm = get_term( $term->parent );
$permalink = get_home_url() . '/diensten/' . $pterm->slug . '/' . $term->slug . '/' . $post->post_name;
} else {
$permalink = get_home_url() . '/diensten/' . $term->slug . '/' . $post->post_name;
}
break;
}
}
return $permalink;
}
}
add_filter( 'post_type_link', 'change_link', 10, 2 );
Notice the commented lines. One is hardcoded and the other is dynamic, and based on tests in a template the dynamic one puts out the same code as the hardcoded one, but it doesn't work. I suspect this has something to do with the regex patterns, but I'm unable to figure out why.
My question is: what is the correct rewrite rule to be able to access the archive page of a sub term based on the term/subterm url hierarchy?