Archives: Snippets | Page 19

Change the Breadcrumb Delimiter in WooCommerce

To change the breadcrumb delimiter in WooCommerce, filter the delimiter key of woocommerce_breadcrumb_defaults. By default WooCommerce prints a slash with a non-breaking space on each side.

For every other argument (wrap_before, wrap_after, before, after and home) with real examples, see Customize WooCommerce Breadcrumbs.

Replace the Breadcrumb Delimiter

Add this to your child theme’s functions.php file or to a small custom plugin:

/**
 * Replace the WooCommerce breadcrumb delimiter with a vertical bar.
 */
function savvy_wc_breadcrumb_delimiter( $defaults ) {
    $defaults['delimiter'] = ' | ';
    return $defaults;
}
add_filter( 'woocommerce_breadcrumb_defaults', 'savvy_wc_breadcrumb_delimiter', 20 );

A product breadcrumb now reads Home | Clothing | T-Shirt instead of Home / Clothing / T-Shirt.

How It Works

The function woocommerce_breadcrumb() builds an array of defaults and passes it through the woocommerce_breadcrumb_defaults filter. The template global/breadcrumb.php then echoes the delimiter between crumbs, but not after the last one.

These are the defaults in current WooCommerce source (includes/wc-template-functions.php):

array(
    'delimiter'   => ' / ',
    'wrap_before' => '<nav class="woocommerce-breadcrumb" aria-label="Breadcrumb">',
    'wrap_after'  => '</nav>',
    'before'      => '',
    'after'       => '',
    'home'        => _x( 'Home', 'breadcrumb', 'woocommerce' ),
)

Only change the delimiter key and return the rest untouched. Returning a brand new array wipes out defaults you did not mean to change, such as the aria-label WooCommerce added to wrap_before in version 8.3.

Delimiter Variations

The delimiter is printed as raw HTML, not escaped, so you can use entities, a styled element or an inline SVG. A few common choices:

// Right-pointing angle: Home › Shop › Product
$defaults['delimiter'] = ' &rsaquo; ';

// Arrow: Home → Shop → Product
$defaults['delimiter'] = ' &rarr; ';

// A span you can style with CSS
$defaults['delimiter'] = '<span class="breadcrumb-sep" aria-hidden="true">/</span>';

The span version is the most flexible. Add aria-hidden="true" so screen readers skip the decorative character, then style .breadcrumb-sep in your theme CSS.

Why the Delimiter Does Not Change

If the separator stays the same after adding the filter, the cause is usually one of these:

  • Storefront or another theme sets its own delimiter. Storefront hooks woocommerce_breadcrumb_defaults at the default priority 10 from the parent theme, which loads after your child theme. That is why the snippet above uses priority 20.
  • The breadcrumb is not WooCommerce’s. Yoast SEO, Rank Math and many themes print their own trail, which this filter does not touch.
  • A page cache is serving old HTML. Purge the cache and reload.

In block themes the Store Breadcrumbs block calls woocommerce_breadcrumb() internally, so the same filter applies there. To hide the trail on some pages instead, see Remove WooCommerce Breadcrumbs on Specific Pages.

FAQs

Common questions about the WooCommerce breadcrumb delimiter:

What is the default WooCommerce breadcrumb delimiter?
It is &nbsp;&#47;&nbsp;, a forward slash with a non-breaking space on each side. It is set in woocommerce_breadcrumb() and can be changed through the woocommerce_breadcrumb_defaults filter.
Can I use HTML or an icon as the delimiter?
Yes. The breadcrumb template echoes the delimiter without escaping, so a <span>, an icon font element or an inline SVG all work. Mark decorative separators with aria-hidden="true".
Why does my delimiter change not work in Storefront?
Storefront sets its own delimiter on the same filter at priority 10, and the parent theme loads after the child theme. Register your filter with a higher priority, such as 20, so it runs last.
Does changing the delimiter affect breadcrumb schema?
No. WooCommerce builds its BreadcrumbList structured data from the crumbs array, not from the rendered HTML, so the separator has no effect on schema.

Enable Excerpt Support for Pages in WordPress

WordPress lets you create an excerpt for posts by entering text in the excerpt box on the post edit screen. But excerpts are not available for pages, and there is no way to enable this through the WordPress admin.

If you want to add the excerpt box for pages too, add the following code to your theme’s functions.php file:

<?php

// START COPY FROM HERE
function add_excerpt_pages() {
    add_post_type_support('page', 'excerpt');
}
add_action('init', 'add_excerpt_pages');

 

After adding the code, edit a page and click “Screen options” in the top-left corner of the screen.

How to enable excerpt for pages in WordPress

How to enable excerpt for pages in WordPress

Check the Excerpt box and you are done. You will now see an excerpt box for all pages on your site…

For safe theme customizations, see What Are Child Themes and How to Use Them.

Change Number of Products Per Page in WooCommerce

Use the following code to change the number of products WooCommerce displays per page. For this to work, make sure the “Products per page” option is selected in Customizer.

Changing the number of products displayed per page

Add this code to your theme’s functions.php file:

/**
 * Change number of products that are displayed per page (shop page)
 */
add_filter( 'loop_shop_per_page', 'new_loop_shop_per_page', 20 );

