This question comes in from blog reader Wilgert (thanks Wilgert!):
could you help me find some simple code to add a custom option field to the general settings tab of the woocommerce admin area? Trying to avoid re-inventing the wheel here.
Well, this may be more than you bargained for, but here we go! The WooCommerce settings can be found under the menu item WooCommerce > Settings and look like so:
Like a lot of WooCommerce these settings can be customized thanks to a variety of actions and filters. For the main settings tabs there are 7 important filters to consider:
woocommerce_general_settings
woocommerce_catalog_settings
woocommerce_page_settings
woocommerce_inventory_settings
woocommerce_tax_settings
woocommerce_shipping_settings
woocommerce_payment_gateways_settings
woocommerce_email_settings
As you can see, one for each of the major tabs, excluding the final “Integration” tab, which is handled elsewhere.
Each of those filters accepts and returns the same nested array data structure, which describes the options and headings shown on the Settings tabs, allowing you easily modify, remove and even add your own custom settings (and even whole new sections of settings). Here’s an example snippet showing some of the common types of settings fields: a dropdown, a text input and a checkbox:
array( array( 'name' => __( 'Pricing Options', 'woocommerce' ), 'type' => 'title', 'desc' => __('The following options affect how prices are displayed on the frontend.', 'woocommerce'), 'id' => 'pricing_options' ), array( 'name' => __( 'Currency Position', 'woocommerce' ), 'desc' => __( 'This controls the position of the currency symbol.', 'woocommerce' ), 'id' => 'woocommerce_currency_pos', 'css' => 'min-width:150px;', 'std' => 'left', // WooCommerce < 2.0 'default' => 'left', // WooCommerce >= 2.0 'type' => 'select', 'options' => array( 'left' => __( 'Left', 'woocommerce' ), 'right' => __( 'Right', 'woocommerce' ), 'left_space' => __( 'Left (with space)', 'woocommerce' ), 'right_space' => __( 'Right (with space)', 'woocommerce' ) ), 'desc_tip' => true, ), array( 'name' => __( 'Thousand separator', 'woocommerce' ), 'desc' => __( 'This sets the thousand separator of displayed prices.', 'woocommerce' ), 'id' => 'woocommerce_price_thousand_sep', 'css' => 'width:30px;', 'std' => ',', // WooCommerce < 2.0 'default' => ',', // WooCommerce >= 2.0 'type' => 'text', 'desc_tip' => true, ), array( 'name' => __( 'Trailing zeros', 'woocommerce' ), 'desc' => __( 'Remove zeros after the decimal point. e.g. <code>$10.00</code> becomes <code>$10</code>', 'woocommerce' ), 'id' => 'woocommerce_price_trim_zeros', 'std' => 'yes', // WooCommerce < 2.0 'default' => 'yes', // WooCommerce >= 2.0 'type' => 'checkbox' ), array( 'type' => 'sectionend', 'id' => 'pricing_options' ), );
Which will render roughly like:
By inspecting the settings data structure we see that it consists of an array of arrays, where each child array represents an element (heading, field or section end) on the settings page. A section of settings starts with an array with a type ‘title’, containing a ‘name’, ‘desc’ description and unique ‘id’. Any subsequent arrays are part of that section until we hit a special array with type ‘sectionend’ and an ‘id’ matching that of the starting section element.
The individual settings fields are given as arrays with a number of common arguments, along with some optional ones depending on the field ‘type’:
- type
- (string) Required field type with some common options: ‘text’, ‘color’, ‘image_width’, ‘select’, ‘checkbox’, ‘textarea’. Also some special case options: ‘single_select_page’, ‘single_select_country’, ‘multi_select_countries’. And you can even define your own custom type, providing the implementation via the
woocommerce_admin_field_{mytype}
action. - Note: WooCommerce 2.0 introduces some new types: ‘email’, ‘pasword’, ‘number’, ‘multiselect’ and ‘radio’.
- name
- (string) The displayed field name
- Note: In WooCommerce 2.0 ‘name’ is replaced by a new field ‘title’, however the new ‘title’ field defaults to ‘name’, so for now at least you’re safe using ‘name’ and compatible with both WC 1.6.6 and previous as well as WC 2.0+
- title
- (string) WooCommerce 2.0 only This replaces the ‘name’ field in WooCommerce 2.0+, but defaults to ‘name’ if that field is provided.
- id
- (string) Unique field identifier, used to retrieve the field from the database options table
- class
- (string) Optional field class names
- css
- (string) Optional field custom css
- std
- (mixed) Optional field default value if the field type is ‘text’, ‘color’, ‘image_width’, ‘select’ or ‘textarea’. This can be a string, numeric or array depending on the option field ‘type’
- Removed in upcoming WooCommerce 2.0
- default
- (mixed) Field default value. This can be a string, numeric or array depending on the option field ‘type’
- This more appropriately named argument is available only for WooCommerce 2.0 and is available for all field types. For now just use both ‘std’ and ‘default’ with the same value
- desc
- (string) Optional field description, displayed next to the input element, or used as the tooltip, depending on ‘desc_tip’
- desc_tip
- (boolean|string) If
true
and ‘desc’ is provided, ‘desc’ will be used as the field tool tip. If a string is used it will be set as the tool tip. - Note: With WooCommerce 2.0+ you can have both a description and tooltip by using strings for each.
- options
- (array) Associative array of option name to value, this is used for the ‘select’, ‘multiselect’ or ‘radio’ field types
- checkboxgroup
- (string) Optional for fields of type ‘checkbox’, value can be one of ‘start’, ” or ‘end’. This is used to create a grouping of checkboxes under a single title/name, and for purposes of showing/hiding some checkboxes based on whether another is checked or not. This allows you to create options that are only visible if another option is checked or not checked.
- show_if_checked
- (string) Show a checkbox if another is checked. Optional for fields of type ‘checkbox’ that are part of a ‘checkboxgroup’, value can be one of ‘option’, ‘yes’ or ‘no’ (default). Only one checkbox in a checkboxgroup should be marked as ‘option’: this is the checkbox that controls the visibility of the others which have a value of ‘yes’.
- hide_if_checked
- (string) Hide a checkbox if another is checked. Optional for fields of type ‘checkbox’ that are part of a ‘checkboxgroup’, value can be one of ‘option’, ‘yes’ or ‘no’ (default). Only one checkbox in a checkboxgroup should be marked as ‘option’: this is the checkbox that controls the visibility of the others which have a value of ‘yes’.
I know there are a lot of possible arguments, with all different values which can be confusing and compounded by the changes with upcoming WooCommerce 2.0, but if you ever have any doubts about how something works, or what options you have, take a look at the woocommerce_admin_fields()
function found in woocommerce/admin/woocommerce-admin-settings.php
. Also the full set of WooCommerce settings can be found in the woocommerce/admin/settings/settings-init.php
file and is a great starting point to find an example close to what you want to do.
Remember that if the above standard fields don’t do quite what you’re looking for you can always define your own totally custom option type along with whatever custom arguments you want, by hooking into the woocommerce_admin_field_{mytype}
action.
Any setting field value can be retrieved from the database by using the standard WordPress get_option()
function with the option’s ‘id’. Ie:
$woocommerce_price_trim_zeros = get_option( 'woocommerce_price_trim_zeros' );
Example
Now with all the formalities and background taken care of, how do we actually add a custom setting option you ask? It’s a simple matter of hooking onto the particular settings filter depending on what tab you want, and adding the option in at the appropriate place in the settings array. Here’s some code from my Sequential Order Numbers Pro plugin which adds a text option named “Order Number Start” to the “General” tab before the end of the “General Options” section:
add_filter( 'woocommerce_general_settings', 'add_order_number_start_setting' ); function add_order_number_start_setting( $settings ) { $updated_settings = array(); foreach ( $settings as $section ) { // at the bottom of the General Options section if ( isset( $section['id'] ) && 'general_options' == $section['id'] && isset( $section['type'] ) && 'sectionend' == $section['type'] ) { $updated_settings[] = array( 'name' => __( 'Order Number Start', 'wc_seq_order_numbers' ), 'desc_tip' => __( 'The starting number for the incrementing portion of the order numbers, unless there is an existing order with a higher number.', 'wc_seq_order_numbers' ), 'id' => 'woocommerce_order_number_start', 'type' => 'text', 'css' => 'min-width:300px;', 'std' => '1', // WC < 2.0 'default' => '1', // WC >= 2.0 'desc' => __( 'Sample order number: AA-20130219-000-ZZ', 'wc_seq_order_numbers' ), ); } $updated_settings[] = $section; } return $updated_settings; }
Which will look like:
Your custom option setting will be automatically saved to the database to the standard WordPress options table with the field ‘id’ as the option name. Retrieve it using the standard WordPress get_option()
function. Just don’t forget that if you use a default value for your setting that you’ll have to either set that value with an “install” function, or use it as the second parameter when retrieving your option from the database. For instance:
$order_number_start = get_option( 'woocommerce_order_number_start', 1 );
The post Add Custom Options to WooCommerce Settings appeared first on Fox Run Software.