WooCommerce Shop Code Snippets

Learn how to set up a WooCommerce shop. You’ll use eleven different plugins and many different code snippets to get this WooCommerce shop set up! Please be warned that this tutorial is not complete, but it is definitely packed with useful information.

Initial Setup

Install WooCommerce Plugin and go through installation steps.

Below are various snippets to modify your WooCommerce shop.

Enable theme support for the Genesis Connect plugin and WooCommerce.

/*-- Enable Genesis Connect --*/
add_theme_support( 'genesis-connect-woocommerce' );
add_theme_support("woocommerce");

Next, install Genesis WooCommerce Connect plugin.

Rename the pre-created Shop page to whatever you want. Somehow WooCommerce displays the products on it.

Install WP All Import and WPAI WooCommerce Addon plugin ($140).

Install the Search and Filter Pro plugin ($20).

Install the WooCommerce Additional Variation Images plugin $50).

Install the WooForce USPS Shipping Plugin ($70).

Install the WooForce FedEx Shipping Plugin ($70).

Install WC Variations Radio Buttons ($0).

Create a Drift account and install the Drift plugin ($0).

Install the YITH WooCommerce Gift Cards plugin ($0).

Install the  Login Widget With Shortcode plugin, create a page called Log In and paste the following shortcode into it: [login_widget]. This will be used in conjunction with the login-out-function.php file.

Install the Custom Post Type UI plugin to create the Gender/Age taxonomy on the product post type.

Hide shipping rates when free shipping is available.

 function my_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', 'my_hide_shipping_when_free_is_available', 100 );

Change WooCommerce’s CSS to display three items per row.

add_filter( 'loop_shop_columns', 'wc_loop_shop_columns', 1, 10 );
/*
 * Return a new number of maximum columns for shop archives
 * @param int Original value
 * @return int New number of columns
 */
function wc_loop_shop_columns( $number_columns ) {
	return 6;
}

Change WooCommerce layout to be compatible with Genesis.

/*-- Change WooCommerce layout for Genesis --*/
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10);
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10);

add_action('woocommerce_before_main_content', 'my_theme_wrapper_start', 10);
add_action('woocommerce_after_main_content', 'my_theme_wrapper_end', 10);

function my_theme_wrapper_start() {
  echo '';
}

function my_theme_wrapper_end() {
  echo '';
}

Remove default Genesis sidebar and add a custom sidebar for WooCommerce pages. This sidebar will be used to display filtering and sorting widgets.

/*-- Register woocommerce sidebar for Search & Filter form --*/
remove_action( 'genesis_after_content', 'genesis_get_sidebar' ); //remove the default Genesis sidebar
genesis_register_sidebar( array(
	'id'            => 'woocommerce-sidebar',
	'name'          => __( 'WooCommerce Sidebar', 'TrueQuality' ),
	'description'   => __( 'This is the WooCommerce primary sidebar', 'TrueQuality' ),
) );

/*-- Display custom woocommerce sidebar if we are on a woocommerce page --*/
add_action('genesis_before_content', 'add_wc_sidebar');
function add_wc_sidebar() {
  if (is_woocommerce() && !is_single()) {
    genesis_widget_area( 'woocommerce-sidebar', array(
	     'before' => '<aside class="sidebar sidebar-primary widget-area" role="complementary" aria-label="Primary Sidebar" itemscope itemtype="http://schema.org/WPSideBar">',
	     'after' => '</aside>',
    ) );
	}
}

Add a custom field to the checkout form.

/*-- Add custom field to checkout form--*/
add_action( 'woocommerce_after_order_notes', 'add_party_field_to_checkout_form' );

function add_party_field_to_checkout_form( $checkout ) {

    echo '<div id="party_name_checkout_field"><h2>' . __('Party/Group') . '</h2>';

    woocommerce_form_field( 'party_name', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Please specify the name of your party'),
        'placeholder'   => __('Your Party Name'),
        ), $checkout->get_value( 'party_name' ));

    echo '</div>';

}

/**
 * Update the order meta with field value
 */
add_action( 'woocommerce_checkout_update_order_meta', 'party_checkout_field_update_order_meta' );

function party_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['party_name'] ) ) {
        update_post_meta( $order_id, 'Party/Group', sanitize_text_field( $_POST['party_name'] ) );
    }
}

/**
 * Display field value on the order edit page
 */
add_action( 'woocommerce_admin_order_data_after_billing_address', 'party_checkout_field_display_admin_order_meta', 10, 1 );

function party_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Party/Group').':</strong> ' . get_post_meta( $order->id, 'Party/Group', true ) . '</p>';
}

 

