0
votes

I'm trying to set up a hierarchical taxonomy within my theme which also uses a hierarchical slug rewrite.

I have car brands as the custom taxonomy. This would list categories like Honda, Toyota etc…

Then under each brand it would be broken out by subcategory based on geography such as

Honda - Alabama - Texas Toyota - Alabama - Texas

The problem I have is that there are multiple sub-categories of the same name which exist in different main categories, but are totally independent.

Example: xyz.com/honda/alabama xyz.com/toyota/alabama-2

Wordpress appends a -2 at the end of the second category. Is there a work around to prevent the -2 in the permalink?

Or is there a better way to structure the taxomony?

My desired result is:

xyz.com/honda/alabama xyz.com/toyota/Alabama

Thank you.

2
Can you not just reorder it to xyz.com/alabama/toyota? and make state the parent? - Xhynk
I could but then when I add xyz.com/california/toyota it would be xyz.com/califorina/toyota-2/ I am trying to prevent the -2 when a sub category is repeated in multiple parent taxonomy which are clearly different. I think this ia a wordpress database issue, and I am looking for a workaround or plugin to fix. - user1609391
Could you just add Custom Fields to your posts? So pick one, state or make as the category, then add cat=STATE&meta_key=make&meta_value=toyota to your WP_Query? - Xhynk

2 Answers

0
votes

The technical answer is that you need to reorganise the categories, WordPress does not perform it, not very helpful but there you go. From a business perspective we use a (paid) plugin to allow duplicate slugs, it is something that should have been built in to WordPress but there you go.

0
votes

I am delighted to have FINALLY found a fix for this. A detailed explanation can be found here: http://www.cuberis.com/2013/07/wordpress-duplicate-slugs-for-different-post-types/.

The article basically says that it is a known issue with its own ticket, that there is a patch available, but that the patch requires editing core-files, which can be worked-around (if needed) with the following function:

function wp_cpt_unique_post_slug($slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug) {
if ( in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) )
return $slug;

global $wpdb, $wp_rewrite;

// store slug made by original function
$wp_slug = $slug;

// reset slug to original slug
$slug = $original_slug;

$feeds = $wp_rewrite->feeds;
if ( ! is_array( $feeds ) )
$feeds = array();

$hierarchical_post_types = get_post_types( array('hierarchical' => true) );
if ( 'attachment' == $post_type ) {
// Attachment slugs must be unique across all types.
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_ID ) );

if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_attachment_slug', false, $slug ) ) {
$suffix = 2;
do {
$alt_post_name = substr ($slug, 0, (200 - ( strlen( $suffix ) + 1 ) )) . "-$suffix";
$post_name_check = $wpdb->get_var( $wpdb->prepare($check_sql, $alt_post_name, $post_ID ) );
$suffix++;
} while ( $post_name_check );
$slug = $alt_post_name;
}
} elseif ( in_array( $post_type, $hierarchical_post_types ) ) {
if ( 'nav_menu_item' == $post_type )
return $slug;
// Page slugs must be unique within their own trees. Pages are in a separate
// namespace than posts so page slugs are allowed to overlap post slugs.
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d AND post_parent = %d LIMIT 1";
$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) );

if ( $post_name_check || in_array( $slug, $feeds ) || preg_match( "@^($wp_rewrite->pagination_base)?d+$@", $slug ) || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
$suffix = 2;
do {
$alt_post_name = substr( $slug, 0, (200 - ( strlen( $suffix ) + 1 ) )) . "-$suffix";
$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID, $post_parent ) );
$suffix++;
} while ( $post_name_check );
$slug = $alt_post_name;
}
} else {
// Post slugs must be unique across all posts.
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d LIMIT 1";
$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID ) );

if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
$suffix = 2;
do {
$alt_post_name = substr( $slug, 0, (200 - ( strlen( $suffix ) + 1 ) )) . "-$suffix";
$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID ) );
$suffix++;
} while ( $post_name_check );
$slug = $alt_post_name;
}
}

return $slug;
}
add_filter('wp_unique_post_slug', 'wp_cpt_unique_post_slug', 10, 6);

The function should be included in your theme's functions.php file.