WooCommerce- How to remove product & product-category from urls? (ok) https://stackoverflow.com/questions/43447175/woocommerce-how-to-remove-product-product-category-from-urls
Copy // Remove slug product-category
add_filter ( 'request' , function ( $vars ) {
global $wpdb;
if( ! empty( $vars['pagename'] ) || ! empty( $vars['category_name'] ) || ! empty( $vars['name'] ) || ! empty( $vars['attachment'] ) ) {
$slug = ! empty( $vars['pagename'] ) ? $vars['pagename'] : ( ! empty( $vars['name'] ) ? $vars['name'] : ( !empty( $vars['category_name'] ) ? $vars['category_name'] : $vars['attachment'] ) );
$exists = $wpdb->get_var( $wpdb->prepare( "SELECT t.term_id FROM $wpdb->terms t LEFT JOIN $wpdb->term_taxonomy tt ON tt.term_id = t.term_id WHERE tt.taxonomy = 'product_cat' AND t.slug = %s" ,array( $slug )));
if ( $exists ){
$old_vars = $vars;
$vars = array( 'product_cat' => $slug );
if ( !empty( $old_vars['paged'] ) || !empty( $old_vars['page'] ) ) $vars['paged'] = ! empty( $old_vars['paged'] ) ? $old_vars['paged'] : $old_vars['page'];
if ( ! empty ( $old_vars[ 'orderby' ] ) ) $vars[ 'orderby' ] = $old_vars[ 'orderby' ];
if ( ! empty ( $old_vars[ 'order' ] ) ) $vars[ 'order' ] = $old_vars[ 'order' ];
}
}
return $vars;
} ) ;
Ask Question Asked 5 years, 6 months agoModified 1 year, 1 month ago Viewed 78k times9
I'm using WooCommerce on a WordPress and it adds product & product-category to the
URLs.
http://dev.unwaveringmedia.com/8dim/product-category/all-party-supplies/ http://dev.unwaveringmedia.com/8dim/product/14-snowman-serving-tray/
I need to remove 'product' & 'product-category' from the URLs. Is there any way to modify the permalinks and remove them?
you should use of woocommerce seo perfect plugin because it's good for seo and create best url for you I use most way to remove category but I saw there are dot in canonical so i decided to use this plugin cheers – amh Sep 6, 2020 at 14:05
Add a comment
6 Answers
Sorted by: Highest score (default) Trending (recent votes count more) Date modified (newest first) Date created (oldest first) 23
Yes. But Please read this article first https://docs.woocommerce.com/document/removing-product-product-category-or-shop-from-the-urls/
You can change this by:
you can change the permalinks in Settings > permalink > optional > Product category base= ./ (type ./ in Product category base).
Be sure that you don’t have any page, post or attachment with the same name (slug) as the category page or they will collide and the code won’t work.
`
Copy <? php
/*
Plugin Name: Remove product-category slug
Plugin URI: https://timersys.com/
Description: Check if url slug matches a woocommerce product category and use it instead
Version: 0.1
Author: Timersys
License: GPLv2 or later
*/
add_filter ( 'request' , function ( $vars ) {
global $wpdb;
if( ! empty( $vars['pagename'] ) || ! empty( $vars['category_name'] ) || ! empty( $vars['name'] ) || ! empty( $vars['attachment'] ) ) {
$slug = ! empty( $vars['pagename'] ) ? $vars['pagename'] : ( ! empty( $vars['name'] ) ? $vars['name'] : ( !empty( $vars['category_name'] ) ? $vars['category_name'] : $vars['attachment'] ) );
$exists = $wpdb->get_var( $wpdb->prepare( "SELECT t.term_id FROM $wpdb->terms t LEFT JOIN $wpdb->term_taxonomy tt ON tt.term_id = t.term_id WHERE tt.taxonomy = 'product_cat' AND t.slug = %s" ,array( $slug )));
if ( $exists ){
$old_vars = $vars;
$vars = array( 'product_cat' => $slug );
if ( ! empty ( $old_vars[ 'paged' ] ) || ! empty ( $old_vars[ 'page' ] ) )
$vars[ 'paged' ] = ! empty ( $old_vars[ 'paged' ] ) ? $old_vars[ 'paged' ] : $old_vars[ 'page' ];
if ( ! empty ( $old_vars[ 'orderby' ] ) )
$vars[ 'orderby' ] = $old_vars[ 'orderby' ];
if ( ! empty ( $old_vars[ 'order' ] ) )
$vars[ 'order' ] = $old_vars[ 'order' ];
}
}
return $vars;
} ) ; `
For more info please see https://timersys.com/remove-product-category-slug-woocommerce/
Add a comment Report this ad3
Noone mentioned how to remove /product/ so here it goes:
Copy function na_remove_slug ( $post_link , $post , $leavename ) {
if ( 'product' != $post -> post_type || 'publish' != $post -> post_status ) {
return $post_link;
}
$post_link = str_replace ( '/product/' , '/' , $post_link ) ;
return $post_link;
}
add_filter ( 'post_type_link' , 'na_remove_slug' , 10 , 3 ) ;
function change_slug_struct ( $query ) {
if ( ! $query -> is_main_query () || 2 != count ( $query -> query ) || ! isset ( $query -> query[ 'page' ] ) ) {
return ;
}
if ( ! empty ( $query -> query[ 'name' ] ) ) {
$query -> set ( 'post_type' , array ( 'post' , 'product' , 'page' ) ) ;
} elseif ( ! empty ( $query -> query[ 'pagename' ] ) && false === strpos ( $query -> query[ 'pagename' ] , '/' ) ) {
$query -> set ( 'post_type' , array ( 'post' , 'product' , 'page' ) ) ;
// We also need to set the name query var since redirect_guess_404_permalink() relies on it.
$query -> set ( 'name' , $query -> query[ 'pagename' ] ) ;
}
}
add_action ( 'pre_get_posts' , 'change_slug_struct' , 99 ) ;
I've added priority since some themes/plugins can conflict with this rule, which happened to me.
This is a simple solution but it doesn't work if there is %product_cat% in the product base and there are multiple categories in the URL, for example: /parent-cat/child-cat/product-slug/ – Hasan Akhtar Oct 23, 2021 at 7:30
Add a comment 2
It wasn't working with pagination for me. Here is full code that's working.
Copy add_filter ( 'request' , function ( $vars ) {
global $wpdb;
if( ! empty( $vars['pagename'] ) || ! empty( $vars['category_name'] ) || ! empty( $vars['name'] ) || ! empty( $vars['attachment'] ) ) {
$slug = ! empty( $vars['pagename'] ) ? $vars['pagename'] : ( ! empty( $vars['name'] ) ? $vars['name'] : ( !empty( $vars['category_name'] ) ? $vars['category_name'] : $vars['attachment'] ) );
$exists = $wpdb->get_var( $wpdb->prepare( "SELECT t.term_id FROM $wpdb->terms t LEFT JOIN $wpdb->term_taxonomy tt ON tt.term_id = t.term_id WHERE tt.taxonomy = 'product_cat' AND t.slug = %s" ,array( $slug )));
if ( $exists ){
$old_vars = $vars;
$vars = array( 'product_cat' => $slug );
if ( ! empty ( $old_vars[ 'paged' ] ) || ! empty ( $old_vars[ 'page' ] ) )
$vars[ 'paged' ] = ! empty ( $old_vars[ 'paged' ] ) ? $old_vars[ 'paged' ] : $old_vars[ 'page' ];
if ( ! empty ( $old_vars[ 'orderby' ] ) )
$vars[ 'orderby' ] = $old_vars[ 'orderby' ];
if ( ! empty ( $old_vars[ 'order' ] ) )
$vars[ 'order' ] = $old_vars[ 'order' ];
}
}
return $vars;
} ) ;
This will add new rewrite rule that will paginate query.
Copy add_action ( 'init' , 'do_rewrite' ) ;
function do_rewrite (){
add_rewrite_rule ( '[^/]+/([^/]+)/page/?([0-9]{1,})/?$' , 'index.php?attachment=$matches[1]&paged=$matches[2]' , 'top' ) ;
add_filter ( 'query_vars' , function ( $vars ){
$vars[] = 'attachment' ;
$vars[] = 'paged' ;
return $vars;
} ) ;}
Using Shehroz Altaf's trick does the job just (almost) perfectly.
Adding the following between the $slug
and $exists
declarations will make it work with sub-categories too.
Copy $slug_array = explode ( '/' , $slug ) ;
$slug = array_values ( array_slice ( $slug_array , - 1 )) [ 0 ];
You can use the following filter: woocommerce_register_post_type_product
Here is an example if you only want to remove /product/ but keep the category.
Copy add_filter ( 'woocommerce_register_post_type_product' , function ($var) {
$var[ 'rewrite' ] = str_replace ( '/product/' , '/' , $var[ 'rewrite' ] ) ;
return $var;
} ) ;
Then make sure to flush the permalinks by updating the permalinks in the Admin panel.
Keep in mind you will still see '/product/' in the permalink structure in the Admin Panel Permalinks, but it will not have an affect.
Add a comment 0
Other solutions all failed for me, after some trial and error I came up with this solution...
Set Product Category Base Permalinks to : shop
Set Custom Base Permalinks to : /shop/%product_cat%/
URLs will then look like
Copy http: //www.example.com/shop/category/sub-category/product
Seems to work fine for pagination and sub categories
Last updated 11 months ago