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.