Black Friday & Cyber Monday SUPER SALE ALL WEEK:
Grab 40% OFF on plugins
Days
Hours
Minutes
Seconds

How to add custom section & fields in WooCommerce Settings

Add Custom Section & Fields in WooCommerce Settings

There may be a time when you want to define some settings for your WooCommerce plugin or extensions.It’s also possible that you don’t want to have the settings on their own separate page. In such case, you can use the WooCommerce Settings API and define your settings in the WooCommerce settings page itself.

You can create sections for your settings in WooCommerce using the filter ‘woocommerce_get_sections_{tab_name}’. If you want to create a section in the Products tab, you can use woocommerce_get_sections_products‘. Or if you want to create a section in the Accounts section, you can use ‘woocommerce_get_sections_accounts‘ filter.

Let’s create a section for settings in the products tab. Let’s take an example from our previous blog where we saw how to add notice to display remaining amount for free shipping. Suppose we are creating a plugin for that. We will create a settings page for it.

add_filter( 'woocommerce_get_sections_products' , 'freeship_add_settings_tab' );

function freeship_add_settings_tab( $settings_tab ){
     $settings_tab['free_shipping_notices'] = __( 'Free Shipping Notices' );
     return $settings_tab;
}

In the above example, we add the function ‘freeship_add_settings_tab‘ to the hook. We should add a prefix to our functions as it makes them unique and does not contradict other functions of the same name. This function has one parameter – $settings_tab which is an array of the settings tabs.

We define our settings section called ‘free_shipping_notices‘ ( which is the key we defined earlier in the $settings_tab array ) by adding it to the array and our display name will be ‘Free Shipping Notices”. It will now appear in the product settings. But it won’t show anything as we have not created any settings yet.

How to add custom section & fields in WooCommerce Settings - Tyche Softwares

Adding fields to the custom settings page

Now we will add some settings to this section. To create settings we can use ‘woocommerce_get_settings_{tab_name}‘ filter. For the products tab, we will use the filter – ‘woocommerce_get_settings_products‘ .

To add settings we will use the WooCommerce Settings API.  With the API we need to define our fields with some properties in an array. Let’s start with adding a title to our settings page.

add_filter( 'woocommerce_get_settings_products' , 'freeship_get_settings' , 10, 2 );

function freeship_get_settings( $settings, $current_section ) {
         $custom_settings = array();
         if( 'free_shipping_notices' == $current_section ) {

              $custom_settings =  array(

                    array(
                            'name' => __( 'Free Shipping Notices' ),
                            'type' => 'title',
                            'desc' => __( 'Show the free shipping threshold to customers' ),
                            'id'   => 'free_shipping' 
                       )

        );

           return $custom_settings;
       } else {
        	return $settings;
       }

}

In the function get_settings(), we first check if the current section is our defined section called ‘free_shipping_notices“. If it is the current section, we will define our settings in it. Our settings will be defined in an array called $custom_settings. Each field we want to add will be an array of a few property – value pairs. These are the properties we can use to create a field –

  1. name : The name of the field to be displayed on the page.
  2. type : The type of the field ( e.g – text, checkbox, select, multiselect ).
  3. desc : The description for the field which will be displayed next to the field
  4. desc_tip : If set to true, it will display the description in a tooltip
  5. id : A unique id for the field.
  6. class: Class name you want to add to the field
  7. css: Add inline css to the field

The type to display a title in the settings is ‘title’. We give it a name, desc & a unique id. Our settings section will now look like this –

How to add custom section & fields in WooCommerce Settings - Tyche Softwares

Now, we need to add some fields for our settings. For our ‘Free Shipping Notices’ example, we will add the following fields –

  1.  A checkbox to enable the free shipping notice
  2. A text field to define the message to be displayed on the product page
  3. A text field to set the message to be displayed after reaching the threshold.
  4. A dropdown to select the position for the notice
  5. A color picker to set the font color
