How to Add a WooCommerce Settings Tab

WooCommerce Settings Page

In my new role as a WooCommerce Developer I've been spending a good chunk of time auditing 3rd party extensions. One of the surprising parts about the audit process is seeing where developers put their settings. Some developers put them under Settings, some put them under a custom menu item, and some just shimmy it in wherever they can.

If you're building a WooCommerce extension the easiest thing you can do to improve your UI is to put all WooCommerce settings where users can find them – on a new WooCommerce settings tab. Sounds pretty easy but you'd be surprised how many people don't do that.

TLDR: example code at the bottom.

Adding a shiny new WooCommerce settings tab only takes three small steps:

  1. Add your new tab to the array of existing tabs
  2. Create an array of settings and pass them to the output function
  3. Pass that same array to the save settings function

1 – Add a New WooCommerce Settings Tab

The first thing you have to do is add a new settings tab. This is actually pretty easy. You just need to add one extra array item to the woocommerce_settings_tabs_array filter.


<?php
class WC_Settings_Tab_Demo {
public static function init() {
add_filter( 'woocommerce_settings_tabs_array', __CLASS__ . '::add_settings_tab', 50 );
}
public static function add_settings_tab( $settings_tabs ) {
$settings_tabs['settings_tab_demo'] = __( 'Settings Demo Tab', 'woocommerce-settings-tab-demo' );
return $settings_tabs;
}
}
WC_Settings_Tab_Demo::init();

2 – Add Your Settings to the Settings Tab

That creates a brand new tab for you to use. Now you need to populate it with settings. There's a handy function, woocommerce_admin_fields,  that you can call and pass in an array of settings. There's a trick here that you can use to make the next step easier. Create one function that only returns your array of settings and then another function that calls the woocommerce_admin_fields function. You'll thank me in the next step.

You'll see below that I'm passing in four “settings”. Two of them are actual settings, one it a title, and one is a section end. You'll want to look through output_fields() in class-wc-admin-settings.php to see all of the available options.

It should look something like this:


<?php
add_action( 'woocommerce_settings_tabs_settings_tab_demo', 'settings_tab' );
function settings_tab() {
woocommerce_admin_fields( get_settings() );
}
function get_settings() {
$settings = array(
'section_title' => array(
'name' => __( 'Section Title', 'woocommerce-settings-tab-demo' ),
'type' => 'title',
'desc' => '',
'id' => 'wc_settings_tab_demo_section_title'
),
'title' => array(
'name' => __( 'Title', 'woocommerce-settings-tab-demo' ),
'type' => 'text',
'desc' => __( 'This is some helper text', 'woocommerce-settings-tab-demo' ),
'id' => 'wc_settings_tab_demo_title'
),
'description' => array(
'name' => __( 'Description', 'woocommerce-settings-tab-demo' ),
'type' => 'textarea',
'desc' => __( 'This is a paragraph describing the setting. Lorem ipsum yadda yadda yadda. Lorem ipsum yadda yadda yadda. Lorem ipsum yadda yadda yadda. Lorem ipsum yadda yadda yadda.', 'woocommerce-settings-tab-demo' ),
'id' => 'wc_settings_tab_demo_description'
),
'section_end' => array(
'type' => 'sectionend',
'id' => 'wc_settings_tab_demo_section_end'
)
);
return apply_filters( 'wc_settings_tab_demo_settings', $settings );
}

3 – Save Your Settings

So by now you should be able to see your settings on your brand new tab. But if you press the save button you'll notice nothing happens. You still need to hook up the save functionality. Hopefully you took my advice in the last section and you created a separate function which returns an array of settings you just need to pass that exact same array into a save function, woocommerce_update_options().


<?php
add_action( 'woocommerce_update_options_settings_tab_demo', 'update_settings' );
function update_settings() {
woocommerce_update_options( get_settings() );
}

Wrapping it all up

