2

I have a custom post type called ‘sets’ and a taxonomy set up under it called ‘project’. Most of the posts under this custom post type will be assigned one project term, but not necessarily. When a project term has not been assigned, I end up with a URL such as:

example.com/sets/no-project/the-post-name

In this case, I would like it to display like this when no taxonomy is assigned:

example.com/sets/the-post-name

Here's my original code:

add_filter('post_link', 'sets_permalink', 10, 3);
add_filter('post_type_link', 'sets_permalink', 10, 3);

function sets_permalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%project%') === FALSE) return $permalink;

    // Get post
    $post = get_post($post_id);
    if (!$post) return $permalink;

    // Get taxonomy terms
    $terms = wp_get_object_terms($post->ID, 'project');   
    if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) 
    $taxonomy_slug = $terms[0]->slug;
    else $taxonomy_slug = 'no-project';

return str_replace('%project%', $taxonomy_slug, $permalink);
}  

While following the instructions from this post, I was able to I came up with this:

Updated code w/ Registered CPT & Taxonomy (Not fully working!)

// Register Taxonomy
add_action( 'init', 'create_project_taxonomies', 0 );
function create_project_taxonomies() {

$labels = array(
'name'              => _x( 'Project', 'taxonomy general name' ),
'singular_name'     => _x( 'Project', 'taxonomy singular name' ),
'search_items'      => __( 'Search Projects' ),
'all_items'         => __( 'All Projects' ),
'parent_item'       => __( 'Parent Project' ),
'parent_item_colon' => __( 'Parent Project:' ),
'edit_item'         => __( 'Edit Project' ),
'update_item'       => __( 'Update Project' ),
'add_new_item'      => __( 'Add New Project' ),
'new_item_name'     => __( 'New Project Name' ),
'menu_name'         => __( 'Projects' ),
);

$args = array(
'hierarchical'      => true,
'labels'            => $labels,
'_builtin'          => false,
'public'            => true,
'show_ui'           => true,
'with_front'        => false,
'show_admin_column' => true,
'query_var'         => true,

'rewrite'           => array( 'slug' => 'sets' ),
);

register_taxonomy( 'project', array('set'), $args );
}


// Project Permalink
add_filter('post_type_link', 'sets_permalink', 10, 3);

function sets_permalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%project%') === FALSE) return $permalink;

// Get post
$post = get_post($post_id);
if (!$post) return $permalink;

// Get taxonomy terms
$terms = wp_get_object_terms($post->ID, 'project');   
if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) 
$taxonomy_slug  = $terms[0]->slug . '/';
else $taxonomy_slug = '';

return str_replace('%project%/', $taxonomy_slug, $permalink);
} 



add_action ('init', 'custom_rewrite', 10, 0);
function custom_rewrite () {

add_rewrite_rule(  'sets/([^/]+)/?$', 'index.php?set=$matches[1]', 'top');
flush_rewrite_rules();
}



 // Custom Post Type
 add_action( 'init', 'create_post_type' );
 function create_post_type() {
 register_post_type( 'set',
 array(
   'labels' => array(
     'name' => __( 'Sets' ),
     'all_items'          => __( 'All Sets'.$plural),
     'singular_name' => __( 'Set' ),
     'edit_item'           => __( 'Edit Set' ),
   ),
   'public' => true,
   'has_archive' => 'sets',
   'can_export'          => true,
   'publicly_queryable' => true,
   'exclude_from_search' => false,
   'query_var'          => true,
   'show_in_nav_menus'   => true,
   'show_ui' => true,
   'menu_position' => 8,
   'capability_type'     => 'post',
   'heirarchical' => true,
   'menu_icon'         => 'dashicons-playlist-audio',
   'rewrite' => array('slug' => 'sets/%project%', 'with_front' => false ),
   'supports'            => array( 'title', 'thumbnail', 'editor'),
   'register_meta_box_cb' => 'set_meta_boxes',

   )
  );

    flush_rewrite_rules();
 }

The Problem

The updated code appears to work correctly. However, when trying to view a post that has no taxonomy assigned, I run into a weird problem. For example, this URL works but it returns a 404 page:

example.com/sets/the-post-name

It seems as if the actual post for the previous URL shows up at:

example.com/sets/project/the-post-name

But as stated above, I need it to display like this when no taxonomy is assigned:

example.com/sets/the-post-name

Now when I assign a taxonomy with the slug named, "groove-sessions" to the post, everything displays perfectly and the link does not show a 404 page. For example, this URL works:

example.com/sets/groove-sessions/the-post-name

Any ideas on how I can fix this issue? Like, is there a way to make it ignore the whole %project% when no taxonomy term is assigned? Thanks.

Thanks!

  • your rewrite rule should be index.php?sets=$matches[1], you're loading a sets post, not a project term. – Milo Nov 5 '15 at 18:36
  • Hey @Milo, thanks for tip. That worked fine but it seems like it has the same results. What I noticed is that with or without the rewrite rule function, (and no taxonomy is assigned of course) the URL in the address bar still shows up as example.com/sets/project/the-post-name, which is what I don't want to happen. – Marz Nov 5 '15 at 19:16
  • You see project or %project% in the URL? If the URLs are not output correctly, the issue is with your post_type_link function. Also note that you only need to filter post_type_link, not post_link, which is only for the post post type. – Milo Nov 5 '15 at 20:04
  • @Milo, project only appears in the URL when there is no taxonomy assigned. Also, I removed the post_link filter, still no luck. – Marz Nov 5 '15 at 20:26
  • well again, your post_type_link filter isn't working correctly if that's the case. I don't understand why the % delimiters would be removed either, which leads me to believe you've got other code interfering or what you have above isn't exactly what's in your live code. if you can provide a full set of code that registers your post type and taxonomy in a form I can copy and paste I can test things, but I can't otherwise reproduce your problem. – Milo Nov 5 '15 at 21:33
2

With helpful tips from Milo, I was able to remove the taxonomy slug when no taxonomy is assigned to the custom post type by adding the following code to the updated functions above:

add_filter( 'request', 'project_request_filter' );
function project_request_filter( $request ){
if( array_key_exists( 'project' , $request )
    && ! get_term_by( 'slug', $request['project'], 'project' ) ){
        $request['set'] = $request['project'];
        $request['name'] = $request['project'];
        $request['post_type'] = 'set';
        unset( $request['project'] );
}
return $request;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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