Skip to content

Instantly share code, notes, and snippets.

@renventura
Created December 26, 2017 02:52
Show Gist options
  • Save renventura/ff93a87f8779457b72ff4dc0366ba053 to your computer and use it in GitHub Desktop.
Save renventura/ff93a87f8779457b72ff4dc0366ba053 to your computer and use it in GitHub Desktop.
Implement a custom WooCommerce settings page, including page sections
<?php
/**
* WooCommerce settings page
*
* This code creates a full WooCommerce settings page by extending the WC_Settings_Page class.
* By extending the WC_Settings_Page class, we can control every part of the settings page.
*
* @author Ren Ventura <renventura.com>
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'RV_Custom_WooCommerce_Settings_Page' ) ) :
class RV_Custom_WooCommerce_Settings_Page extends WC_Settings_Page {
public function __construct() {
$this->id = 'settings-page-slug';
$this->label = __( 'Settings Page Title', 'text-domain' );
/**
* Define all hooks instead of inheriting from parent
*/
// parent::__construct();
// Add the tab to the tabs array
add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 99 );
// Add new section to the page
add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_sections' ) );
// Add settings
add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
// Process/save the settings
add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
}
/**
* Get sections
*
* @return array
*/
public function get_sections() {
// Must contain more than one section to display the links
// Make first element's key empty ('')
$sections = array(
'' => __( 'Overview', 'text-domain' ),
'license' => __( 'License', 'text-domain' )
);
return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections );
}
/**
* Output sections
*/
public function output_sections() {
global $current_section;
$sections = $this->get_sections();
if ( empty( $sections ) || 1 === sizeof( $sections ) ) {
return;
}
echo '<ul class="subsubsub">';
$array_keys = array_keys( $sections );
foreach ( $sections as $id => $label ) {
echo '<li><a href="' . admin_url( 'admin.php?page=wc-settings&tab=' . $this->id . '&section=' . sanitize_title( $id ) ) . '" class="' . ( $current_section == $id ? 'current' : '' ) . '">' . $label . '</a> ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
}
echo '</ul><br class="clear" />';
}
/**
* Get settings array
*
* @return array
*/
public function get_settings() {
global $current_section;
$settings = array();
if ( $current_section == 'license' ) {
$settings = array(
/**
* For settings types, see:
* https://github.com/woocommerce/woocommerce/blob/fb8d959c587ee95f543e682e065192553b3cc7ec/includes/admin/class-wc-admin-settings.php#L246
*/
// License input
array(
'title' => __( 'License Settings', 'text-domain' ),
'type' => 'title',
'desc' => __( 'Manage your license settings for the WooCommerce Custom Redirects plugin.', 'text-domain' ),
'id' => 'woocommerce_redirects_license_settings'
),
array(
'title' => __( 'License Key', 'text-domain' ),
'type' => 'text',
'desc' => __( 'Add your license key.', 'text-domain' ),
'desc_tip' => true,
'id' => 'woocommerce_redirects_license',
'css' => 'min-width:300px;',
),
array(
'type' => 'sectionend',
'id' => 'woocommerce_redirects_license_settings'
),
);
} else {
// Overview
$settings = array();
}
return apply_filters( 'woocommerce_get_settings_' . $this->id, $settings );
}
/**
* Output the settings
*/
public function output() {
$settings = $this->get_settings();
WC_Admin_Settings::output_fields( $settings );
}
/**
* Process save
*
* @return array
*/
public function save() {
global $current_section;
$settings = $this->get_settings();
WC_Admin_Settings::save_fields( $settings );
if ( $current_section ) {
do_action( 'woocommerce_update_options_' . $this->id . '_' . $current_section );
}
}
}
endif;
new RV_Custom_WooCommerce_Settings_Page;
@robertpassaro
Copy link

This is great. Thanks. One little addition -- it's sometimes finicky to get to work, if you include it on the wrong hook. The following worked for me, as the default Woo setting tabs are kept in an array of included classes that you can filter, like so, to include you custom class as a new element the array:

add_filter( 'woocommerce_get_settings_pages', 'load_custom_settings_tab' );

function load_custom_settings_tab( $settings ) {
$settings[] = include plugin_dir_path( dirname( FILE ) ) . 'some-directory/class-rv-custom-woocommerce-settings-page.php';
return $settings;
}

@UVLabs
Copy link

UVLabs commented Jun 20, 2021

This is great. Thanks. One little addition -- it's sometimes finicky to get to work, if you include it on the wrong hook. The following worked for me, as the default Woo setting tabs are kept in an array of included classes that you can filter, like so, to include you custom class as a new element the array:

add_filter( 'woocommerce_get_settings_pages', 'load_custom_settings_tab' );

function load_custom_settings_tab( $settings ) {
$settings[] = include plugin_dir_path( dirname( FILE ) ) . 'some-directory/class-rv-custom-woocommerce-settings-page.php';
return $settings;
}

I used this method as well.

@WebsiteDons
Copy link

That's somewhat long and complex though. The current single method get_settings_for_default_section() is much cleaner and to the point

<?php
defined('ABSPATH') || exit;

if ( class_exists('WC_Settings_Userfields', false) ) {
	return new WC_Settings_Userfields();
}

class WC_Settings_Userfields extends WC_Settings_Page 
{
	public function __construct() {
		$this->id    = 'userfields';
		$this->label = __('User Fields', 'woocommerce');

		parent::__construct();
	}

	protected function get_settings_for_default_section() 
	{
		$settings = [
			[
				'type'  => 'title',
				'id'    => 'custom_reg_fields',
				'title' => __('Enable Special User Registration Fields', 'woocommerce'),
				'desc'  => __('Choose fields to display in the registration form.', 'woocommerce'),
			],
				[
					'type'     => 'checkbox',
					'id'       => 'woocommerce_reg_phone',
					'default'  => '',
					'title'    => __('Phone', 'woocommerce'),
					'desc'     => __('Get user phone for text alerts.', 'woocommerce')
				],
				[
					'type'     => 'checkbox',
					'id'       => 'woocommerce_reg_gender',
					'default'  => '',
					'title'    => __('Gender', 'woocommerce'),
					'desc'     => __('User gender.', 'woocommerce')
				],
				[
					'type'     => 'checkbox',
					'id'       => 'woocommerce_reg_photo',
					'default'  => '',
					'title'    => __('Photo', 'woocommerce'),
					'desc'     => __('Upload image for user avatar.', 'woocommerce')
				],
			['type'=>'sectionend','id'=>'custom_reg_fields']
		];

		return apply_filters('woocommerce_userfields_settings', $settings);
	}

}

return new WC_Settings_Userfields();

Register the page

via theme functions.php or in plugin

if( is_admin() ) {
add_filter('woocommerce_get_settings_pages', function($settings) {
	$settings[] = include INCPATH.'/class-wc-settings-userfields.php';
	return $settings;
});
}

Result

2023-02-11 16_16_04

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment