Building sites based on WordPress & WooCommerce can sometimes lead you to create custom solutions that you never thought you would have to or that such a request was ever to be made. A friend of mine, Goran Jakovljević from wpgens.com, had a similar situation. He had to move the whole shipping methods area away from the table and into somewhere else. In this tutorial, I will show you how to customize WooCommerce checkout pages with understanding and also how to move other parts around.
We are going to get into two specific parts of customizing the checkout page. First, we will move the shipping address & notes to the bottom of the page and have the order details (total) appear on the right side (next to the billing address). Second, we will move the shipping methods from the table and move it up above the product list.
If you don’t like to read a lot, you can watch it here:
First Steps: Making a Child Theme
When you want to customize WooCommerce checkout pages, you will probably have to use a child theme (or another plugin). In this tutorial, I will also use a child theme.
When you install a new WordPress site, you will get the Twenty Seventeen theme and we will use that as our parent theme. Go to your
wp-content/themes folder and create a new folder
child17. Inside that folder, create a
style.css and copy this code there:
Now, go to the admin dashboard and activate that theme (be sure to have the Twenty Seventeen available there also).
Before we go further, let’s make sure that we have the right CSS from the parent theme so create the file
functions.php and add this:
How to Customize WooCommerce Checkout Pages
It is pretty easy to change and override WooCommerce templates. With the same approach we will use here to customize WooCommerce checkout pages, you can customize any other WooCommerce parts.
When you want to overwrite a WooCommerce template, just create a folder
woocommerce in your theme and then start following the same path that WooCommerce has for each template inside the folder
Replacing Shipping Details with Order Totals
Now that we have a child theme and understand how to override a WooCommerce template, we are ready to proceed.
To re-order the shipping details and order totals, you need to create a folder
woocommerce folder in your child theme. Then add a file
form-checkout.php and copy the whole file contents from the plugin
We will do now something really simple. If you look closely to that template, you will see that the billing and shipping details are wrapped inside
.col-2set. We want that placed above and then wrap the order details into a
.col-2. Check it out here:
If you want to see the complete file, you can check it out here.
So simple, right? You could do some more advanced stuff, but that is up to you!
Moving Shipping Methods Somewhere Else
The previous parts was really simple, right? Let’s now move the shipping methods above the products. How to do that?
If you check the
checkout-form.php for order review, you will see there is an action
woocommerce_checkout_order_review. This action will include a file
So, what should we do? Let’s create a new file in our child theme,
woocommerce/checkout/review-order.php. After that, go to WooCommerce and copy the code from that template (
Then, find the shipping methods code that will look like this:
Once you found that, select it all, copy it and DELETE IT. Yes, remove it from that template. We don’t need it, but keep it in the clipboard (don’t copy other stuff).
Now, we will go to our previous template
checkout-form.php and find the
After that, copy the shipping methods code above it. You probably think that you are done, right? Wrong.
Fixing the Shipping Methods Refresh Issue
Now, since the shipping methods are in their own custom table, they won’t be refreshed if you change the address. To be able to view that issue, you will have to add at least 2 shipping zones. Add them inside WooCommerce Settings. I have 2 shipping zones, first is Everywhere with 2 different shipping methods and the second one is Croatia with a free shipping method. Be sure to put Everywhere as the last option.
Open the checkout page (with at least 1 product in the cart). The shipping methods will be correct on the page load. But if you try to change the address, let’s say from Croatia to United States, you won’t see the refreshed shipping methods.
How to fix that? We will use fragments.
Fragments are JSON objects retrieved from AJAX responses and each fragment consists of:
- key – class or id which we can use to target an element
- value – new HTML that we will put into that place
When we change our details on the checkout page, WooCommerce performs an AJAX request to our website and retrieves a new order total. You can check what it does inside
woocommerce/includes/class-wc-ajax.php. For the checkout page purposes, you might be interested in checking out the method
On the front side, when the AJAX response is retrieved, WooCommerce goes through each fragment and uses the key to target an element through jQuery. After that, it replaces it with the value. How is that done? You can check the GitHub
checkout.js on WooCommerce.
Refactoring the Shipping Methods
To add our own fragment, we first need to wrap the shipping methods in a custom table since Shipping Methods HTML is actually a table row
tr. This table will also have a custom class (our fragment key).
Adding our own Fragment HTML
If you look closely to the method
update_order_review, you will see that the fragments are filtered with
woocommerce_update_order_review_fragments. We will use that filter to add our own fragment. Open the file
functions.php and add this:
In here, we are adding the complete custom shipping table (with the custom class) and we are adding that HTML to the key
Now, when the AJAX is processed, the WooCommerce will get our old table HTML with
$('.my-custom-shipping-table') and replace it with the new HTML.