Reputation: 125
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?
Upvotes: 6
Views: 19434
Reputation: 549
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
Upvotes: 0
Reputation: 943
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;
}
Upvotes: 0
Reputation: 10809
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!
Upvotes: 5