There's really only three steps to this whole process. If you followed along you're all done. Go ahead and replace my dummy settings with your actual settings. I have a complete version here if you had any trouble following along (or if you're lazy and you skipped to the bottom of the page) 🙂


<?php
/
* Plugin Name: WooCommerce Settings Tab Demo
* Plugin URI: https://gist.github.com/BFTrick/b5e3afa6f4f83ba2e54a
* Description: A plugin demonstrating how to add a WooCommerce settings tab.
* Author: Patrick Rauland
* Author URI: http://speakinginbytes.com/
* Version: 1.0
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
class WC_Settings_Tab_Demo {
/
* Bootstraps the class and hooks required actions & filters.
*
*/
public static function init() {
add_filter( 'woocommerce_settings_tabs_array', __CLASS__ . '::add_settings_tab', 50 );
add_action( 'woocommerce_settings_tabs_settings_tab_demo', __CLASS__ . '::settings_tab' );
add_action( 'woocommerce_update_options_settings_tab_demo', __CLASS__ . '::update_settings' );
}
/
* Add a new settings tab to the WooCommerce settings tabs array.
*
* @param array $settings_tabs Array of WooCommerce setting tabs & their labels, excluding the Subscription tab.
* @return array $settings_tabs Array of WooCommerce setting tabs & their labels, including the Subscription tab.
*/
public static function add_settings_tab( $settings_tabs ) {
$settings_tabs['settings_tab_demo'] = __( 'Settings Demo Tab', 'woocommerce-settings-tab-demo' );
return $settings_tabs;
}
/
* Uses the WooCommerce admin fields API to output settings via the @see woocommerce_admin_fields() function.
*
* @uses woocommerce_admin_fields()
* @uses self::get_settings()
*/
public static function settings_tab() {
woocommerce_admin_fields( self::get_settings() );
}
/
* Uses the WooCommerce options API to save settings via the @see woocommerce_update_options() function.
*
* @uses woocommerce_update_options()
* @uses self::get_settings()
*/
public static function update_settings() {
woocommerce_update_options( self::get_settings() );
}
/
* Get all the settings for this plugin for @see woocommerce_admin_fields() function.
*
* @return array Array of settings for @see woocommerce_admin_fields() function.
*/
public static function get_settings() {
$settings = array(
'section_title' => array(
'name' => __( 'Section Title', 'woocommerce-settings-tab-demo' ),
'type' => 'title',
'desc' => '',
'id' => 'wc_settings_tab_demo_section_title'
),
'title' => array(
'name' => __( 'Title', 'woocommerce-settings-tab-demo' ),
'type' => 'text',
'desc' => __( 'This is some helper text', 'woocommerce-settings-tab-demo' ),
'id' => 'wc_settings_tab_demo_title'
),
'description' => array(
'name' => __( 'Description', 'woocommerce-settings-tab-demo' ),
'type' => 'textarea',
'desc' => __( 'This is a paragraph describing the setting. Lorem ipsum yadda yadda yadda. Lorem ipsum yadda yadda yadda. Lorem ipsum yadda yadda yadda. Lorem ipsum yadda yadda yadda.', 'woocommerce-settings-tab-demo' ),
'id' => 'wc_settings_tab_demo_description'
),
'section_end' => array(
'type' => 'sectionend',
'id' => 'wc_settings_tab_demo_section_end'
)
);
return apply_filters( 'wc_settings_tab_demo_settings', $settings );
}
}
WC_Settings_Tab_Demo::init();

28 thoughts on “How to Add a WooCommerce Settings Tab

  1. thanks for the tutorial!

    how can i put multiple fields into one line (e.g. address: first name and last name, and in the next line street and street number (need that for define a pickup address …))

  2. I added a custom type to your code but not able to merge it back. Here is the gist: https://gist.github.com/neo99/eec01b9df3448ee27ee6

    Please feel free to add it back to your gist.

    • Thanks for the code sample! With a quick glance it looks good. I’d rather not merge it into my code sample. I don’t think every user needs a custom setting and would rather not confuse them. I’ll just leave your link here and they can find it that way. 🙂

  3. Hi Patrick,
    Thank you so much for this code. Can you tell me how to add sections inside the custom settings tab? I really need that. I have tried different ways but not got that.

  4. Yep, adding to the Woo interface makes perfect sense. I almost fell into the trap:

    Some developers put them under Settings, some put them under a custom menu item, and some just shimmy it in wherever they can.

    But your post put me right. Cheers \m/

  5. Hey, great post! I am pretty new to PHP and WordPress development and I am just running a few exercises… I don’t really understand what is the right approach to get the settings and actively use them for a plugin.

    • Hi Mirko – well if you’re altering the way WooCommerce works I’d suggest using the code snippet in this post. 🙂

      If you’re creating a whole new plugin it’s pretty common to create your own plugin settings page. To do this you can use the WordPress Settings API. It isn’t the friendliest API so I’d find lots of examples. It’s a bit of a slow learning curve but I think it’s better to go this route rather than use a plugin settings generator which create a lot of garbage code.

      • Hi Patrick,

        the first one, I am trying to add a simple function to WooCommerce.
        But for the sake of my “learning process” I was trying to understand how to load and use the options. Should I add my function inside the same class and refer to variables such as:

        $this->wc_settings_tab_demo_description

        ?

  6. Hello, i liked your tutorial and i just wanted to ask , we do you use static class in this example ? does that make some difference from the regular way of instantiating the class

    thx

  7. I saw different implementation, is there any difference between

    $settings = array(
    'section_title' => array(

    and (without section_title key)

    $settings = array(
    array(

    What is the difference between this API and functions init_form_fields() and init_settings() which are used for Payment and Shipping Gateways? Or it is the same Settings API (options are saved into serialized groups in this case)?

    • Hi Pavel,

      I haven’t tried doing it without the section_title. What is the difference? Please do share. 🙂

      For the Shipping & Payment Gateway APIs I would follow those tutorials. You aren’t creating your own settings page. You’re following a specific set of instructions so that WooCommerce will create it for you.

      I hope that helps! 🙂

  8. Hi Patrick,

    How would this be modified to add a setting to a sub-section of a tab? I’m seeing conflicting approaches in both the official Woo docs and various other articles and I wondered what your take was?

  9. I’m working on a plugin and I need to grab an API URL in various places – like a .php file that is receiving a form via AJAX.

    How do I get the value stored in the settings?

    If I just put global $woocommerce, then var_dump($woocommerce); — I can see the setting I want buried waayyy deep in the object.

    Is there ‘normal’ / ‘best practice’ way to get a value from a stored setting?

    Thanks!

  10. Hi there,

    thanks for the nice guide. I have just noticed that the new tab does not appear on any site that is not the main one on a WP network. Can you think of any reason?

    Thanks

  11. Can you please let me know where are the options saved into the database.

  12. So if I create my own tab like this:
    $settings_tabs[‘my_own_tab’] =

    I have a question about this line… is this woocommerce filter or a custom filter?
    return apply_filters( ‘wc_settings_tab_demo_settings’, $settings );

    Would I just change this to ‘wc_my_own_tab_settings’?

    Thanks

  13. Anyone having a problem after Woocommece 4.2 version?

    PHP Notice: Undefined index: id in /public_html/wp-content/plugins/woocommerce/packages/woocommerce-admin/src/Loader.php on line 865

    Best regards!

  14. Hi, and thanks for the tutorial.

    I would suggest to remove array key, when adding a section title / fields or section end inside $settings array.

    Example:

    ‘section_title’ => array(
    ‘name’ => __( ‘Section Title’, ‘woocommerce-settings-tab-demo’ ),
    ‘type’ => ‘title’,
    ‘desc’ => ”,
    ‘id’ => ‘wc_settings_tab_demo_section_title’
    ),

    Should be just :

    array(
    ‘name’ => __( ‘Section Title’, ‘woocommerce-settings-tab-demo’ ),
    ‘type’ => ‘title’,
    ‘desc’ => ”,
    ‘id’ => ‘wc_settings_tab_demo_section_title’
    ),

    The reason is, when I have tried to add multiple sections, they become sorted randomly, and even “Save changes” button could appear somewhere in the middle of the page.

    Looking at WooCommerce source as reference ( woocommerce/includes/admin/settings/class-wc-settings-accounts.php ), in fact there is also no array keys.

  15. How Can i add multiple sections inside this new tab?

  16. Hi Patrick,

    is it possible to set up some capability for the new added setting tab, so that will only allow some specific role to reach this tab? if it is possible , how to do it ? thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.