Skip to main content
Developer in WordPress t-shirt developing

Adding a Select Input to WordPress Settings

In previous articles in the WordPress Settings series we covered adding a settings page with a few basic fields. Those articles cover the steps to build a settings form with three text inputs, a textarea input, a WP Editor input, and a password input. This article builds on the previous articles by adding a Select input to our existing settings.

Adding the Defaults

In the previous article we covered how every WordPress setting should have a default value assigned and how to add the defaults to your code. Below is an extended version of that code that includes the default settings for our new Select input.

<?php
  
function ltdi_register_settings() {

    /* Code for settings section goes here. */

    if ( false == get_option( 'ltdi_theme_settings' ) ) {
        $defaults = [
            'setting_field_one' 	   => '',
            'setting_field_two' 	   => '',
            'setting_textarea_field' => '',
            'setting_wp_editor_field' => '',
            'setting_password_field' => '',
            'setting_select_field'   => '1', /* new setting */
        ];
        add_option( 'ltdi_theme_settings', $defaults );
    }
}
add_action( 'admin_init', 'ltdi_register_settings' );
  1. We continue editing the “ltdi_register_settings” function from the previous article by adding a key/value pair for our “setting_select_field”.
  2. For this tutorial the default value will be different. Instead of an empty string we will add an actual value. In this case it will be the value of “1”.
  3. Like the previous articles, if no settings are found, the get_options() function will return false.
  4. When a false value is returned from get_option() we use the function add_option(), passing our settings unique identifier and the array of defaults as the first and second parameters respectively.  Doing so will save the default settings to the database.

Adding the Select Input

As mentioned in a previous article’s section “Adding the Setting Input Fields”, each field is added with a combination of the built-in function “add_settings_field” and a callback function for the specific field type.

For the select input we start with the built-in function add_settings_field, using the arguments listed below.

The first argument is the field $name.  It is a required unique identifier for the setting. It should be a single string value usually formatted with underscores to combine multiple words. In this case it is “setting_select_field”.

The second argument is the field $title. It should be a string value formatted for display to the WordPress user.  For this tutorial we will use the string “New Select Setting”.

The third argument is the name of the $callback function that outputs the form input’s HTML. Because we are implementing a Select input we will be using the name “ltdi_get_select_input”.

The fourth argument tells WordPress what group of settings to add the setting to. For this tutorial we will use the string “ltdi_theme_settings” which is the name of our settings group.

The fifth argument tells WordPress what section to associate our setting with. For this tutorial we will use the string “ltdi_theme_settings_section” which is the name of our settings section.

Unlike in the input typs in the previous four articles, the Select input arguments array uses three key/value pairs. The first two, “label_for” and “class” are the same. The third however has a key of “options” and is used to provide the available options to our select input.

<?php

  function ltdi_register_settings() {
      
      /* Code for settings section and adding defaults goes here. */
    
      /* Code that adds the text fields in the previous articles goes here. */
   
      add_settings_field(
          'setting_select_field',
          'New Select Setting',
          'ltdi_get_select_input',
          'ltdi_theme_settings',
          'ltdi_theme_settings_section',
          [
              'label_for' => 'setting_select_field',
              'class' => 'setting_select_field',
		      'options' => [
                  [
				       'value' => '1',
                      'label' => 'Option One'
				   ],
				   [
					   'value' => '2',
					   'label' => 'Option Two'
				   ],
				   [
					   'value' => '3',
					   'label' => 'Option Three'
				   ]
			   ]
          ]  
      );

Adding the Select Callback

Although the field has been added to WordPress, before it can be used we need to create the callback function to output the select input’s HTML on the screen.

<?php

function ltdi_get_select_input($args) {
    $settings = \get_option('ltdi_theme_settings');

	printf(
		'<select id="%1$s" name="ltdi_theme_settings[%1$s]" />',
		$args['label_for']
	);

	foreach ($args['options'] as $option) {
		$selected = selected($settings[$args['label_for']], $option['value'], false);

		printf(
			'<option value="%1$s" %3$s>%2$s</option>',
			$option['value'],
			$option['label'],
			$selected
		);
	}

	echo '</select>';
}
  1. We start by declaring the function “ltdi_get_select_input”.
  2. Withing our new function we use the get_option() function with the argument “ltdi_theme_settings” to retrieve all our settings.
  3. We use the PHP function printf() and the value stored in $args[‘label_for’] to output the opening HTML of the select input.
  4. Then we loop through the “options” available in the $args variable.
    • Directly within the loop we use the selected() WordPress function to determine if the option’s value is the selected value. If so, the value is assigned to the $selected variable.
  5. Then we use the printf() function with the values stored in the $option[‘value’], $option[‘label’] and $selected variables to ouput the HTML for all the options.
  6. We finish by echoing the closing HTML fo the select input.

Putting It All Together

Here is the final code including code from the previous article. What is added in this article is indicated with comment “new code”. When this code is added to your WordPress theme’s function file or your plugin’s main file, you should have a functioning WordPress settings page with two text inputs, one textarea input, one WordPress Editor input, one password input and our new select input.

<?php

function ltdi_register_settings() {
    
    add_settings_section(
        'ltdi_theme_settings_section',
        __('Theme Settings', 'ltdi'),
        'ltdi_section_introduction'
        'ltdi_theme_settings'
    );

    if ( false == get_option( 'ltdi_theme_settings' ) ) {
        $defaults = [
            'setting_field_one' 	   => '',
            'setting_field_two' 	   => '',
            'setting_textarea_field' => '',
            'setting_wp_editor_field' => '',
            'setting_password_field' => '',
            'setting_select_field'   => '1', /* new code */
        ];
        add_option( 'ltdi_theme_settings', $defaults );
    }

    add_settings_field(
        'setting_field_one',
        __('Setting Field One', 'ltdi'),
        'ltdi_get_text_input',
        'ltdi_theme_settings',
        'ltdi_theme_settings_section',
        [
	        'label_for' => 'setting_field_one',
	        'class' => 'setting_field_one'
        ]	
    );

    add_settings_field(
        'setting_field_two',
        __('Setting Field Two', 'ltdi'),
        'ltdi_get_text_input',
        'ltdi_theme_settings',
        'ltdi_theme_settings_section',
        [
            'label_for' => 'setting_field_two',
	        'class' => 'setting_field_two'
        ]
    );

    add_settings_field(
       'setting_password_field',
       'New Password Setting',
       'ltdi_get_password_input',
       'ltdi_theme_settings',
       'ltdi_theme_settings_section',
       [
           'label_for' => 'setting_password_field',
           'class' => 'setting_password_field'
       ]  
    );

    add_settings_field(
        'setting_textarea_field',
        __('New Textarea Setting', 'ltdi'),
        'ltdi_get_textarea_input',
        'ltdi_theme_settings',
        'ltdi_theme_settings_section',
        [
	        'label_for' => 'setting_textarea_field',
	        'class' => 'setting_textarea_field'
        ]	
    );

    add_settings_field(
        'setting_wp_editor_field',
        __('New WP Editor Setting', 'ltdi'),
        'ltdi_get_editor_input',
        'ltdi_theme_settings',
        'ltdi_theme_settings_section',
        [
	        'label_for' => 'setting_wp_editor_field',
	        'class' => 'setting_wp_editor_field'
        ]	
    );

    add_settings_field(
        'setting_select_field',
        'New Select Setting',
        'ltdi_get_select_input',
        'ltdi_theme_settings',
        'ltdi_theme_settings_section',
        [
            'label_for' => 'setting_select_field',
            'class' => 'setting_select_field',
            'options' => [
                [
				   'value' => '1',
                  'label' => 'Option One'
				 ],
				 [
			       'value' => '2',
				   'label' => 'Option Two'
				 ],
				 [
			       'value' => '3',
				   'label' => 'Option Three'
				 ]
			 ]
       ]  
    );

    register_setting(
        'ltdi_theme_settings',
        'ltdi_theme_settings',
        'ltdi_setting_sanitization'
    );
}
add_action( 'admin_init', 'ltdi_register_settings' );


function ltdi_section_introduction() {
    echo 'This is the Section Introduction'
}


function ltdi_get_text_input($args){
    $settings = \get_option('ltdi_theme_settings');
    $value = !empty($settings[$args['label_for']]) ?: '';

    printf(
        '<input type="text" id="%1$s" name="ltdi_theme_settings[%1$s]" value="%2$s" />',
        $args['label_for'],
        $value
    );
};


function ltdi_get_textarea_input($args) {
   $settings = \get_option('ltdi_theme_settings');
   $value    = !empty($settings[$args['label_for']]) ?: '';

   printf(
       '<textarea id="%1$s" name="ltdi_theme_settings[%1$s]" rows="8" cols="100">%2$s</textarea>',
       $args['label_for'],
       $value
   );
}


function ltdi_get_editor_input($args) {
   $settings = \get_option('ltdi_theme_settings');
   $value   = !empty($settings[$args['label_for']]) ? $settings[$args['label_for']] : '';
   $editor_id = 'ltdi_theme_settings[' . $args['label_for'] . ']';
   
   $options = [
		'media_buttons' => false
   ];

   echo \wp_editor($value, $editor_id, $options);
}

function ltdi_get_password_input($args) {
    $settings = \get_option('ltdi_theme_settings');
	$value    = $settings[$args['label_for']] ?? '';

	printf(
		'<input type="password" id="%1$s" name="ltdi_theme_settings[%1$s]" value="%2$s" />',
		$args['label_for'],
		$value
	);
}

/* New Code */
function ltdi_get_select_input($args) {
    $settings = \get_option('ltdi_theme_settings');

	printf(
		'<select id="%1$s" name="ltdi_theme_settings[%1$s]" />',
		$args['label_for']
	);

	foreach ($args['options'] as $option) {
		$selected = selected($settings[$args['label_for']], $option['value'], false);

		printf(
			'<option value="%1$s" %3$s>%2$s</option>',
			$option['value'],
			$option['label'],
			$selected
		);
	}

	echo '</select>';
}


function ltdi_setting_sanitization($input) {
 	$output = [];
    
    foreach( $input as $key => $value ) {

        if (isset( $input[$key])) {
            $output[$key] = strip_tags( stripslashes( $input[ $key ] ) );
        }
    }

    return apply_filters( 'ltdi_setting_validation', $output, $input );
}


function ltdi_settings_page_callback() {
    echo '<div class="wrap">';
    echo __('<h1>This is the page content</h1>', 'ltdi');
    
    echo '<form method="post" action="options.php">';
    settings_fields('ltdi_theme_settings');
    do_settings_sections('ltdi_theme_settings');
    submit_button();
    echo '</form>';
  
    echo '</div>';
}

Receive Tutorials Direct to Your Inbox