Your theme contains outdated copies of some WooCommerce template files

Often when you upgrade WooCommerce you get the error Your theme contains outdated copies of some WooCommerce template files. Ianua in this case. How to resolve this issue? Well. let’s work things out shall we?

Check System Status Page

The error message Your theme contains outdated copies of some WooCommerce template files will also indicate you should check the system status page where they will show you what pages are outdated. Here the full error message:

Your theme (Ianua) contains outdated copies of some WooCommerce template files. These files may need updating to ensure they are compatible with the current version of WooCommerce. You can see which files are affected from the system status page. If in doubt, check with the author of the theme.

NB They also refer to to learn more about the WooCommerce template structure

Outdated Templates

At the bottom of the system status page they will show you what templates are outdated.

Outdated Templates

If you are the author of the theme it will be up to you to update the files in question. If you bought the theme from another developer you should ask them for an update and then overwrite the theme according to their instructions.

Updating Theme Caveats

Now remember, just because a template got an update it does not mean the theme won’t work anymore. Two, if you would update a theme you bought by yourself you may lose the layout that was set up using it so do this only if you know what you are doing. Better to contact the theme builder before you make any changes yourself!

When to Update

If we check ianua/archive-product.php for example we will see that we added the product archive page as we wanted a specific display:

A custom WP_Query was created to load the products. This so additional html could be added for all the page elements with ease. This page was on the list of pages needing an update according to WooCommerce. It stated

ianua/archive-product.php version - is out of date. The core version is 2.0.0,

This page won’t be updated at this moment though. That is because of the custom code for one. It also is not using any WooCommerce functionality that no longer works. If the latter would have been the case we would have had to update the outdated code.

So only update if the files that need updating do not have any custom code, which will be rare if the file in question is part of the theme. Two, if there is custom, only update the functionality that is outdated or even causing (fatal) errors.

Removing the Warning

If you do want the warning not to be mentioned anymore, add the correct block with the file version number. In this case the block would be:

* The Template for displaying product archives, including the main shop page which is a post type archive
* This template can be overridden by copying it to yourtheme/woocommerce/archive-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
* @author      WooThemes
* @package     WooCommerce/Templates
* @version 2.0.0

As you can see the version was 2.0.0 at the time of the writing of this blog post. Of course other files have other version numbers.

WooCommerce Product in a Post

How do you take care of having a WooCommerce Product in a Post? More important, why should you put your product or products in blog posts? In this post I will explain how and why you should do it.

WooCommerce Product in a Post Advantages

If a reader really enjoyed your posts and goes all the way to the bottom of that blog post he is more likely to be interested in a product related to that post. It will be very helpful for him to see what products or services you are offering that are related to the blog post. You hereby basically give useful information for free how to deal with a problem or how to deal with something. And at the same time you offer your help in case the reader cannot work it out or simply does not have the time to do it.

WooCommerce Shortcodes

WooCommerce uses shortcodes. These shortcodes allow you to load WooCommerce functionality in pages or posts. In our case we want to load some basic product details to show our readers we can help them out with related services.You add a WooCommerce shortcode for the product in question using its product id. Here an example:

[ product id="999" ]

NB Spaces added after first and before last bracket to not have the product 999 load here

You will then see something like this:

WooCommerce Product in blog post

Other Options

There are even options to add the full product with all its details or just the product title, price and add to cart button. To load the full product page you do this using the shortcode [ product_page id=”99″ ]. But I think it is better to just add a thumbnail, title and price and option to add the product to the cart. And that is what this shortcode does. As for just showing a cart button with the product title and price you can use [ add_to_cart id=”99″ ]. As I find a thumbnail to go with the product more visually appealing I would stick to the choice suggested.


Setting up WooCommerce Subscriptions

Setting up WooCommerce Subscriptions is pretty straightforward. As should be the reasons going for subscriptions. However, you may run into certain issues and documentation on some issues may not be clear enough.

Subscriptions Rock

Subscriptions will mean recurring revenue. It will means that you can sell packages that can be sold time and again. And you will be selling them automatically. We all need repeat business where we can get it and this is the perfect way to arrange repeat business. Also, it is way easier and cheaper to keep a client than acquire one so the more reason to keep the ones you acquired.


We assume here you can acquire the plugin yourself and activate the plugin from within WordPress or using the WP CLI command line tool. That is not too hard really, even for beginners. So let’s move onto the configuration.

WooCommerce Subscriptions Configuration

Once the plugin is up and running you can go to your WooCommerces settings where you will find a new tab called subscriptions and there you can work on setting up WooCommerce Subscriptions  for real. There may be other issues to deal with like PayPal tweaks as we will discuss later, but let’s start with this overview tab.

WooCommerce Subscriptions Configuration

