While not your exact desired URL structure, you can get:
/products
» View all custom posts
/products/type/cell-phones
» View all custom posts with the taxonomy cell-phones
/products/type/cell-phones/brand/samsung
» View all custom posts where the taxonomy is cell-phones AND samsung
/brand/samsung
» View all custom posts where the taxonomy is samsung
/product/test-product-1
» View the product (single custom post)
without having to specify custom re-write rules.
It does require that you register your taxonomies and custom post types in a particular order though. The trick is to register any taxonomy where the slug begins with your post-type's slug before you register that custom post type. For example, assume the following slugs:
product_type taxonomy slug = products/type
product custom_post_type slug = product
product custom_post_type archive slug = products
product_brand taxonomy slug = brand
Then you could register them in this order:
register_taxonomy(
'products_type',
'products',
array(
'label' => 'Product Type',
'labels' => $product_type_labels,
'public' => true,
'show_ui' => true,
'show_in_nav_menus' => true,
'args' => array( 'orderby' => 'term_order' ),
'rewrite' => array( 'slug' => 'products/type', 'with_front' => false ),
'has_archive' => true,
'query_var' => true,
)
);
register_post_type('products', array(
'labels' =>$products_labels,
'singular_label' => __('Product'),
'public' => true,
'show_ui' => true,
'capability_type' => 'post',
'hierarchical' => false,
'rewrite' => array('slug' => 'product', 'with_front' => false ),
'has_archive' => 'products',
'supports' => array('title', 'editor', 'thumbnail', 'revisions','comments','excerpt'),
));
register_taxonomy(
'products_brand',
'products',
array(
'label' => 'Brand',
'labels' => $products_brand_labels,
'public' => true,
'show_ui' => true,
'show_in_nav_menus' => true,
'args' => array( 'orderby' => 'term_order' ),
'rewrite' => array( 'slug' => 'brand', 'with_front' => false ),
'has_archive' => true,
'query_var' => true,
)
);
If you absolutely have to have a URL like:
/products/type/cell-phones/brand/samsung/test-product-1
» View the product (single custom post)
Then you would require a rewrite rule something like this:
add_rewrite_rule(
'/products/type/*/brand/*/([^/]+)/?',
'index.php?pagename='product/$matches[1]',
'top' );
UPDATE
https://stackoverflow.com/questions/3861291/multiple-custom-permalink-structures-in-wordpress
Here's how you correctly re-define the single post URL.
Set re-write to false for the custom post type. (Leave the archive as is) and then after registering the taxonomies and posts, also register the following rewrite rules.
'rewrite' => false
global $wp_rewrite;
$product_structure = '/%product_type%/%brand%/%product%';
$wp_rewrite->add_rewrite_tag("%product%", '([^/]+)', "product=");
$wp_rewrite->add_permastruct('product', $product_structure, false);
Then filter post_type_link to create the desired URL structure - allowing for unset taxonomy values. Amending the code from the linked post, you'd have:
function product_permalink($permalink, $post_id, $leavename){
$post = get_post($post_id);
if( 'product' != $post->post_type )
return $permalink;
$rewritecode = array(
'%product_type%',
'%brand%',
$leavename? '' : '%postname%',
$leavename? '' : '%pagename%',
);
if('' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft'))){
if (strpos($permalink, '%product_type%') !== FALSE){
$terms = wp_get_object_terms($post->ID, 'product_type');
if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0]))
$product_type = $terms[0]->slug;
else
$product_type = 'unassigned-artist';
}
if (strpos($permalink, '%brand%') !== FALSE){
$terms = wp_get_object_terms($post->ID, 'brand');
if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0]))
$brand = $terms[0]->slug;
else
$brand = 'unassigned-brand';
}
$rewritereplace = array(
$product_type,
$brand,
$post->post_name,
$post->post_name,
);
$permalink = str_replace($rewritecode, $rewritereplace, $permalink);
}
return $permalink;
}
add_filter('post_type_link', 'product_permalink', 10, 3);
Now I just need to figure out how to re-write the brand taxonomy url without the leading brand tag, and I should match your desired URL exactly.