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.

I've tried plugins, read through stack and spent hours on this, and I just can't seem to find a way to achieve what I want.

I can achieve the following permalink structure:

custom-post-type/taxonomy-term/post-title

for example, our-work/interactive/some-project-title

which also allows our-work/interactive to correctly display all our-work posts with the taxonomy term interactive, but I can no longer get the archive page our-work to work, here is the code I'm using to achieve the above

function my_custom_post_work() {
    $labels = array(
        'name'               => _x( 'Work', 'post type general name' ),
        'singular_name'      => _x( 'Work', 'post type singular name' ),
        'add_new'            => _x( 'Add New', 'book' ),
        'add_new_item'       => __( 'Add New Work' ),
        'edit_item'          => __( 'Edit Work' ),
        'new_item'           => __( 'New Work' ),
        'all_items'          => __( 'All Work' ),
        'view_item'          => __( 'View Work' ),
        'search_items'       => __( 'Search Work' ),
        'not_found'          => __( 'No work found' ),
        'not_found_in_trash' => __( 'No work found in the Trash' ), 
        'parent_item_colon'  => '',
        'menu_name'          => 'Our Work'
    );
    $args = array(
        'labels'        => $labels,
        'description'   => 'Holds our works and work specific data',
        'public'        => true,
        'menu_position' => 5,
        'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
        'has_archive'   => true,
        'rewrite'       => array( 'slug' => 'our-work/%work_category%')
    );
    register_post_type( 'work', $args );    
}
add_action( 'init', 'my_custom_post_work' );

function mav_taxonomies_work() {
    $labels = array(
        'name'              => _x( 'Work Categories', 'taxonomy general name' ),
        'singular_name'     => _x( 'Work Category', 'taxonomy singular name' ),
        'search_items'      => __( 'Search Work Categories' ),
        'all_items'         => __( 'All Work Categories' ),
        'parent_item'       => __( 'Parent Work Category' ),
        'parent_item_colon' => __( 'Parent Work Category:' ),
        'edit_item'         => __( 'Edit Work Category' ), 
        'update_item'       => __( 'Update Work Category' ),
        'add_new_item'      => __( 'Add New Work Category' ),
        'new_item_name'     => __( 'New Work Category' ),
        'menu_name'         => __( 'Work Categories' ),
    );
    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'has_archive'   => true,
    );
    register_taxonomy( 'work_category', 'work', $args );
}
add_action( 'init', 'mav_taxonomies_work', 0 );

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

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

    return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);

Ideally I'd like the following to work:

  • /our-work/ => display all custom posts
  • /our-work/taxonomy-term/ => display all posts with that term selected
  • /our-work/taxonomy-term/post-title/ => the permalink whenever a specific post is clicked.

Is there a better way / a way to do this?

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

Replace your code with the following.
I have made some changes to the post_type_link filter's callback function.

function my_custom_post_work() {
    $labels = array(
        'name'               => _x( 'Work', 'post type general name' ),
        'singular_name'      => _x( 'Work', 'post type singular name' ),
        'add_new'            => _x( 'Add New', 'book' ),
        'add_new_item'       => __( 'Add New Work' ),
        'edit_item'          => __( 'Edit Work' ),
        'new_item'           => __( 'New Work' ),
        'all_items'          => __( 'All Work' ),
        'view_item'          => __( 'View Work' ),
        'search_items'       => __( 'Search Work' ),
        'not_found'          => __( 'No work found' ),
        'not_found_in_trash' => __( 'No work found in the Trash' ), 
        'parent_item_colon'  => '',
        'menu_name'          => 'Our Work'
    );
$args = array(
        'labels'        => $labels,
        'description'   => 'Holds our works and work specific data',
        'public'        => true,
        'menu_position' => 5,
        'supports'      => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
        'has_archive'   => true,
        'rewrite'       => array( 'slug' => 'our-work/%work_category%')
    );
    register_post_type( 'work', $args );    
}
add_action( 'init', 'my_custom_post_work' );

function mav_taxonomies_work() {
    $labels = array(
        'name'              => _x( 'Work Categories', 'taxonomy general name' ),
        'singular_name'     => _x( 'Work Category', 'taxonomy singular name' ),
        'search_items'      => __( 'Search Work Categories' ),
        'all_items'         => __( 'All Work Categories' ),
        'parent_item'       => __( 'Parent Work Category' ),
        'parent_item_colon' => __( 'Parent Work Category:' ),
        'edit_item'         => __( 'Edit Work Category' ), 
        'update_item'       => __( 'Update Work Category' ),
        'add_new_item'      => __( 'Add New Work Category' ),
        'new_item_name'     => __( 'New Work Category' ),
        'menu_name'         => __( 'Work Categories' ),
    );
    $args = array(
        'labels' => $labels,
        'hierarchical' => true,
        'has_archive'   => true,
    );
    register_taxonomy( 'work_category', 'work', $args );
}
add_action( 'init', 'mav_taxonomies_work', 0 );
add_filter('post_type_link', 'filter_post_type_link', 10, 2);    
function filter_post_type_link( $post_link, $id = 0, $leavename = FALSE ) {
    if ( strpos('%work_category%', $post_link) === 'FALSE' ) {
      return $post_link;
    }
    $post = get_post($id);
    if ( !is_object($post) || $post->post_type != 'work' ) {
      return $post_link;
    }
    $terms = wp_get_object_terms($post->ID, 'work_category');
    if ( !$terms ) {
      return str_replace('our-work/%work_category%/', '', $post_link);
    }
    return str_replace('%work_category%', $terms[0]->slug, $post_link);
}

Also, you will have to write rewrite rules for your custom post type for your proposed URI structure to work.

Add the below code to your theme's functions.php file:

add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
add_action( 'wp_loaded','my_flush_rules' );    
function my_flush_rules(){
    $rules = get_option( 'rewrite_rules' );
            global $wp_rewrite;
    $wp_rewrite->flush_rules();
} 

// Adding a new rule    
function my_insert_rewrite_rules( $rules )    
{
    $newrules = array();
    $newrules['our-work/?$'] = 'index.php?post_type=work';
    $newrules['our-work/page/?([0-9]{1,})/?$'] = 'index.php?post_type=work&paged=$matches[1]';
    $newrules['our-work/(.+?)/page/?([0-9]{1,})/?$'] = 'index.php?post_type=work&work_category=$matches[1]&paged=$matches[2]';
    //print_r($rules);
    return $newrules + $rules;
}
share|improve this answer
    
:O! AMAZING. THANK YOU. –  Joshua Richards Apr 17 '13 at 12:58
    
@Joshua Richards You are most welcome –  Dipali Dhole Apr 17 '13 at 15:57
add comment

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.