Subscription Button and Default Roles

You can set the button text and default roles. Button text speaks for itself. Default role you should choose carefully. What do customers become when they are subscribed. Most of the time the default settings are fine. But do make sure they apply to your business setup.

Subscription Renewals

Normally you will do the subscription renewals automatically. That is the joy of using them in the first place. You let customers auto renew their accounts so they can keep on enjoying their package and you can keep on enjoying recurring payments. Sometimes however you would like to accept manual renewals. This way the subscription is put on hold until your customer renews himself.

NB Do realize this setup will only work for new clients post activation

Switching Subscription Package

You can allow the switching of packages. This means you can allow your customers to upgrade or downgrade their subscription with you. You can do this with a variable subscription product which most of you will have  or within a grouped product. You can also choose both.

Subscription Switching

Prorate recurring Payment

When you allow the switching for one of your products you can choose to pay the client the difference between the old setup and cheaper setup. Or if it is more expensive let him pay the difference. If you like you can even allow Prorate recurring payment only for upgrades

You can however also choose to let it be his loss. And that case he will will pay until the end of the period of the subscription package he chose and pay for the new setup at the same time.

If you work with a sign-up fee as well you can choose to run this fee when the client switches package, but you do not need to do this.


You can run all renewals at the same date, the first of the month for example. This can be useful with certain products. As WooCommerce stated:

For example, a store selling a monthly gift box might ship the boxes on the first of each month. If a customer signed up on the 20th of January, by default her first renewal would be on the 20th of February. With renewal synchronization enabled, the customer can sign up on the 20th January and pay nothing to sign up (unless there is a sign up fee) and have the first subscription renewal processed on the 1st of February. The next renewal will then be processed on the 1st of March, then 1st April and so on.

Also here with this setup you can do pro rating for the first payment. This as your customer may only enjoy part of the package that month before the new package is sent out.

PayPal Issues

Once activated you will normally get a warning straight away. This is because most of us will need to enter our PayPal IPN and API credentials under checkout > PayPal. If you never did this before the error:

PayPal is inactive for subscription transactions. Please set up the PayPal IPN and enter your API credentials to enable PayPal for Subscriptions.

will refer you to WooCommerce documentation to get this IPN and API Credentials in order. The link to IPN details goes to the wrong section though and I had to click on PayPal there to get to that same link again properly. There you can read up on both and there you will also find links to PayPal documentation. The WooCommerce section on IPN is actually here. And there they have a nice animated gif showing you how to do it.

PayPal Tweaks

To get the IPN done and API Credentials you need to do some tweaks at PayPal first. Go to your profile > selling tools. Your Profile is found in the top right corner once logged into PayPal:

Your PayPal Profile

After clicking that you can find selling tools as options in the right sidebar:

PayPal Selling Tools


Under selling tools > you will find “Instant payment notifications” (IPN) where you can set up the proper url. In our case it is:

Do change the url go represent your website of course. Also make sure message delivery is enabled.

NB IPN is not the be best way to run these things and for other sites like Rocket Pure we set up PIT as well.

PayPal API Credentials

The PayPal API Credentials you can find or set up under profile > selling tools > API Credentials. Once you clicked on update here you will get to the location where you either can add or grant API permission or manage API permissions:

PayPal API

When you click on manage you will see the API Access page

PayPal API Access

NB Sometimes you will be required to identify yourself as account owner. Especially when you decided to work from a different location like I as Digital Nomad often do.

These credentials you will need to enter in your WooCommerce environment:

API Credentials

Once that is done the setting upWooCommerce Subscriptions is a fact and you are ready to rock and roll!

WooCommerce Product Order

You need the products in your shop to be displayed in a certain order.  So how do you deal with the WooCommerce Product Order? Where can this be done? It is just one of these things. Once you know where it is it is easy.Well is is a little bit different from ordering posts, but not much.

Advanced Product Data

You need to go to the advanced product settings for your product. So go to the product you would like to move down or up on your shop page. Then under Product data > Advanced you can pick a menu order.

WooCommerce Product Order

The lower the number the earlier it will popup on the list. Don’t forget to hit update!

WooCommerce Coupon Codes – How to set them up

One great way to start selling your products is using WooCommerce Coupon Codes. It is a nice way to entice your customers to buy your product. We all love a discount don’t we? So how do we setup WooCommerce Coupon Codes? Let’s dive in shall we?

Locating WooCommerce’s Coupons

When you go to your WordPress Dashboard and then to WooCommerce you will see the options coupons right away.

Woocommerce Coupons in Menu

Coupons List

Once you click on coupons you will be able to add new coupons or edit existing ones just like you would with posts and pages in WordPress.

WooCommerce Coupons List

Just click on “add coupon” to add a new one.

New Coupon

Once there you can

  • give it a title and description,
  • indicate the duration and
  • the amount of discount as a percentage or amount

Add new coupon

I think a percentage works best so recommend this. Do not forget to make it expire. I would not let it last forever. Discounts last for a certain period. In that period like Christmas time people should get that discount. And once that period it over the coupon should have expired.

Usage Restrictions

As for Usage restrictions, well, there are many options like

  • minimum or maximum amount spent,
  • individual use only,
  • excluding sales items
  • products it will be applied to

Usage Restrictions

I would at least pick the product you apply it to unless you do everything on sale. Besides that it is smart to exclude items that are on sale already.

Usage Limits

As for usage limits do restrict things if your shop is really busy or does get busy here. You can l

  • imit usage per coupon,
  • limit the usage for a certain item if it applies to many products and
  • limit it by user.

Usage Limits

Coupon Code

The coupon code itself is the title you gave it. So “WOO-SETUP-15” for example would be a good one for selling WooCommerce products in our case. Well, it should be pretty clear as the title is called “coupon code”, but we decided it would be good to mention anyways.

WooCommerce & Google Analytics Pro Setup

Often you use Google Analytics to track buyers. But a lot of beginners set up the bare basics only. You should do a WooCommerce & Google Analytics Pro Setup instead. One that allows you thorough tracking of all your customer transactions and movals on your site. One that shows you every step they take and how your goals are converting. In this blog post I will show you some great tips to do just that.

Google Analytics Goals

You want to track properly whether or not your product is being sold. That will be your end goal. The goal to sell and get paid is what you want of course. In Google Analytics you can set up goals to track your store goals. You can find them under admin:

Google Analytics Goals

Once you are there you can set up you own goal by clicking on the red “new goal button .

Revenue Goal

The type of goal we would go for here is a revenue goal. You are interested in making money after all. For that Google Analytics has a goal template ready:

Goal Template - revenue

Next step is to choose the type of revenue goal. We pick a destination.The trick is to use the WooCommerce order received page as the final step or destination. Once that page is reached it means your customer really went all the way and bought your product.

That is this slug:


In Google Analytics you indicate that under goal destination and you pick “begins with”:

Goal Destination

PayPal Caveat

If you do use PayPal you also have to make sure that the client is sent back to your store automatically and that the tracking continues. This you do by going to:

  • your profile
  • selling tools
  • website preferences

PayPal Setup

There you can choose to send users back to your store once paid automatically and add a utm slug to keep the tracking going.

PayPal Auto Return

The slug used for Imagewize is

And for you you would obviously have to change the domain to represent your shop. And that followed by the utm string: ?utm_nooverride=1 

Goal Funnel

I also recommend setting up a funnel to analyse the user’s behavior. It is very useful for example to find out where in the process the customer bailed. A few steps you could use are:

  • shop
  • product page
  • cart
  • checkout

This will depend of course on what your customer’s path will be. Some of you use the one page checkout. And in that case there may just be 2 steps. Or when you do use the shop page and then the product page you will need one step before the ones I made here:

GA Funnel

The one here starts at the product page as you can see. And I made it a required step. That is not always necessary nor desired though.

Google Analytics Ecommerce

To also track all transactions taking place you should also activate ecommerce on Google Analytics. This you can also do under admin > view. There you find the ecommerce settings option. Make sure you enable default and enhanced ecommerce to get all the goodness.

GA Ecommerce Setup

NB The abandoned cart plugin will also help of course.

Enhanced E-commerce for Woocommerce Store Plugin

Now to make the Ecommerce work well with WooCommerce and without the need to be a JavaScript ninja you need to install one plugin: Enhanced E-commerce for Woocommerce store.

Enhanced Ecommerce Google Analytics Plugin for WooCommerce

It will make it all work like a charm. Trust me it is pretty amazing. The commercial version of this plugin is even better, but this free one does most of what you need. Here is the shortlist with what it brings as told by them at WordPress:

  • Supports four New Reports in Enhanced Ecommerce
  • Shopping Behaviour Report
  • Checkout Behaviour Report
  • Product Performance Report
  • Sales Performance Report
  • Supports Guest checkout functionality
  • Supports Display Advertising Feature
  • Captures Product Impressions, Add to Cart & Product Clicks events on category page
  • Captures Product Impressions, Add to Cart & Product Clicks events on product page

As you can see it is pretty amazing, isn’t it?

Well once you have done all this tracking should have become pretty amazing. Good luck!

Bonus: Great general article on Google Analytics and Conversion Tracking

Can’t get enough? Subscribe to our mail list!

[gravityform id=”14″ title=”false” description=”false”]

[product id=”6934″]

Single Product WooCommerce Website