Add the following code to functions.php to change the number of products on the shop page to twelve.

/*-- Modify the main woocommerce loop to display twelve products per page --*/
add_action( 'pre_get_posts', 'my_modify_main_query' );
function my_modify_main_query( $query ) {
    if( $query->is_main_query() && (is_shop() || is_product_category() || is_tax('gender_age')) && !is_admin()) {
        $query->set( 'posts_per_page', 12 );
    }
}

Change the Add to Cart button with the following code.

add_action('init','remove_loop_button');
function remove_loop_button(){
	remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
}

add_action('woocommerce_after_shop_loop_item','replace_add_to_cart');
function replace_add_to_cart() {
	global $product;
	$link = $product->get_permalink();
	echo $link;
}

Add this code if you are importing products with WP All Import and have also purchased the WooCommerce plugin to enable additional variation images.

/*-- When WP All Import saves a post, get its gallery and apply it to a new post meta key (allows the WC Add More Variation Images plugin to recognize the gallery) --*/
add_action('pmxi_saved_post', 'post_saved', 10, 1);
function post_saved($id) {
        $product_image_gallery = get_post_meta($id, '_product_image_gallery')[0];
        update_post_meta( $id, '_wc_additional_variation_images', $product_image_gallery );
}

Create a file called login-out-function.php in your themes root folder and add the following code to it. This code will add a Log In link when user’s are logged out and a Log Out link when users are logged in. It will add the link to the menus with the slugs top-menu and footer-2.

<?php
/**
 * Simple helper function for make menu item objects
 * 
 * @param $title      - menu item title
 * @param $url        - menu item url
 * @param $order      - where the item should appear in the menu
 * @param int $parent - the item's parent item
 * @return \stdClass
 */ 
function _custom_nav_menu_item( $title, $url, $order, $parent = 0 ){
  $item = new stdClass();
  $item->ID = 1000000 + $order + parent;
  $item->db_id = $item->ID;
  $item->title = $title;
  $item->url = $url;
  $item->menu_order = $order;
  $item->menu_item_parent = $parent;
  $item->type = '';
  $item->object = '';
  $item->object_id = '';
  $item->classes = array();
  $item->target = '';
  $item->attr_title = '';
  $item->description = '';
  $item->xfn = '';
  $item->status = '';
  return $item;
}



add_filter( 'wp_get_nav_menu_items', 'custom_nav_menu_items', 20, 2 );

function custom_nav_menu_items( $items, $menu ){
  // only add item to a specific menu
  if ( $menu->slug == 'top-menu' || $menu->slug == 'footer-2' ){

    // only add profile link if user is logged in
    if ( get_current_user_id() ){
        $items[] = _custom_nav_menu_item( 'Logout', wp_logout_url( home_url() ), 4 );
       
    } else {
        $items[] = _custom_nav_menu_item( 'Login', '/log-in', 4 );
    }
  }
    
  return $items;
}

Then, add the following code to functions.php to activate the code above.

include('login-out-function.php');

Remove the orderby widget by creating a folder called WooCommerce in your theme’s folder. Create a folder called loop inside of that, and create an empty file called orderby.php inside of that (your-theme-folder > woocommerce > loop > orderby.php).

Create a file called taxonomy.php in the woocommerce folder and insert the following code. The following code can also be found in the Genesis Connect plugin which you should have installed.

This step is completely unnecessary and only exists to help you understand what’s going on in your taxonomy template.

<?php
/**
 * This template displays the archive for Products
 *
 * @package genesis_connect_woocommerce
 * @version 0.9.8
 *
 * Note for customisers/users: Do not edit this file!
 * ==================================================
 * If you want to customise this template, copy this file (keep same name) and place the
 * copy in the child theme's woocommerce folder, ie themes/my-child-theme/woocommerce
 * (Your theme may not have a 'woocommerce' folder, in which case create one.)
 * The version in the child theme's woocommerce folder will override this template, and
 * any future updates to this plugin won't wipe out your customisations.
 *
 * @since 0.9.0
 *
 */

/** Remove default Genesis loop */
remove_action( 'genesis_loop', 'genesis_do_loop' );

/** Remove WooCommerce breadcrumbs */
remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 );

/** Uncomment the below line of code to add back WooCommerce breadcrumbs */
//add_action( 'genesis_before_loop', 'woocommerce_breadcrumb', 10, 0 );

/** Remove Woo #container and #content divs */
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );


/** Get Shop Page ID */
// @TODO Retained for backwards compatibility with < 1.6.0 WooC installs
global $shop_page_id;
$shop_page_id = get_option( 'woocommerce_shop_page_id' );


