Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

What I want to achieve is an online listing catalog with a URL like this:

www.example.com/drawing-tools/brand/type/material/color/

In this example, I have a custom post type named "drawing-tools" with 4 custom taxonomies for it: "brand", "type", "material", "color"

When a user access a URL like:

www.example.com/drawing-tools/rotring/mechanical-pencil/plastic/black/

it gets all the items that match those criteria.

The tricky part is that all of the taxonomies are required to be in a URL. So something like this:

www.example.com/drawing-tools/plastic/black/

would simply return an 404 error page.

So my main question is:

How exactly can I have all of the taxonomies in the URL in that form and return an 404 error page if one taxonomy is missing?

I was thinking to write a rewrite rule that would take those uri segments and pass them as arguments to a query based on the 'Query Multiple Taxonomies' plugin and return that 404 error if one segment is missing. But I don't know how to accomplish this. Is there any solutions that you can give me?

[Update 1]

The rewrite rule would basically take this URL:

www.example.com/drawing-tools/rotring/mechanical-pencil/plastic/black/

and make it into:

www.example.com/?drawing-tools_name=rotring+mechanical-pencil+plastic+black

The above structure is required by the 'Query Multiple Taxonomies' plugin.

[Update 2]

I've given up to the Query Multiple Taxonomies plugin and instead I've switched to WP 3.1. Now, with the help from this previous question I've managed to get to work those taxonomies like I wanted.

Here is the full code:

register_post_type('drawing-tools', array(
    'labels' => array(
            'name' => __( 'Drawing Tools' ),
            'singular_name' => __( 'Drawing Tool' ),
            'add_new' => __( 'Add New' ),
            'add_new_item' => __( 'Add New Drawing Tool' ),
            'edit' => __( 'Edit' ),
            'edit_item' => __( 'Edit Drawing Tool' ),
            'new_item' => __( 'New Drawing Tool' ),
            'view' => __( 'View Drawing Tools' ),
            'view_item' => __( 'View Drawing Tool' ),
            'search_items' => __( 'Search Drawing Tools' ),
            'not_found' => __( 'No items found' ),
            'not_found_in_trash' => __( 'No items found in trash' ),
            'parent' => __( 'Parent Drawing Tool' ),
            ),
    'public' => true,
    'publicly_queryable' => false,
    'show_in_nav_menus' => false,
    'exclude_from_search' => false,
    'show_ui' => true,
    '_builtin' => false,
    '_edit_link' => 'post.php?post=%d',
    'capability_type' => 'post',
    'hierarchical' => false,
    'rewrite' => array("slug" => "drawing-tools/%brand%/%type%/%material%/%color%"), // Permalinks format
    'has_archive' => false,
    'menu_position' => 5,
    'supports' => array('author')
));

  register_taxonomy('brand',array('drawing-tools'), array(
    'hierarchical' => false,
    'labels' => array(
        'name' => _x( 'Brands', 'taxonomy general name' ),
        'singular_name' => _x( 'Brand', 'taxonomy singular name' ),
        'search_items' =>  __( 'Search Brands' ),
        'all_items' => __( 'All Brands' ),
        'parent_item' => __( 'Parent Brand' ),
        'parent_item_colon' => __( 'Parent Brand:' ),
        'edit_item' => __( 'Edit Brands' ), 
        'update_item' => __( 'Update Brand' ),
        'add_new_item' => __( 'Add New Brand' ),
        'new_item_name' => __( 'New Unit Brand' ),
        'menu_name' => __( 'Brands' ),
                ),
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'drawing-tools' ),
  ));

  register_taxonomy('type',array('drawing-tools'), array(
    'hierarchical' => false,
    'labels' => array(
        'name' => _x( 'Types', 'taxonomy general name' ),
        'singular_name' => _x( 'Type', 'taxonomy singular name' ),
        'search_items' =>  __( 'Search Types' ),
        'all_items' => __( 'All Types' ),
        'parent_item' => __( 'Parent Type' ),
        'parent_item_colon' => __( 'Parent Type:' ),
        'edit_item' => __( 'Edit Types' ), 
        'update_item' => __( 'Update Type' ),
        'add_new_item' => __( 'Add New Type' ),
        'new_item_name' => __( 'New Type' ),
        'menu_name' => __( 'Types' ),
                ),
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'drawing-tools/%brand%' ),
  ));

 register_taxonomy('material',array('drawing-tools'), array(
    'hierarchical' => false,
    'labels' => array(
        'name' => _x( 'Materials', 'taxonomy general name' ),
            'singular_name' => _x( 'Material', 'taxonomy singular name' ),
        'search_items' =>  __( 'Search Materials' ),
        'all_items' => __( 'All Materials' ),
        'parent_item' => __( 'Parent Material' ),
        'parent_item_colon' => __( 'Parent Material:' ),
        'edit_item' => __( 'Edit Material' ), 
        'update_item' => __( 'Update Material' ),
        'add_new_item' => __( 'Add New Material' ),
        'new_item_name' => __( 'New Material Name' ),
        'menu_name' => __( 'Materials' ),
                ),
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'drawing-tools/%brand%/%type%' ),
  ));

 register_taxonomy('color',array('drawing-tools'), array(
    'hierarchical' => false,
    'labels' => array(
        'name' => _x( 'Colors', 'taxonomy general name' ),
        'singular_name' => _x( 'Color', 'taxonomy singular name' ),
        'search_items' =>  __( 'Search Colors' ),
        'all_items' => __( 'All Colors' ),
        'parent_item' => __( 'Parent Color' ),
        'parent_item_colon' => __( 'Parent Color:' ),
        'edit_item' => __( 'Edit Color' ), 
        'update_item' => __( 'Update Color' ),
        'add_new_item' => __( 'Add New Color' ),
        'new_item_name' => __( 'New Color Name' ),
        'menu_name' => __( 'Colors' ),
                ),
    'show_ui' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'drawing-tools/%brand%/%type%/%material%' ),
  ));  


function filter_post_type_link($link, $post)
{
    if ($post->post_type != 'drawing-tools')
        return $link;

    if ($cats = get_the_terms($post->ID, 'brand'))
        $link = str_replace('%brand%', array_pop($cats)->slug, $link);

    if ($cats = get_the_terms($post->ID, 'type'))
        $link = str_replace('%type%', array_pop($cats)->slug, $link);

    if ($cats = get_the_terms($post->ID, 'material'))
        $link = str_replace('%material%', array_pop($cats)->slug, $link);

    if ($cats = get_the_terms($post->ID, 'color'))
        $link = str_replace('%color%', array_pop($cats)->slug, $link);      
    return $link;
}

add_filter('post_type_link', 'filter_post_type_link', 10, 2);

Now, when a user access the link:

www.example.com/drawing-tools/rotring/mechanical-pencil/plastic/black/

everything works as expected. The problem is that the user can also access a partial structure like this

www.example.com/drawing-tools/rotring/

and still get results according to those taxonomies.

How can I restrict a user from accessing such a URL and instead returning a 404 error message?

share|improve this question
    
can you have taxonmy term page using drawing-tools/%brand%/%type% as slug for example? it's not working for me... i get drawing-tools/%brand%/%type%/my-term-name and it gives a blank page –  yeahman May 9 at 20:54

2 Answers 2

I believe WP 3.1 introduced a fix for what you're describing... from the codex:

  • Custom Content Type Improvements - allows developers to generate archive pages, and have better menu and capability controls. Read more in the article Post Types.
  • Advanced Queries - allows developers to query multiple taxonomies and custom fields

I haven't used either of these improvements yet so I can't comment specifically, but it seems like that's what you're looking for. Good luck!

share|improve this answer
    
I've moved to version 3.1 and indeed it works but it doesn't fit the 404 criteria, specifically that I want users to be able to use all of the taxonomies at once and not separated. Right now a user can access www.example.com/drawing-tools/rotring/ and have a list of all items that match that taxonomy but I want him to only be able to access the structure with all of the taxonomies: www.example.com/drawing-tools/rotring/mechanical-pencil/plastic/black/. How can I return a 404 when he wants to access a partial taxonomy structure? –  Jaquis Mar 10 '11 at 10:26
up vote 1 down vote accepted

The solution is fairly simple and I don't know why it took me so long to find it on the Codex. You must make use of the $wp_query class.

So, in the template, before calling the loop, set a variable to hold the returned data:

$vars = $wp_query->query_vars;

And then, check if the required taxonomies are set:

if ( isset( $vars['brand']) && isset( $vars['type'] ) && isset( $vars['material'] ) && isset( $vars['size'] ) )

If they are continue with the loop. If not:

global $wp_query; 
status_header('404');
$wp_query->set_404();

I wonder, though, if this is the most optimum solution.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.