Archives: Snippets | Page 18

Disable Payment Gateway for Specific Shipping Method in WooCommerce

A look at the WooCommerce checkout page and specifically how to disable a payment method for a customer based on the shipping method they selected. For example, disable “Cash on Delivery” for the “Local Pickup” shipping method.

WooCommerce - Disable a payment method for a specific shipping method

Here is a snippet that lets you do something like this (functions.php):

/**
 * @snippet       Disable a payment method for a specific shipping method
 * @author        Roee Yossef
 * @website       https://savvy.co.il
 */
  
function sv_gateway_disable_shipping_326( $available_gateways ) {
     
   if ( ! is_admin() ) {
        
      $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
        
      $chosen_shipping = $chosen_methods[0];
        
      if ( isset( $available_gateways['cod'] ) && 0 === strpos( $chosen_shipping, 'local_pickup' ) ) {
         unset( $available_gateways['cod'] );
      }
        
   }
     
   return $available_gateways;
     
}
add_filter( 'woocommerce_available_payment_gateways', 'sv_gateway_disable_shipping_326' );

Replace PayPal Logo in WooCommerce

If you use PayPal as a payment option on the WooCommerce checkout page, you can replace the PayPal logo displayed there. Add the following code to your theme’s functions.php file:

/**
 * Add custom gateway icons
 *
 * @param string $icon Image HTML.
 * @param string $gateway_id Gateway ID.
 *
 * @return string
 */
function sv_custom_wc_gateway_icons($icon, $gateway_id)
{
    // Example for PayPal:
    if ('paypal' == $gateway_id) {
        $icon = '<img src="' . get_stylesheet_directory_uri() . '/images/paypal.svg" alt="' . __('PayPal') . '" />';
    }
    return $icon;
}

add_filter('woocommerce_gateway_icon', 'sv_custom_wc_gateway_icons', 10, 2);

Change the path and filename to your new image and you are set!

Extend WordPress Auto Logout Period

The following code lets you extend how long it takes before WordPress automatically logs you out of the admin area. Add this code to your theme’s functions.php file:

function keep_me_logged_in_for_1_year( $expirein ) {
   return 31556926; // 1 year in seconds
}
add_filter( 'auth_cookie_expiration', 'keep_me_logged_in_for_1_year' );

For more security tips, see Hardening WordPress Security.

Check if a Post Has Embedded Content

The following snippet lets you check whether a specific post has embedded content. It works inside the loop using the post ID. Alternatively, you can pass any ID to check if that post contains embedded content.

<?php

function has_embed( $post_id = false ) {
	if( !$post_id ) $post_id = get_the_ID();
	else $post_id = absint( $post_id );
	if( !$post_id ) return false;

	$post_meta = get_post_custom_keys( $post_id );
	$post_meta = array_map( 'trim' , $post_meta );

	foreach( $post_meta as $meta ) {
		if( '_oembed' != substr( $meta , 0 , 7 ) )
			continue;
		return true;
	}
	return false;
}

Usage:

if( has_embed() ) {
   // do whatever
}

For more on embedded content, see Improving Loading Time of Embedded Videos.

Pre-populating Post Types with Default Content

The following snippet lets you add default content automatically to every new post of a given post type. Add to functions.php:

<?php
////////////////////////////////////////////////////////////////////////////////////
// This auto populates post types and posts.
///////////////////////////////////////////////////////////////////////////////////


function my_editor_content( $content ) {

	global $post_type;

	switch( $post_type ) {
		case 'your_post_type_here': //auto populate
			$content = 'The content you want to pre-populate the post type with.';
			break;
	}

	return $content;
}
add_filter( 'default_content', 'my_editor_content' );

For more on custom post types, see How to Create Custom Post Types.

Style the ACF Admin Interface

Here is how to add CSS to the ACF admin interface. In this case, we made Repeater Fields have clearer separation. Several other changes were made to improve the interface readability:

Note: Remove the opening PHP tag from the code…

<?php
function my_acf_admin_head() {t?>
    <style type="text/css">

        .acf-flexible-content .layout .acf-fc-layout-handle {
            background-color: #202428;
            color: #eee;
        }

        .acf-repeater.-row > table > tbody > tr > td,
        .acf-repeater.-block > table > tbody > tr > td {
            border-top: 2px solid #202428;
        }

        .acf-repeater .acf-row-handle {
            vertical-align: top !important;
            padding-top: 16px;
        }

        .acf-repeater .acf-row-handle span {
            font-size: 20px;
            font-weight: bold;
            color: #202428;
        }

        .imageUpload img {
            width: 75px;
        }

        .acf-repeater .acf-row-handle .acf-icon.-minus {
            top: 30px;
        }

    </style>
t<?php
}

add_action( 'acf/input/admin_head', 'my_acf_admin_head' );

And here is the result for the Repeater. Notice the separator line?

Making the Repeater have clearer styling

Add CSS to WooCommerce Emails

To change the styling of emails that WooCommerce sends, you can add inline CSS using the woocommerce_email_header hook. Add the following code to your functions.php file:

<?php
/**
 * WooCommerce
 * Add inline CSS to emails sent out
 */
function sv_add_css_to_woo_email() {
    echo '<style type="text/css">
             h1 {
                 text-align: center !important;
                 color: #DDD;
             }
         </style></pre>'; 
}
add_action( 'woocommerce_email_header', 'sv_add_css_to_woo_email' );

For more WooCommerce email customization, see Mastering WooCommerce Hooks.

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'] = '&nbsp;&#124;&nbsp;';
    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'   => '&nbsp;&#47;&nbsp;',
    '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.