I’m currently wrapping up a new WooCommerce-powered ecommerce website for a client, and thought that I’d share the code I’m using to add multiple new tabs to the product pages.
When I originally went looking for a solution to this challenge I found a couple blog posts by Sean Barton that pointed me in the right direction: How to remove the WooCommerce 2.0+ Reviews tab and Adding your own tabs to Woocommerce and Woothemes. His posts explain in detail how the WooCommerce tab system works, so I won’t try to duplicate that here in this post.
Unless I missed it, his posts didn’t explain how to add multiple tabs, which is what I needed to do for this project. After coming up with my solution and while writing this post I did notice that he has released a plugin for managing multiple tabs. I haven’t tried it, but it’s there if you’d rather use a plugin instead of working directly with the code.
“Ingredients” and “Benefits” tabs
For this project, the tabs I needed to add were “Ingredients” and “Benefits,” as you can see in the screenshot below. The code I’m posting here uses those two labels, and you’ll need to make adjustments to the code as necessary to suit your project.
Add your metaboxes or custom fields first
There’s more involved here than just adding a tab or two, since you also need a way to add content to those tabs. To do that I’m using Custom Metaboxes and Fields for WordPress. I’m not going to go into detail about how to use CMB as there is documentation for that already available, but I will post the specific code that I’m using along with CMB to add custom metaboxes to the WooCommerce product post types.
The first Gist posted below shows how I add the metaboxes to the product post type. For the sake of making it simpler for my client to create and edit the content for those tabs, I’m using the WYSIWYG metabox. This screenshot shows the metaboxes in place on a product edit page.
Now add the product tabs
The second Gist posted below shows the code to add the tabs to your products on the front end. Some things to note:
- If the custom metabox that populates a tab is empty, then that tab will not be displayed on the front end.
- You can rearrange the tabs by changing their priority.
I’m using several functions to sanitize, format, and display the tab content: esc_textarea, htmlspecialchars_decode, and wpautop. If you know of a better or simpler way to do this that still works on the front end, feel free to let me know in the comments below.- After a comment and a question (see below), I’ve updated the code to use
apply_filters( 'the_content', $product_ingredients )
instead of the previous combination of functions described in step 3.
The Code
Gist – Add custom metaboxes to WooCommerce products
Gist – Add multiple product tabs to WooCommerce 2.x
Where to put this code
Add the code to a core functionality plugin (best choice), its own plugin, or functions.php.
Jerome says
Hello mate,
Just wanted to say thanks for this article. Just what i was looking for !!
Cheers.
John Sundberg says
You’re welcome, Jerome!
Afaq Shahid says
Hey mate,
I was planning to deploy this code on my website but after some digging I came across this CMB2 plugin (https://wordpress.org/plugins/cmb2/). Its apparently a completely rewritten version of the CMB you mentioned in the article above. Is it safe to install this plugin and then deploy the code given above? I mean is your code compatible with this CMB2 plugin?
John Sundberg says
Hi Afaq,
Your question is the first I’ve heard of CMB2, but reading through their documentation and support forum it sounds like it’s backward-compatible with CMB code instances. So my guess is that it will work, and if not, it shouldn’t be too hard to tweak the code to make it work.
If you try it, I’d be glad to hear how it went for you.
John
Carmi says
Thanks for the great article. I was able to implement the custom tabs by adding the code to my core function plugin.
However, I can’t get content from the metaboxes to display any short codes, images, links, or HTML generated by the wysiwyg.
Any ideas?
John Sundberg says
Carmi,
Great question.
I looked through the “old” CMB issues on GitHub and found a comment by Bill Erickson regarding his recommendation for outputting content from the WYSIWYG metabox, and I’ve updated the Gist above with that modified code.
I just tested this on a WooCommerce install, and it rendered an image, an unordered list, and paragraphs in the Ingredients tab. I didn’t try a shortcode, but I suspect that will work too.
Bill’s comment on GitHub
Let me know if this works for you.
John
Carmi says
Great. Thank you both. Shortcodes work with this method as well.
Carmi
CiaSea says
Thank you John. I’ve been coding in PHP for 5 years, WordPress however is kinda new to me. Probably I’ll figure it out somehow, thank you for your work. You’ve made some people in the Brazil very happy.
John Sundberg says
CiaSea,
You’re very welcome!
John
Nic says
Hi there.
Great suggestion. I’m not a developer (mostly a googler than a coder myself) and I’m stuck with your code: I was able to get tabs to appear in my product page front-end, but I’m struggle trying to display the tab content.
In the back-end product page I added two fields: a code-text and a oembed area instead of yours WYSIWYG fields. I know I have to edit some line (I read the CMB2 documentation trying with some esc_url or re-writing your echo declaration, but no luck).
Any hint from you by chance?
Anyway, thanks for this tip
Nic
Nic says
My bad, after reading woo themes documentation I figured out by myself. I was messing the custom_tab_content tag
John Sundberg says
Hi Nic,
Glad to hear you were able to solve that one!
John
Nam says
Hi,
I know this should be quite obvious, but what file do I add the 2 code snippets above to?
Thanks!
Nam
John Sundberg says
Hi Nam,
You can add the code snippets to your functions.php file, or create a new plugin, or use a mu-plugin. The first snippet is intended to be used IF you’re using Custom Meta Boxes (the original version, not the updated CMB2).
John
Nam says
Thanks John!
Also, if I wanted to display input text boxes instead of a WYSIWYG metabox what would I need to change?
Thanks again
Nam
John Sundberg says
You’re welcome, Nam.
Change
'type' => 'wysiwyg',
to'type' => 'text',
If you’re using CMB or CMB2, there should be a file called example-functions.php that shows you all the different metabox options.
Nam says
It worked, Cheers John!
YL says
Thanks a lot for the great article and explanation.
I’m totally new to php and wordpress. I simply copied these two code snippets to my function.php file, but it seems I can never get the custom tabs shown even in the back end.
I am not sure if I put them i the right place as i noticed there are two function.php files: one is function.php while another is my theme.function.php… I tried in both files and still cannot make it work.
Highly appreciate any piece of advise and help.
Thanks a million in advance
YL says
Finally, I figured it out myself.
In case any one who runs into the same issue:
I just changed the add_filter( ‘cmb_meta_boxes’, ‘bhww_core_cpt_metaboxes’ ) to add_filter( ‘rwmb_meta_boxes’, ‘bhww_core_cpt_metaboxes’ ), then the codes work like a charm on my theme:)
Thank you thank you thank you for posting this super article.
John Sundberg says
Hi Yasmine,
Glad you figured it out – nice work!
And for anyone else with a similar issue or question, the filter hook for the metaboxes in the code above needs to match the actual filter being hooked to.
John
Jan says
Why does this not work for me?
Copy paste does not work. Should I change the code? how?
John Sundberg says
Hi Jan,
You’ll need to provide more information than you did before I or anyone else can help you figure out why it’s not working for you.
John
July says
Hi, I’m new to wordpress and php … and I need help! I searched for days this issue and finally found your post !!. I copied and pasted the code in functions.php of my theme child, but it does not work. I’ve seen other comments that have had a problem like mine and have solved … But I have no idea how!
Ah! and thanks for sharing your work.
John Sundberg says
Hi July,
What are you using to generate your custom meta boxes? CMB or CMB2? Or something else?
Having asked that, you really haven’t given enough information about your situation for me to understand what is not working.
John
Brad Crawford says
Fantastic!! Great solution. And definitely better than paying $99 for the WooCommerce multiple tabs plugin. Ouch!! I was able to use this with the CMB2 plugin by looking at their example functions.php file and adjusting your code accordingly. Thanks!
John Sundberg says
You’re welcome Brad!
And glad to hear you’ve got it working with CMB2. I’m in the process myself of slowly updating all the sites I maintain to CMB2, and at some point I’ll update the code on this blog post.
John
Deepak M says
Hello John,
Thanks a lot for this tutorial. Even though I’m new to wordpress and PHP was able to make it work with CMB2 with some minor tweaks after reading the their documentation.
Deepak
paul simmons says
Good work john,
The tutorial is very easy to add custom tabs to woocommerce page.
I also came across another plugin (http://bit.ly/1VfqtaI) which enables to add multiple custom tabs to Woocommerce product page. The plugin also allows to add Global tabs and upload custom images.
Jim says
Great article.
Is it also possible to translate the custom tabs with WPML translator?
Thanks.
Jim
John Sundberg says
Hi Jim,
At this point the tab titles are translatable, and should be found in the “woocommerce” text domain for the front end, and “cmb” for the admin. Looking at the code, the h2 tags in the tab content are not translatable at this point, I believe, but it wouldn’t be hard to make them so.
John
John Sundberg says
Jim,
I just updated the code so that those h2 tags are now translatable, in the ‘woocommerce’ text domain.
John
Ashley says
This helped me so much. Thank you!
John Sundberg says
You’re welcome!
Amit says
hello sr
my Qustion is .how was able to add tabs please me guide
John Sundberg says
Amit,
Did you read the article? Everything you need to know to add the tabs is there, along with some other information I linked to in the article.
John
Mike says
Cool – I’ve got this working with cmb2! But what if I want the Ingredients tab to be made up of 5 or 6 metaboxes instead of just one. (I assume there would be some assembly of them I could do in the function where I have some html, then concatentate the value of the first metabox, more html, and so on.)
And can we make 2 text inputs that are related (maybe I should delve more into cmb2 for that)? Like I want to have a section that lists active ingredients, then their purpose, so I was thinking of having 2 text inputs that are married, so to speak (and there can be a different number of active ingredients for each product). This is getting complicated quickly for a total newbie like me!
Mike says
OK, I’ve got the first part, I’ll let you know if I have any luck with the 2nd part…
Mike says
Found it – Groups!
https://github.com/WebDevStudios/CMB2/wiki/Field-Types#group
John Sundberg says
Nice work!
Gabi says
This is a great article, I will be implementing this. Excellent stuff.
Would you happen to know how to force the description tab to always show, even if nothing is in there? I am trying to run some logic that if the field is empty, to then display the information from a custom field function, but it’s not liking the condition 🙁
John Sundberg says
Hi Gabi,
Are you modifying the tabs.php template in templates/single-product/tabs? That’s probably the approach I would take – just be sure to make a copy and put it in a woocommerce folder in your theme directory.
John
Gabi says
John
Thanks for your reply.
Tried doing this on the tabs.php template, description.php and also through functions (all copied to child theme)
The issue that I am having is relatively easy logically, but can’t get it working.
If product description is empty then show custom field.
I think because WordPress hides the tab automatically if there is no content, then this causes an issue.
An alternative solution would probably be if custom field has data, then show instead of the_content() data in the description box.
Does that make sense?
I tried creating a new tab and doing the following;
If custom field is not empty, then show custom field, else show the_content()
No luck though so far.
Thanks very much
John Sundberg says
Gabi,
Check out the function woocommerce_default_product_tabs() in wc-template-functions.php. That’s where the $tabs array is built, which gets passed to tabs.php through a filter hook, woocommerce_product_tabs. You could then add a filter for that filter hook, rewriting the logic for the description tab and returning it to the array.
At least, if I’m understanding what you’re wanting to do correctly, that’s what I would try next.
John
hasan says
Hi i had use this code. but not worked, tab area display in backend but not in front
*** code removed ***
John Sundberg says
Hi Hasan,
Are you using CMB or CMB2 for your metaboxes? This tutorial was written when CMB was still in use, so that could be a factor.
Other than that, I’m not sure what might be happening.
If you post a link to your site I could take a look…
John
Ana says
Hi, could you please help me?, I paste your code in function.php and it doesn´t work, also I paste it in a function plugin neither work. My theme is Divi builder.
I also change the line add_filter( ‘cmb_meta_boxes’, ‘bhww_core_cpt_metaboxes’ ) to add_filter( ‘rwmb_meta_boxes’, ‘bhww_core_cpt_metaboxes’ ), but don`t work.
I have WordPress version 4.6.1 and WooCommerce 2.6.4
I only need a extra Tab, Ingredients.
Thanks a lot
John Sundberg says
Hi Ana,
How are you creating your metaboxes? The filter that you changed, cmb_meta_boxes, is for the CMB plugin, though there is a newer version of that now: CMB2. CMB or CMB2 is a plugin or framework that allows you to create custom metaboxes. If you’re not using that you would need to adapt my code to work with whatever you are using for metaboxes.
John