How to remove taxonomy slug from custom post type url?

19.1k views Asked by At

I have a custom post type(product) with taxonomy product-type. One of my url like this:
http://www.naturesbioscience.com/product-type/immune-support-supplements/
I want this like:
http://www.naturesbioscience.com/immune-support-supplements/

I have used "rewrite" => array('slug' => '/ ', 'with_front' => false in register_taxonomy function and I got the url like:
http://www.naturesbioscience.com/immune-support-supplements/
But I got 404 not found in other pages.

Anyone can help me?

3

There are 3 answers

1
Raunak Gupta On

I think you forgot to rewrite custom taxonomy post slug.
Write this in your register_post_type methord.

'rewrite' => array('slug' => 'product-type')

Now you have to remove product-type slug from your custom products

/**
 * Remove the slug from published post permalinks.
 */
function custom_remove_cpt_slug($post_link, $post, $leavename)
{
    if ('product-type' != $post->post_type || 'publish' != $post->post_status)
    {
        return $post_link;
    }
    $post_link = str_replace('/' . $post->post_type . '/', '/', $post_link);

    return $post_link;
}

add_filter('post_type_link', 'custom_remove_cpt_slug', 10, 3);

Now as you have removed the custom post type slug so WordPress will try to match it with page or post so you have tell WP to check the URL in you custom post type also. So use this for that:

function custom_parse_request_tricksy($query)
{
    // Only noop the main query
    if (!$query->is_main_query())
        return;

    // Only noop our very specific rewrite rule match
    if (2 != count($query->query) || !isset($query->query['page']))
    {
        return;
    }

    // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
    if (!empty($query->query['name']))
    {
        $query->set('post_type', array('post', 'product-type', 'page'));
    }
}

add_action('pre_get_posts', 'custom_parse_request_tricksy');

Reference: Remove The Slugs from Custom Post Type URL

Hope this helps!

0
Ali Raza On
add_filter( 'post_type_link', 'change_product_request', 10, 3 );

function change_product_request( $post_link, $post, $leavename ) {

        if ( 'product' != $post->post_type || 'publish' != $post->post_status ) {
            return $post_link;
        }

        $post_link = str_replace( "/{$post->post_type}/" , '/', $post_link );

        return $post_link;
}

Now, you'll get a 404 page because WordPress only allow posts and pages to behave in this way. You'll also have to add the following:

add_action( 'pre_get_posts', 'product_permalink' );

function product_permalink( $query ) {

    if ( ! $query->is_main_query() ) {
            return;
        }
        if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
            return;
        }

        if ( ! empty( $query->query['pagename'] ) ) { // name has been updated to pagename so  $query->query['pagename']

            global $wpdb;
            $pt = $wpdb->get_var(
                "SELECT post_type FROM `{$wpdb->posts}` " .
                "WHERE post_name = '{$query->query['pagename']}'"
            );
            $query->set( 'post_type', $pt );
        }

        return $query;
}
2
Annapurna On

I had similar issue. The question is quite old, but anyone looking for apt answer can see this.

Do not pass "/" for rewrite slug, since it causes more problem than it solves, as in this case, causing 404 error in other pages.

First, we need to remove the slug from the URL for the published post. Paste the code in functions.php

/**
 * Remove the slug from published post permalinks. Only affect our CPT though.
 */
function sh_remove_cpt_slug( $post_link, $post, $leavename ) {

    if ( in_array( $post->post_type, array( 'product-type' ) )
        || 'publish' == $post->post_status )
        $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
    return $post_link;
}
add_filter( 'post_type_link', 'sh_remove_cpt_slug', 10, 3 );

This will still cause error since it specifies that only 'post' and 'page' post types can have url without post-type slug.

Now to teach WP that out CPT will also have URL without slug, we need to get this in our functions.php

function sh_parse_request_tricksy( $query ) {

    // Only loop the main query
    if ( ! $query->is_main_query() ) {
        return;
    }

    // Only loop our very specific rewrite rule match
    if ( 2 != count( $query->query )
        || ! isset( $query->query['page'] ) )
        return;

    // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'product-type' ) );
    }
}
add_action( 'pre_get_posts', 'sh_parse_request_tricksy' );

This is it. Ref: https://wordpress.stackexchange.com/a/320711/98322