function freeship_get_settings( $settings, $current_section ) {
        $custom_settings = array();

        if( 'free_shipping_notices' == $current_section ) {

        	$custom_settings =  array(

            array(
                'name' => __( 'Free Shipping Notices' ),
                'type' => 'title',
                'desc' => __( 'Show the free shipping threshold to customers' ),
                'id'   => 'free_shipping' 
            ),

            array(
                'name' => __( 'Enable Free shipping notices' ),
                'type' => 'checkbox',
                'desc' => __( 'Show the free shipping threshold on product page'),
                'id'	=> 'enable'

            ),

            array(
                'name' => __( 'Message' ),
                'type' => 'text',
                'desc' => __( 'Message to display on the notice'),
                'desc_tip' => true,
                'id'	=> 'msg_threshold'

            ),

            array(
                'name' => __( 'Message when free shipping reached' ),
                'type' => 'text',
                'desc' => __( 'Message to display when free shipping is reached'),
                'desc_tip' => true,
                'id'	=> 'msg_free'

            ),

            array(
                'name' => __( 'Position' ),
                'type' => 'select',
                'desc' => __( 'Position of the notice on the product page'),
                'desc_tip' => true,
                'id'	=> 'position',
                'options' => array(

                          'top' => __( 'Top' ),
                          'bottom' => __('Bottom')

                )

            ),
            
            array(
                'name' => __( 'Text Color' ),
                'type' => 'color',
                'desc' => __( 'Color of the text in the notice'),
                'desc_tip' => true,
                'id'	=> 'color',

            ),

             array( 'type' => 'sectionend', 'id' => 'free_shipping' ),

    );

        return $custom_settings;
     } else {
        	return $settings;
    }
}

As you can see, we defined an array of five arrays for our five fields. At the end, we make sure we end the section using the ‘sectionend’ type and giving it the id of our section.

Our Settings section will now look like this –

How to add custom section & fields in WooCommerce Settings - Tyche Softwares

These settings will be saved in our ‘wp_options‘ table. If we want to access these values we will use the get_option() function. For example, if we want the value of Message field which has the id – ‘msg_threshold’, we can access it using – get_option( ‘msg_threshold’ ).

The pre-defined values for ‘type’ are – text, checkbox, select, multiselect, textarea, radio, single_select_country, multi_select_countries, etc. Now, if you want to add a field other than these, you need to define them using the hook ‘woocommerce_admin_field_{type}’. The type we add in the hook will be same as the type we will define in our array.

Let’s add a button field in our settings. For this, we will use the hook ‘woocommerce_admin_field_button‘.

add_action( 'woocommerce_admin_field_button' , 'freeship_add_admin_field_button' );

function freeship_add_admin_field_button( $value ){
                $option_value = (array) WC_Admin_Settings::get_option( $value['id'] );
                $description = WC_Admin_Settings::get_field_description( $value );
                
                ?>
               
                <tr valign="top">
                    <th scope="row" class="titledesc">
                        <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo esc_html( $value['title'] ); ?></label>
                        <?php echo  $description['tooltip_html'];?>
                    </th>
                    
                    <td class="forminp forminp-<?php echo sanitize_title( $value['type'] ) ?>">
                
                         <input
                                name ="<?php echo esc_attr( $value['name'] ); ?>"
                                id   ="<?php echo esc_attr( $value['id'] ); ?>"
                                type ="submit"
                                style="<?php echo esc_attr( $value['css'] ); ?>"
                                value="<?php echo esc_attr( $value['name'] ); ?>"
                                class="<?php echo esc_attr( $value['class'] ); ?>"
                        /> 
                        <?php echo $description['description']; ?>
                       
                    </td>
                </tr>

           <?php       
}

In the above example, the function add_admin_field_button() takes one parameter – $value. The $value parameter is the array of the field we define in the get_settings() function. So, if we want the value of the type property in the array, we will get it using $value[‘type’].

