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 . "https://wordpress.stackexchange.com/";
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!

1 Answer
1

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;
}

Leave a Reply

Your email address will not be published. Required fields are marked *