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?
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.
Install and activate the plugin below:
(For more info please see https://timersys.com/remove-product-category-slug-woocommerce/)
`
<?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/
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.
$slug_array = explode( '/', $slug );
$slug = array_values(array_slice($slug_array, -1))[0];
Other solutions all failed for me, after some trial and error I came up with this solution...
- Install free 'WOO CATEGORY BASE PERMALINK FIXER' plugin from https://masterns-studio.com/code-factory/wordpress-plugin/woo-category-base/
- Set Product Category Base Permalinks to : shop
- Set Custom Base Permalinks to : /shop/%product_cat%/
URLs will then look like
http://www.example.com/shop/category/sub-category/product
Seems to work fine for pagination and sub categories
It wasn't working with pagination for me. Here is full code that's working.
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.
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;
} );}