In this function, we create an input field of type submit and the values for its attributes will be fetched from the array we define for our settings field. So, we will add one more field in our settings of type ‘button’.

<?php
function freeship_get_settings( $settings, $current_section ) {
        $custom_settings = array();

        if( 'free_shipping_notices' == $current_section ) {

        	$custom_settings =  array(

            array(
                'name' => __( 'Free Shipping Notices' ),
                'type' => 'title',
                'desc' => __( 'Show the free shipping threshold to customers' ),
                'id'   => 'free_shipping' 
            ),

            array(
                'name' => __( 'Enable Free shipping notices' ),
                'type' => 'checkbox',
                'desc' => __( 'Show the free shipping threshold on product page'),
                'id'	=> 'enable'

            ),

            array(
                'name' => __( 'Message' ),
                'type' => 'text',
                'desc' => __( 'Message to display on the notice'),
                'desc_tip' => true,
                'id'	=> 'msg_threshold'

            ),

            array(
                'name' => __( 'Message when free shipping reached' ),
                'type' => 'text',
                'desc' => __( 'Message to display when free shipping is reached'),
                'desc_tip' => true,
                'id'	=> 'msg_free'

            ),

            array(
                'name' => __( 'Position' ),
                'type' => 'select',
                'desc' => __( 'Position of the notice on the product page'),
                'desc_tip' => true,
                'id'	=> 'position',
                'options' => array(

                     'top' => __( 'Top' ),
                     'bottom' => __('Bottom')

                )

            ),

            array(
                'name' => __( 'Activate' ),
                'type' => 'button',
                'desc' => __( 'Activate plugin'),
                'desc_tip' => true,
                'class' => 'button-secondary',
                'id'	=> 'activate',

            ),
            
            array(
                'name' => __( 'Text Color' ),
                'type' => 'color',
                'desc' => __( 'Color of the text in the notice'),
                'desc_tip' => true,
                'id'	=> 'color',

            ),


             array( 'type' => 'sectionend', 'id' => 'free_shipping' ),

             );

    return $custom_settings;
     } else {
        return $settings;
     }

}

The values of all the properties in this array will be substituted in the input field in our function and the button will be displayed in the settings.

How to add custom section & fields in WooCommerce Settings - Tyche Softwares

In this way, we can add any type of field in the settings. As I said earlier, these values will saved in the wp_options table. You can see how all the types such as text, checkbox, etc are defined here.

Our Deposits for WooCommerce plugin settings are created in the same way under the Products section.

How to add custom section & fields in WooCommerce Settings - Tyche Softwares

It’s not necessary to create the settings section under the Products tab. You can create it anywhere you want. You can also create a whole new section similar to Products for your settings. But if there aren’t many settings, it’s best to create a section inside any of the existing tabs.

Browse more in: WooCommerce, Code Snippets, WooCommerce How Tos, WooCommerce Tutorials

Share It:

Subscribe
Notify of
5 Comments
Newest
Oldest
Inline Feedbacks
View all comments
Sanjay Singh
4 years ago

Thanks 😉

4 years ago

How to hide save changes button or disable it?

Editor
7 months ago
Reply to  Abhi

Hi,

You would need to write custom code in order to do that, it’s beyond the scope of this article.

zami
4 years ago

you are using $current_section var . but i copied it and found an error.
Warning: call_user_func_array() expects parameter 1 to be a valid callback, array must have exactly two members in C:\xampp\htdocs\wordpress\wp-includes\class-wp-hook.php on line 290

Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\wordpress\wp-content\plugins\woocommerce\includes\admin\class-wc-admin-settings.php on line 206
how can i solve it ?

Editor
7 months ago
Reply to  zami

This code has been tested in 2023 on the Storefront theme, with WordPress 6.3 and WooCommerce 8.0.3. It worked for us, with no such warnings.

Last edited 7 months ago by Anubha Bhat
5
0
Would love your thoughts, please comment.x
()
x