Sometimes it’s a good idea to have custom options/settings all in one page in admin panel. Those options then can be used anywhere when developing themes or plugins. I.e. those options can be values that are likely to change in future, so that you or someone else wouldn’t have to change it everywhere if it was hardcoded. To create WordPress settings page for custom options is fairly easy, everything can be done in functions.php file in your theme.

Create PHP Class For Settings Page

For better maintainability of our code, let’s create a PHP class in separate file called CustomSettingsPage.php in theme folder.

The class would look like this:

<?php

// wp-content/themes/YourTheme/CustomSettingsPage.php

class CustomSettingsPage
{
    /**
     * Array of custom settings/options
     */
    private $options;

    /**
     * Constructor
     */
    public function __construct()
    {
        add_action( 'admin_menu', array( $this, 'add_settings_page' ) );
        add_action( 'admin_init', array( $this, 'page_init' ) );
    }

    /**
     * Add settings page
     * The page will appear in "Settings" menu dropdown
     */
    public function add_settings_page()
    {
        add_options_page(
            'Custom Settings', // Page title
            'Custom Settings Page', // Title
            'manage_options', // Capability
            'custom-settings-page', // Url slug
            array( $this, 'create_admin_page' ) // Callback
        );
    }

    /**
     * Options page callback
     */
    public function create_admin_page()
    {
        // Set class property
        $this->options = get_option( 'custom_settings' );
        ?>
        <div class="wrap">
            <h2>Custom settings page</h2>           
            <form method="post" action="options.php">
            <?php
                // This prints out all hidden setting fields
                settings_fields( 'custom_settings_group' );   
                do_settings_sections( 'custom-settings-page' );
                submit_button(); 
            ?>
            </form>
        </div>
        <?php
    }

    /**
     * Register and add settings
     */
    public function page_init()
    {        
        register_setting(
            'custom_settings_group', // Option group
            'custom_settings', // Option name
            array( $this, 'sanitize' ) // Sanitize
        );

        add_settings_section(
            'custom_settings_section', // ID
            'Custom Settings', // Title
            array( $this, 'custom_settings_section' ), // Callback
            'custom-settings-page' // Page
        );

        add_settings_field(
            'custom_setting_1', // ID
            'Custom Setting 1', // Title 
            array( $this, 'custom_setting1_html' ), // Callback
            'custom-settings-page', // Page         
            'custom_settings_section'
        );      

        add_settings_field(
            'custom_setting_2', 
            'Custom Setting 2', 
            array( $this, 'custom_setting2_html' ), 
            'custom-settings-page',
            'custom_settings_section'
        );      
    }

    /**
     * Sanitize POST data from custom settings form
     *
     * @param array $input Contains custom settings which are passed when saving the form
     */
    public function sanitize( $input )
    {
        $sanitized_input= array();
        if( isset( $input['custom_setting_1'] ) )
            $sanitized_input['custom_setting_1'] = sanitize_text_field( $input['custom_setting_1'] );

        if( isset( $input['custom_setting_2'] ) )
            $sanitized_input['custom_setting_2'] = sanitize_text_field( $input['custom_setting_2'] );

        return $sanitized_input;
    }

    /** 
     * Custom settings section text
     */
    public function custom_settings_section()
    {
        print('Some text');
    }

    /** 
     * HTML for custom setting 1 input
     */
    public function custom_setting1_html()
    {
        printf(
            '<input type="text" id="custom_setting_1" name="custom_settings[custom_setting_1]" value="%s" />',
            isset( $this->options['custom_setting_1'] ) ? esc_attr( $this->options['custom_setting_1']) : ''
        );
    }

    /** 
     * HTML for custom setting 2 input
     */
    public function custom_setting2_html()
    {
        printf(
            '<input type="text" id="custom_setting_2" name="custom_settings[custom_setting_2]" value="%s" />',
            isset( $this->options['custom_setting_2'] ) ? esc_attr( $this->options['custom_setting_2']) : ''
        );
    }
}

Let’s instantiate this class in our functions.php file:

// functions.php

// ...

if( is_admin() ){
	require 'CustomSettingsPage.php';

	new CustomSettingsPage();
}

Now you can navigate in admin panel Settings->Custom Settings Page to what we have created.

Basically, these options are saved in wp_options table in database. Here we have created custom_settings group to have custom_setting_1 and custom_setting_2, which are serialized and stored in one record.

When you will want to get those options somewhere else, just use get_option function, like this:

$custom_settings = get_option( 'custom_settings' );
$custom_setting_1 = $custom_settings['custom_setting_1'];
$custom_setting_2 = $custom_settings['custom_setting_2'];

 

And that’s it! Now you have an easy way to handle custom options so that you or your client would have a flexible way to change those values in future.