I have the following setup:
- A custom post type called Products.
- A custom taxonomy called Product Categories.
- A page called Products with a custom page template assigned to it. This page template allows me to query my custom posts and display them in a layout of my choosing. Slug is set to /products.
I wanted my urls for my products to display in the following way:
/products/product-category/child-product-category/product-name.
Or to be more specific:
- View my “Products” page set with the custom template at the url /products
- View each “Product Category” on a url of /products/product-category
- View my custom post type “Products” on a url of /products/product-category/product-name
But nothings ever easy. The trouble I was having was that both my product page and product post type wanted to use the same slug (/products) and therefore conflicted causing 404′s. Not only that but custom taxonomies by default do not show the category in the url, and finally although in my head it made sense as a user to see the url /products/product-category/product-name they were not in any kind of heirarchical structure within wordpress to order them in a url this way.
So after a lot of googling and after finding this really helpful article I finally managed to put together some code that fixed the problem.
add_action( 'init', 'register_custom_post_types' );
//Set up Product Post Type
function register_custom_post_types() {
register_post_type('products', array(
'label' => __('Products'),
'singular_label' => __('Product'),
'public' => true,
'show_ui' => true,
'capability_type' => 'post',
'hierarchical' => true,
'rewrite' => array( 'slug' => 'products/%productcats%' ),
'publicly_queryable' => true,
'query_var' => true,
'has_archive' => true,
'supports' => array('title','editor','thumbnail','excerpt'),
));
//Set up Product Categories
register_taxonomy('productcats', 'products', array(
'hierarchical' => true,
'label' => 'Categories',
'singular_label' => 'Category',
'rewrite' => array( 'slug' => 'products' ),
));
}
//Fix Permalinks
add_filter('post_link', 'product_permalink', 10, 3);
add_filter('post_type_link', 'product_permalink', 10, 3);
function product_permalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%productcats%') === FALSE) return $permalink;
// Posts
$post = get_post($post_id);
if (!$post) return $permalink;
// Custom Taxonomy
$terms = wp_get_object_terms($post->ID, 'productcats');
if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
else $taxonomy_slug = 'uncategorized';
return str_replace('%productcats%', $taxonomy_slug, $permalink);
}
//Flush permalinks
flush_rewrite_rules( false );For a step by step explanation of the permalink function please refer to the original article I found on google. You may find you need to go to settings/permalinks in your admin and save again for the changes to take effect. You will already need to have the custom permalink structure set to /%postname%. More information on setting up custom page templates, custom post types and custom taxonomies can be found on the wordpress codex.