Sometimes you have an online store with one product or service to sell only. Sometimes that is because that is all you are selling, sometimes it is because you are just starting out. So how could you make the shop look good with a single product WooCommerce website?

Single Product Shop Layout

Oftentimes you will think that having a shop page is kind of overkill, but WooCommerce creates this page as it creates other pages like “My Account”, Cart and Checkout. So what should you do with this shop page? Well you could style it in such a way that the shop page looks a lot like the single product page. And then you could make it possible to directly put the item in the basket and go to the one page checkout. This way you will be bypassing the product page itself though that page will also exist.

Bypass Shop Page

Somehow that does not seem right to me. I would think it is better to have the product page and not have the shop page. So how could we do this? Well, we could make visitors skip the shop page, but building in a redirect to your product and by hiding the shop page by not mentioning it in the menu.

Helga the Viking mentioned a possible redirect option here:

function so_template_redirect(){
 if( function_exists( 'is_shop' ) && is_shop() ){
 $product_id = 999; // change to the ID of your 1 product
 $permalink = get_permalink( $product_id );
 wp_redirect( $permalink );
 add_action( 'template_redirect', 'so_template_redirect' );

Using the template_redirect a redirect can be done the WordPress way. I may be stating the obvious, but you need to add this code to the functions.php of your child theme or add it to a separate plugin perhaps dedicated to custom functions.

Presentation Single Product

The single product could be mentioned the navigation using the name shop or whatever you would like it to be. This way you create a single product WooCommerce website. A shop with one product that bypasses the superfluous shop overview page.

WooCommerce 2.7.0 Test Drive – Dealing with Deprecated Functions and Disallowed Direct Calls

Decided to test WooCommerce 2.7.0 beta 3 locally for my Ianua Theme. As a theme author it is always important to see if a whole new version works for you or not and if not to fix the issues. I realized a lot of code for single product page display was deprecated as functions got renamed and a lot of calls could not be made directly to the $product class anymore.

Deprecated get_gallery_attachment_ids

Ran into this PHP notice on single product pages. The function:


is now outdated and should be replaced by:


Steps to Reproduce this Error

This was the actual error message delivered by xdebug so very thorough:

 PHP Notice: WC_Product::get_gallery_attachment_ids is <strong>deprecated</strong> since version 2.7! Use WC_Product::get_gallery_image_ids instead. in /srv/www/ on line 3828
 [01-Mar-2017 06:55:56 UTC] PHP Stack trace:
 [01-Mar-2017 06:55:56 UTC] PHP 1. {main}() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 2. require() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 3. require_once() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 4. include() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 5. include() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 6. wc_get_template_part() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 7. load_template() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 8. require() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 9. do_action() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 10. WP_Hook->do_action() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 11. WP_Hook->apply_filters() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 12. woocommerce_show_product_images() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 13. wc_get_template() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 14. include() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 15. WC_Abstract_Legacy_Product->get_gallery_attachment_ids() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 16. wc_deprecated_function() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 17. _deprecated_function() /srv/www/
 [01-Mar-2017 06:55:56 UTC] PHP 18. trigger_error() /srv/www/

System Status Report

System status report did mention I had several files that were outdated. Those were all the WooCommerce files I heavily edited to display the store as I needed with custom queries and custom html and JavaScript voodo.

### WordPress Environment ###

Home URL:
 Site URL:
 WC Version: 2.7.0
 Log Directory Writable: ✔
 WP Version: 4.7.2
 WP Multisite: –
 WP Memory Limit: 256 MB
 WP Debug Mode: ✔
 WP Cron: –
 Language: en_US

### Server Environment ###

Server Info: nginx/1.11.5
 PHP Version:
 PHP Post Max Size: 50 MB
 PHP Time Limit: 120
 PHP Max Input Vars: 1000
 cURL Version: 7.47.0

SUHOSIN Installed: –
 Max Upload Size: 50 MB
 Default Timezone is UTC: ✔
 fsockopen/cURL: ✔
 SoapClient: ❌ Your server does not have the SoapClient class enabled - some gateway plugins which use SOAP may not work as expected.
 DOMDocument: ✔
 GZip: ✔
 Multibyte String: ✔
 Remote Post: ✔
 Remote Get: ✔

### Database ###

WC Database Version: 2.7.0
 WC Database Prefix: wp_
 woocommerce_sessions: ✔
 woocommerce_api_keys: ✔
 woocommerce_attribute_taxonomies: ✔
 woocommerce_downloadable_product_permissions: ✔
 woocommerce_order_items: ✔
 woocommerce_order_itemmeta: ✔
 woocommerce_tax_rates: ✔
 woocommerce_tax_rate_locations: ✔
 woocommerce_shipping_zones: ✔
 woocommerce_shipping_zone_locations: ✔
 woocommerce_shipping_zone_methods: ✔
 woocommerce_payment_tokens: ✔
 woocommerce_payment_tokenmeta: ✔
 MaxMind GeoIP Database: ✔

### Security ###

Secure connection (HTTPS): ✔
 Hide errors from visitors: ❌Error messages should not be shown to visitors.

### Active Plugins (10) ###

Gravity Forms: by rocketgenius – 2.0.7
 Ianua Projects: by Imagewize – 1.2.1
 Regenerate Thumbnails: by Alex Mills (Viper007Bond) – 2.2.6
 WPML Multilingual CMS: by OnTheGoSystems – 3.6.2
 WooCommerce PayPal Express Checkout Gateway: by Automattic – 1.1.2
 WooCommerce: by Automattic – 2.7.0-beta-3
 WordPress Importer: by wordpressdotorg – 0.6.3
 WPML CMS Nav: by OnTheGoSystems – 1.4.19
 WPML String Translation: by OnTheGoSystems – 2.5.1
 WPML Translation Management: by OnTheGoSystems – 2.2.6

### Settings ###

API Enabled: ✔
 Force SSL: –
 Currency: EUR (€)
 Currency Position: left
 Thousand Separator: ,
 Decimal Separator: .
 Number of Decimals: 2
 Taxonomies: Product Types: external (external)
 grouped (grouped)
 simple (simple)
 variable (variable)
 ### WC Pages ###

Shop base: #235 - /shop/
 Cart: #236 - /cart/
 Checkout: #237 - /checkout/
 My account: #238 - /my-account/

### Theme ###

Name: Ianua
 Version: 1.0.0
 Author URL:
 Child Theme: ❌ – If you're modifying WooCommerce on a parent theme you didn't build personally
 then we recommend using a child theme. See: How to create a child theme

WooCommerce Support: ✔

### Templates ###

Overrides: ianua/archive-product.php version - is out of date. The core version is 2.0.0
 ianua/woocommerce/single-product/product-image.php version 2.6.3 is out of date. The core version is 2.7.0
 ianua/woocommerce/single-product/related.php version 1.6.4 is out of date. The core version is 2.7.0
 ianua/single-product.php version - is out of date. The core version is 1.6.4

Outdated Templates: ❌Learn how to update

So I knew there were things I had to check out or fix. Just did not realize there were quite a few issues I had to deal with.

Product Image Template

So I checked product-image.php as that is where I deal with product images as I should.

Path to file:


and on line 25 I had:

$attachment_ids = $product->get_gallery_attachment_ids();

and as stated get_gallery_attachment_ids is outdated or deprecated. So I replaced it by get_gallery_image_ids . And this worked and the image gallery came back again without the error notice.

get_display_price Deprecated

And then other issues showed up. The function:


is outdated as well. So we had to deal with this too. The exact PHP notice in brief was:

Notice: WC_Product::get_display_price is <strong>deprecated</strong> since version 2.7! Use wc_get_price_to_display instead. in /srv/www/ on line 3828

I found it inside:


on line 1046:

 echo '<div class="six columns tab-whole product-content right"><span class="price">$' . $product->get_display_price() . '</span>';

I have it as part of an action I added as a replacement of

add_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );

Just replacing it with wc_get_price_to_display() got me another error

Fatal error: Uncaught Error: Call to undefined method WC_Product_Simple::wc_get_price_to_display() in /srv/www/ on line 1046

So I added:


which worked. It was inspired by the new:


And this worked like a charm. Will do some more testing later on of course. But let’s move on to the other notices shall we?

product_type called directly

Then I had a product_type called directly notice. Another direct call notice stating this should not be done basically.

[01-Mar-2017 06:55:56 UTC] PHP Notice:  product_type was called <strong>incorrectly</strong>. Product properties should not be accessed directly. Please see <a href="">Debugging in WordPress</a> for more information. (This message was added in version 2.7.) in /srv/www/ on line 4136

NB Woo Poly Integrations had similar issues mentioned in a ticket at their Github repo.

This was in the same extra.php file on line 1066:

 do_action( 'woocommerce_' . $product->product_type . '_add_to_cart' );

That is what happens when you use many filters. Might need to get rid of some of these soon. Anyways, I realized it now has to be


based on /plugins/woocommerce/includes/class-wc-product-simple.php line 33. Again I may need to do some more testing.

Get_related is deprecated

Had a get_related is outdated notice:

[01-Mar-2017 08:18:11 UTC] PHP Notice:  WC_Product::get_related is <strong>deprecated</strong> since version 2.7! Use wc_get_related_products instead. in /srv/www/ on line 3828

line 29 of the theme’s single-product/related.php I had

if ( ! $related = $product->get_related( $posts_per_page ) ) {

wc_get_related_products which again caused a fatal error as it could not find the method. This was I as I had it all wrong and just need to run the function and necessary arguments. So turned it into:

if ( ! $related = wc_get_related_products( $product->get_id(), $args['posts_per_page'] )) {

And now all product were displaying well.


There also seems to be a new file for working with sliders in single products (beta one blog post mentions it here. It is Photoswipe. Somehow the code was injected at the bottom of the page in the footer. So I added my own in woocommerce/single-product/photoswipe.php . One with only the header code:


 * Photoswipe markup
 * This template can be overridden by copying it to yourtheme/woocommerce/single-product/photoswipe.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
 * @author WooThemes
 * @package WooCommerce/Templates
 * @version 2.7.0

This as I use my own flex slider based one. That took care of that issue. I may use it for other projects though.

Backend Product Editing Issues

What I currently do have is working on the product details does not go well. It seems I cannot switch tabs to let’s say inventory or shipping. Will do some testing on this a little later on. Could be the fact that WooCommerce 2.7.0 is beta after all. But that seems to be an Advanced Custom Fields issue as I found this JavaScript error:

Uncaught Error: Option 'ajax' is not allowed for Select2 when attached to a <select> element.
 at String.<anonymous> (select2.js?ver=3.5.2:930)
 at Function.each (jquery.js?ver=1.12.4:2)
 at constructor.prepareOpts (select2.js?ver=3.5.2:928)
 at constructor.prepareOpts (select2.js?ver=3.5.2:2601)
 at constructor.init (select2.js?ver=3.5.2:690)
 at HTMLSelectElement.<anonymous> (select2.js?ver=3.5.2:3391)
 at Function.each (jquery.js?ver=1.12.4:2)
 at jQuery.fn.init.each (jquery.js?ver=1.12.4:2)
 at jQuery.fn.init.$.fn.select2 (select2.js?ver=3.5.2:3378)
 at HTMLSelectElement.<anonymous> (wc-enhanced-select.js?ver=2.7.0:115)


Custom Product Tabs for WooCommerce

Sometimes you need more tabs for your products. Sometimes the descriptions tab, reviews and attributes tab are not enough. You may need a tab with directions on how to use the product, a tab on ingredients of the product or a tab displaying all available sizes. So let’s talk about adding custom product tabs for WooCommerce. How can you add an additional tab to the product page?

WooCommerce Product Tabs Filter

To add a custom product tabs for WooCommerce you can follow WooCommerce’s guidelines and add the following to your functions.php file:

add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
 // Adds the new tab
 $tabs['test_tab'] = array(
 'title' => __( 'New Product Tab', 'woocommerce' ),
 'priority' => 50,
 'callback' => 'woo_new_product_tab_content'

return $tabs;

function woo_new_product_tab_content() {

// The new tab content

echo '<h2>New Product Tab</h2>';
 echo '<p>Here\'s your new product tab.</p>';

You will of course have to adjust the code to your liking. So you should at least:

  • $tabs label
  • title – pick you own title
  • priority – set the priority of the tab – perhaps it should come first?
  • callback – add the name of the function loading the tab data

So something like:

$tabs['ingredients'] = array(
 'title' => __( 'Ingredients' ),
 'priority' => 10,
 'callback' => 'ianua_product_ingredients_tab'

should do the trick just fine.

Tab Contents Callback Function

Inside the code above we also added the function being the one loading the content in the tab:

function woo_new_product_tab_content() {

// The new tab content

echo '<h2>New Product Tab</h2>';
 echo '<p>Here\'s your new product tab.</p>';

So the filter is followed by the function loading the content. Later on we shall see we did not do the same and used a template tag woocommerce_get_template to load the code from another file.

Content to Load

What would you like to load in the tab and how would you like to display it? For that you need to create a function and add it to your functions.php file or include it somehow. You could load custom field data using a custom field added to product pages. And that is what we are going to do and that is also what most developers would do.

Creating Custom Fields

To create the custom field you could use Advanced Custom Fields (free or premium) or GenerateWP (Premium version for meta boxes) for example. Or you use the built in option and generate them on the product page. Does not look really pretty though. You can code them yourself too of course. For just one or two custom fields ACF would be overkill really but you could use it locally to generate the fields and then export them as PHP to add to your theme. AND you would need to include ACF in your theme.

Advanced Custom Fields Custom Field

To create a meta box or custom field in ACF you just to to advanced custom fields in the backend. Code I created in like a minute would be:

if( function_exists('acf_add_local_field_group') ):

acf_add_local_field_group(array (
 'key' => 'group_5881d7c5ba966',
 'title' => 'Product Page Meta Boxes',
 'fields' => array (
 array (
 'key' => 'field_5881d81b4ad68',
 'label' => 'Ingredients',
 'name' => 'ingredients',
 'type' => 'textarea',
 'instructions' => 'Fill in the ingredients for the product here',
 'required' => 0,
 'conditional_logic' => 0,
 'wrapper' => array (
 'width' => '',
 'class' => '',
 'id' => '',
 'default_value' => 'Text to be added here',
 'placeholder' => '',
 'maxlength' => '',
 'rows' => '6',
 'new_lines' => 'wpautop',
 'location' => array (
 array (
 array (
 'param' => 'post_type',
 'operator' => '==',
 'value' => 'product',
 'menu_order' => 0,
 'position' => 'normal',
 'style' => 'default',
 'label_placement' => 'top',
 'instruction_placement' => 'label',
 'hide_on_screen' => '',
 'active' => 1,
 'description' => '',


As stated this will not work without advanced custom fields included in your theme. So if you feel like this is overkill it would be better to add your own code.

Clean Generated Meta Box code

Coding yourself takes some time like I said and there is a site where you can generate a custom field for free. One that uses native code. It has been created by Jeremy Hixon and can be found here. I created one for WooCommerce products with a text area and the code looks like this:


 * Generated by the WordPress Meta Box generator
 * at

function ingredients_get_meta( $value ) {
 global $post;

$field = get_post_meta( $post->ID, $value, true );
 if ( ! empty( $field ) ) {
 return is_array( $field ) ? stripslashes_deep( $field ) : stripslashes( wp_kses_decode_entities( $field ) );
 } else {
 return false;

function ingredients_add_meta_box() {
 __( 'Ingredients', 'ingredients' ),
 __( 'Ingredients', 'ingredients' ),
add_action( 'add_meta_boxes', 'ingredients_add_meta_box' );

function ingredients_html( $post) {
 wp_nonce_field( '_ingredients_nonce', 'ingredients_nonce' ); ?>

<p>Product Ingredients</p>

 <label for="ingredients_product_ingredients_text"><?php _e( 'Product Ingredients Text', 'ingredients' ); ?></label><br>
 <textarea name="ingredients_product_ingredients_text" id="ingredients_product_ingredients_text" ><?php echo ingredients_get_meta( 'ingredients_product_ingredients_text' ); ?></textarea>

function ingredients_save( $post_id ) {
 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
 if ( ! isset( $_POST['ingredients_nonce'] ) || ! wp_verify_nonce( $_POST['ingredients_nonce'], '_ingredients_nonce' ) ) return;
 if ( ! current_user_can( 'edit_post', $post_id ) ) return;

if ( isset( $_POST['ingredients_product_ingredients_text'] ) )
 update_post_meta( $post_id, 'ingredients_product_ingredients_text', esc_attr( $_POST['ingredients_product_ingredients_text'] ) );
add_action( 'save_post', 'ingredients_save' );

 Usage: ingredients_get_meta( 'ingredients_product_ingredients_text' )

It does miss a couple of elements though like how many rows you would like to have and the text domain. And the meta key here is not as we have it inside the filter so that needs adjusting too. The new generator does have the text domain, but the amount of rows is not an automated option yet. Five rows are added by default. But that you could adjust that in the code yourself.

Basic Custom Field

Besides ACF or hand made meta boxes you could just use the built in version as long as aesthetics is not paramount. When you just want to add one in your product you need to make sure custom fields are active in screen options:

Custom Fields Active

and then you will see this block underneath your product text to add a new custom field:

Add a new Custom Field

Make sure the key (= name)  and value are the ones you use in your function to call them inside your theme. And that you of course save the custom field. Once that is done you can load it for all products.

Custom Callback Code

Here is the code to grab the custom field data:

global $woocommerce, $post;
if ( !empty($post->post_content) ) : ?>
 <?php $heading = apply_filters('woocommerce_product_description_heading', __('Product Description', 'woocommerce')); ?>
<h5><?php echo $heading; ?></h5>
<?php echo get_post_meta($post->ID, 'Ingredients', true); ?>
<?php endif; ?>

As you can see we use get_post_meta . That is the best way to grab a meta key or value. We added this code inside a separate ingredients.php file which we added under single-product/tabs and we load it with:

function ianua_product_ingredients_tab() {
 woocommerce_get_template( 'woocommerce/single-product/tabs/ingredients.php' );

but you could also add the code inside the filter itself as is shown above in the basic filter.


If your theme is styled for tabs properly already this should work and look well.  But if not you can always add specific classes andor wrap the code in a div to target that tab or all tabs more specifically. In my case so far it worked fine in several themes out of the box.

Final Custom Product Tab

So if all went well you were able to create a custom product tab for WooCommerce that is loaded under all products, either as a basic custom field, an ACF custom field or a custom generated custom field. And you added the necessary filter and function to load the tab as the next tab in line.


Extending WooCommerce Storefront

When you are installing the Storefront theme as discussed in our earlier post WooCommerce Storefront Theme Configuration you are given a teaser with options to extend WooCommerce Storefront. A couple of enhancements using plugins as well as possible child themes are mentioned. Let’s go through them in this post.

Storefront Enhancing Plugins

Storefront recommend a couple of plugins you can use to extend it, to make it easier to work with this theme as well enhance it with more features. Here is the list of the plugins for extending WooCommerce Storefront:

  • Powerpack ($59)
  • Mega Menus ($39)
  • Reviews ($19)
  • Pricing Tables ($19)
  • Product Hero ($19)
  • Blog Customizer ($19)
  • Parallax Hero ($19)

NB  Addons only works with Storefront

As you can see these are all commercial plugins that you need to pay for. They are not for free as WordPress is. Well, I would say WordPress is not really for free either as it will require your time and $ to make it work for your business too, but that is another debate. Do I think some of these plugins are useful?


Well the Powerpack is not cheap, but it is an interesting extension. It is an addon that basically allows you to customize way more elements of your theme in the customizer without the need for extra coding in a child theme or plugins. What does it allow you to do more besides what you can in Storefront is:

  • header customization including logo, cart and navigation
  • styling – adjust font families, font size color, margins and padding
  • checkout options – option to go for distraction free checkout or keep two step checkout
  • homepage editor – basic homepage editor to add calls to action and configure general layout
  • product page editor – edit product page layout

Powerpack Features

Mega Menus

Must say I find it a bit expensive for a menu enhancement, but it is a solid mega menu that offers multiple options to create a solid mega menu dropdown to show store items with or without images. And it allows you to drag and drop multiple types of widgets inside the menu from the customizer. And Magento has extensions for similar or more expensive prices.


Storefront Mega Menu


A lot of themes have basic reviews built in when they are catering to the e-commerce crowd and there are universal WordPress review plugins out there so you do not really need this one per se. But this is a solid review plugin with multiple display options. You can

  • display it as a slider or in blocks,
  • use three styling options and there is a
  • review scope you can configure to display certain specific reviews, reviews from certain products, load the most ones recent first

Pricing Table

A lot of themes do have pricing tables built in. Either via a page builder like Visual Composer or simply as a custom post type. So what does this addon have to offer that we may like? Well, nothing much really besides the fact that the customizing can be done in the customizer. So I am not that impressed really.

Pricing Tables

Product Hero

This is more like a slider that integrates well with Storefront and WooCommerce. But frankly as I am using Revolution Slider already that can do that and more I do not see the advantage of using this Product Hero slider.

Product Hero

Blog Customizer

The blog customizer is a useful addon. What it does it that it allows you to pick a certain blog layout. You may like the classical one after another blog article look or the magazine look with several next to each other. It also allows you to move the post meta data around. This means you can decide where the sidebar with additional information goes, if the category and tag details should go to the end of the post or just below the title and so on.

However, most multi purpose themes with or without a builder or even with the builder alone will allow you to do this all. So if you are going for a page builder like Beaver Builder or the Visual Composer you can probably go without this addon.

Parallax Hero

Parallax scroll or the display of content parallax style has been popular since 2012 or s0. Designer Depot mentioned this on it in 2013 in a blog post:

parallax scroll is when content scrolls at different speeds, creating a sense of perspective and therefore depth.

Some clients really love it for blogs, others for the homepage. Well, the parallax hero can enhance your Storefront Hero header with the parallax hero scroll effect. I do (no longer ) like this effect and I think it is a bit outdated now. But it is an easy implementation of it. So if you, or your client, likes it go ahead and purchase this addon.

Child Themes

There are a whole bunch of child themes available and all for just $39 bucks. So if the style of Storefront is not appealing to you and you do not want to code your own child theme to change its looks you should have a look at the child themes available.

Storefront Child Themes

Now, I think the WooCommerce team, nowadays a part of Automattic, does a solid job coding these themes and design wise there are some really nice ones. So do have a look. The advantage here is that these all work with Storefront and saves you the extra coding. It may still be needed that you want further tweaks. In that case it is better to convert a child theme into a new version. The only downside as always is that updates for that child theme can then no longer be applied with ease. But hey if the child theme gets you closer to your goal then go for it!

Child Themes in Detail

I won’t be discussing the child themes in detail now. What I will do is that I will create a new post in the future on adding one of these child themes and my and or my client’s experience with that particular theme. This post took quite some time already and is rather large and insightful already so hope you are happy with the content for this blog post as it is for now.