add_filter( 'genesis_pre_get_option_site_layout', 'genesiswooc_archive_layout' );
/**
 * Manage page layout for the Product archive (Shop) page
 *
 * Set the layout in the Genesis layouts metabox in the Page Editor
 *
 * @since 0.9.0
 *
 * @param str $layout Genesis layout, eg 'content-sidebar', etc
 * @global string|int $shop_page_id The ID of the Shop WP Page
 * @return str $layout Shop Page layout from postmeta
 */
function genesiswooc_archive_layout( $layout ) {

	global $shop_page_id;

	$layout = get_post_meta( $shop_page_id, '_genesis_layout', true );

	return $layout;
}

add_action( 'genesis_before_loop', 'genesiswooc_archive_product_loop' );
/**
 * Display shop items (product custom post archive)
 *
 * This function has been refactored in 0.9.4 to provide compatibility with
 * both WooC 1.6.0 and backwards compatibility with older versions.
 * This is needed thanks to substantial changes to WooC template contents
 * introduced in WooC 1.6.0.
 *
 * @uses genesiswooc_content_product() if WooC is version 1.6.0+
 * @uses genesiswooc_product_archive() for earlier WooC versions
 *
 * @since 0.9.0
 * @updated 0.9.4
 * @global object $woocommerce
 */
function genesiswooc_archive_product_loop() {

	global $woocommerce;
	
	$new = version_compare( $woocommerce->version, '1.6.0', '>=' );
	
	if ( $new )
		genesiswooc_content_product();
		
	else
		genesiswooc_product_archive();
}

genesis();

Create another file in your woocommerce folder and call it content-product.php and insert the following template code. This adds a class of “last” to the last product in a row. The layout would break without that class.

Editing:  
/home/truequalityshoes/public_html/wp-content/themes/TrueQuality/woocommerce/content-product.php
 Encoding:    Re-open Use Code Editor     Close  Save Changes

<?php
/**
 * The template for displaying product content within loops
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/content-product.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
 * will need to copy the new files to your theme to maintain compatibility. We try to do this.
 * as little as possible, but it does happen. When this occurs the version of the template file will.
 * be bumped and the readme will list any important changes.
 *
 * @see     http://docs.woothemes.com/document/template-structure/
 * @author  WooThemes
 * @package WooCommerce/Templates
 * @version 2.5.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

global $product, $woocommerce_loop;

// Store loop count we're currently on
if ( empty( $woocommerce_loop['loop'] ) ) {
	$woocommerce_loop['loop'] = 0;
}

// Store column count for displaying the grid
if ( empty( $woocommerce_loop['columns'] ) ) {
	$woocommerce_loop['columns'] = apply_filters( 'loop_shop_columns', 3 );
}

// Ensure visibility
if ( ! $product || ! $product->is_visible() ) {
	return;
}

// Increase loop count
$woocommerce_loop['loop']++;

// Extra post classes
$classes = array();
if ( 0 === ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 === $woocommerce_loop['columns'] ) {
	$classes[] = 'first';
}
if ( 0 === $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) {
	$classes[] = 'last';
}
?>
<li <?php post_class( $classes ); ?>>

	<?php
	/**
	 * woocommerce_before_shop_loop_item hook.
	 *
	 * @hooked woocommerce_template_loop_product_link_open - 10
	 */
	do_action( 'woocommerce_before_shop_loop_item' );

	/**
	 * woocommerce_before_shop_loop_item_title hook.
	 *
	 * @hooked woocommerce_show_product_loop_sale_flash - 10
	 * @hooked woocommerce_template_loop_product_thumbnail - 10
	 */
	do_action( 'woocommerce_before_shop_loop_item_title' );

	/**
	 * woocommerce_shop_loop_item_title hook.
	 *
	 * @hooked woocommerce_template_loop_product_title - 10
	 */
	do_action( 'woocommerce_shop_loop_item_title' );

	add_action('woocommerce_after_shop_loop_item_title','woocommerce_template_single_excerpt', 5 );

	/**
	 * woocommerce_after_shop_loop_item_title hook.
	 *
	 * @hooked woocommerce_template_loop_rating - 5
	 * @hooked woocommerce_template_loop_price - 10
	 */
	do_action( 'woocommerce_after_shop_loop_item_title' );

	/**
	 * woocommerce_after_shop_loop_item hook.
	 *
	 * @hooked woocommerce_template_loop_product_link_close - 5
	 * @hooked woocommerce_template_loop_add_to_cart - 10
	 */
	do_action( 'woocommerce_after_shop_loop_item' );
	?>

</li>