function new_loop_shop_per_page( $cols ) {
  // $cols contains the current number of products per page based on the value stored on Options –> Reading
  // Return the number of products you wanna show per page.
  $cols = 9;
  return $cols;
}

For more WooCommerce customization, see Mastering WooCommerce Hooks.

Completely Disable Search in WordPress

To completely disable WordPress search, add the following code to your theme’s functions.php file:

<?php function sv_filter_query($query, $error = true) {
    if (is_search()) {
        $query->is_search = false;
        $query->query_vars[s] = false;
        $query->query[s] = false;
        if ($error == true)
            $query->is_404 = true;
    }
}

add_action('parse_query', 'sv_filter_query');
add_filter('get_search_form', create_function('$a', "return null;"));
    
function remove_search_widget() {
    unregister_widget('WP_Widget_Search');
}

add_action('widgets_init', 'remove_search_widget');

Limit WordPress Search to Specific Post Types

Ever wondered how to limit search results to a specific Custom Post Type? It is simple. We have already seen how to completely disable WordPress search by modifying functions.php. Now we will do something similar to filter our search results.

Add the following code to your functions.php file:

function sv_search_filter($query) {
 
    if ($query->is_search && !is_admin() ) {
        $query->set('post_type',array('post','page'));
    }
 
return $query;
}
 
add_filter('pre_get_posts','sv_search_filter');

Note this line:

$query->set('post_type',array('post','page'));

You can filter search results by changing the values in that array. Search results will now show only pages and posts, but you can change this array to include any post type you want.

Show Only Free Shipping in WooCommerce Cart and Checkout

By default, WooCommerce displays all shipping options on the cart and checkout pages. If you want to show only the free shipping option on these pages, add the following code to functions.php:

/**
 * Hide shipping rates when free shipping is available.
 * Updated to support WooCommerce 2.6 Shipping Zones.
 *
 * @param array $rates Array of rates found for the package.
 * @return array
 * @link https://docs.woocommerce.com/document/hide-other-shipping-methods-when-free-shipping-is-available/
 */
function prefix_hide_shipping_when_free_is_available( $rates ) {
	$free = array();
	foreach ( $rates as $rate_id => $rate ) {
		if ( 'free_shipping' === $rate->method_id ) {
			$free[ $rate_id ] = $rate;
			break;
		}
	}
	return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'prefix_hide_shipping_when_free_is_available', 100 );

Cache Busting and Versioning for rtl.css

Do you load the rtl.css file using the automatic method WordPress provides? That is, adding the rtl.css file to your theme directory so that when the site language is set to right-to-left (RTL), this file loads automatically. It is the preferred way to load RTL-specific CSS for RTL sites.

However, this file has no version (no query string), which makes cache busting difficult in the browser, especially for this file (if you are not using a caching plugin).

The Query String mentioned above

To add the ver parameter to the rtl.css file based on when the file was last modified, use the following filter:

add_filter( 'locale_stylesheet_uri', function ($localized_stylesheet_uri) {
    $time_ver = filemtime( get_stylesheet_directory() . '/rtl.css' );
    return add_query_arg( array('ver' => $time_ver), $localized_stylesheet_uri );
});

Change WooCommerce Product Image Zoom Behavior

If you want to change the zoom (magnification) behavior when hovering over a product on the WooCommerce product page, you can use the woocommerce_single_product_zoom_options filter:

add_filter( 'woocommerce_single_product_zoom_options', 'custom_single_product_zoom_options' );
function custom_single_product_zoom_options( $zoom_options ) {
    // Changing the magnification level:
    $zoom_options['magnify'] = 0.7;

    return $zoom_options;
}

Here are the parameters you can change:

$zoom_options = array (
    'url' => false,
    'callback' => false,
    'target' => false,
    'duration' => 120, // Transition in milli seconds (default is 120)
    'on' => 'mouseover', // other options: grab, click, toggle (default is mouseover)
    'touch' => true, // enables a touch fallback
    'onZoomIn' => false,
    'onZoomOut' => false,
    'magnify' => 1, // Zoom magnification: (default is 1  |  float number between 0 and 1)
);

For more WooCommerce product page customization, see Mastering WooCommerce Hooks.

Dismiss ACF Unsafe HTML Notice

The ACF plugin in version 6.2.5 and above displays a message like this: ACF now automatically escapes unsafe HTML when rendered by the_field or the ACF shortcode. If you know your field content is safe and want to dismiss this message, add the following code to your functions.php file:

function savvy_acf_remove_msg() {
	add_filter('acf/admin/prevent_escaped_html_notice', '__return_true');
	add_filter('acf/shortcode/allow_unsafe_html', '__return_true');
	add_filter('acf/the_field/allow_unsafe_html', '__return_true');
}
add_action('init', 'savvy_acf_remove_msg');

Disable WordPress URL Guessing

URL Guessing is a built-in WordPress feature that attempts to perform automatic redirects when a user lands on an incorrect URL. In other words, WordPress tries to guess the URL and redirects the user to an address similar to the wrong one entered in the browser bar, so instead of getting a 404 page, the user is redirected to the address WordPress thinks they meant.

To disable this feature, add the following code to your theme’s functions.php file:

<?php

function sv_no_redirect_404($redirect_url)
{
	if (is_404()) {
		return false;
	}
	return $redirect_url;
}
add_filter('redirect_canonical', 'sv_no_redirect_404');