Add WordPress Settings Without a Plugin
WordPress Settings
In a previous article I covered how to add a settings page to WordPress. Once a settings page is added to WordPress there are five additional steps to adding custom settings without a plugin. They are “adding sections”, “displaying settings”, “adding defaults”, “adding input fields”,“sanitizing input data” and “registering settings with WordPress”. Just like in the previous article, each step is completed by a combination of built-in functions and custom functions outlined below.
Adding the Setting Section
Each group of settings requires a section to place the form fields in. To create a settings section WordPress provides a built-in function called add_settings_section. We will use that function along with two custom functions to add our section. The add_settings_section function has 4 required parameters that I have outlined below.
Parameters
$section_name
The $section_name is a required parameter used by WordPress as a unique identifier for the section. It should be a string value that is namespaced to prevent conflicts with other code. For this tutorial we will use the string “ltdi_theme_settings_section“. The “ltdi” at the beginning of the string is the namespace.
$section_title
The $section_title is a required parameter used by WordPress as a heading for the settings section. It should be a string value formatted for display to the WordPress user. For this tutorial we will use the string “Theme Settings”.
$callback
The $callback is a required parameter. The value should be the name of a callable function that outputs content between the section heading and the section fields. It is primarily used to display an introduction to the user. For this tutorial we will use the value ”ltdi_section_introduction”. Notice that this parameter is also namespaced.
$option_name
The $option_name is a required parameter used by WordPress as a unique identifier for this group of settings. There are a few built-in option names that include “general”, “reading”, “writing”, “discussion”, and “media”. For this tutorial we will use ”ltdi_theme_settings” which will group all our settings in one place in the WordPress database.
<?php
function ltdi_register_settings() {
add_settings_section(
'ltdi_theme_settings_section',
__('Theme Settings', 'ltdi'),
'ltdi_section_introduction'
'ltdi_theme_settings'
);
}
add_action( 'admin_init', 'ltdi_register_settings' );
function ltdi_section_description(){
echo 'This is the Section Introduction'
}
What is this code doing:
- We create the two custom functions, “ltdi_register_settings” and “ltdi_section_description”.
- Within the “ltdi_register_settings” function we place the built-in function “add_settins_section” including all the parameters outlined above.
- Within the “ltdi_section_introduction” function we echo out placeholder content.
- We then use the “ltdi_section_introduction” function name as the third parameter of the “add_settings_section” function.
- Then hook the “ltdi_register_settings” function into the “admin_init” hook.
Displaying the Setting Section
Now that we’ve created the settings section, it can be added to the settings page. In the previous article a custom function called “ltdi_settings_page_callback” was created. Within that function we displayed the page heading “This is the page content” as seen in the example below.
<?php
function ltdi_settings_page_callback() {
echo __('<h1>This is the page content</h1>', 'ltdi');
}
To output the settings section we will modify the previous code by adding three built-in WordPress functions “settings_fields“, “do_settings_sections“ and “submit_button” wrapped in some basic HTML form tags.
settings_fields
The settings_fields function accepts one parameter which matches the $option_name parameter from the add_settings_section function above. It will output all the hidden security fields needed for the settings form.
do_settings_sections
The do_settings_sections function accepts one parameter which also matches the $option_name parameter from the add_settings_section function above. It will eventually output all the form inputs on the page.
submit_button
The submit_button function has no parameters. It will output the submit button for the form.
<?php
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>';
}
What is this code doing:
- We modify the “ltdi_settings_page_callback” function from the previous article to include some HTML to wrap the page.
- We add HTML form tags with a method value of “post” and an action value of “options.php”.
- Within the form tags we include the three built-in WordPress functions that will output our settings form.
Adding the Setting Defaults
It is best practice to provide default values for every custom setting added to WordPress. To do this we will use the built-in functions get_option and add_option.
<?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_field_three' => '',
];
add_option( 'ltdi_theme_settings', $defaults );
}
}
add_action( 'admin_init', 'ltdi_register_settings' );
What is this code doing:
- We continue editing the “ltdi_register_settings” function, just below the code for adding the settings section.
- The first line is a conditional to check the returned value of the function get_option() with the parameter “ltdi_theme_settings”, the unique identifier for the group of settings we are attempting to retrieve.
- If no settings are found the get_options() function will return false.
- If the return value is equal to false, we create an associative array of default values for each of our settings.
- We then use the function add_option(), passing our settings unique identifier and the array of defaults as parameters to add our default settings to the database.
Adding the Setting Input Fields
Each WordPress setting requires an input to change the setting. WordPress provides a built-in function called add_settings_field to add input fields. This function has 4 required and 2 optional parameters that I have outlined below.
Parameters
$setting_name
The $setting_name is a required parameter that is used as a unique identifier for each setting. It should be a string value. For this tutorial we will use the strings “setting_field_one”, “setting_field_two”, and “setting_field_three” from my defaults.
$setting_title
The $setting_title is a required parameter used by WordPress as a label for each field. It should be a string value formatted for display to the WordPress user. For this tutorial we will use the strings “Setting Field One”, “Setting Field Two”, and “Setting Field Three”.
$callback
The $callback is a required parameter. The value should be the name of a callable function that outputs the form input’s HTML you want to use. In this tutorial I am using a text field, so the callback function is named ”ltdi_get_text_field”. Just like previous custom function names, this function is namespaced.
$option_name
The $option_name is a required parameter that tells WordPress what group of settings to add the setting to. For this tutorial we will use the string “ltdi_theme_settings” which matches the $option_name parameter from above where we created the settings section.
$section_name
Although the $section_name parameter is optional, to ensure this field is associated with our section we enter our section’s unique identifier “ltdi_theme_settings_section” to make the connection.
$args ($arguments)
Although the $args parameter is optional, I strongly encourage its use. It should be in the form of an array. There are two built-in keys to this array, “label_for” and “class”. It can also be used to pass additional information to your callback function.
When provided, the “label_for” key is used by WordPress to create HTML label tags around the form label. The provided value will be used as the “for” attribute in that tag.
When provided, the “class” key is used by WordPress to add a custom CSS Class attribute to the wrapping <tr> HTML tags around the input.
<?php
function ltdi_register_settings() {
/* Code for settings section adding defaults goes here. */
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'
]
);
/* Repeat above code for each setting field. */
}
add_action( 'admin_init', 'ltdi_register_settings' );
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
);
};
What is this code doing:
- Within the “ltdi_register_settings” function, just after the code for adding the defaults, we include our first use of the “add_setting_field” function including the parameters for our first setting.
- We repeat this function for each setting we are adding, making sure to update the parameters for each setting.
- We then proceed to create our new “ltdi_get_text_input” callback function for creating our text input.
- The first line of code uses the built-in function “get_option” to attempt to retrieve our settings and assign it back to the $settings variable.
- The second line uses a ternary and the “label_for” parameter to see if the setting value exists.
- If a value exists, it assigns it back to the $value variable, if not it assigns an empty string.
- The function proceeds to output the text field with the assigned value.
Registration and Sanitization
We now have the fields displaying on the page, but there is one last function required to make it all work. If you try to add values and save, you will get an error message that says “Error: The ltdi_theme_settings options page is not in the allowed options list”.
This is because the settings need to be registered for WordPress to recognize them. To get the settings registered requires one built-in function and one custom function.
register_setting
The register_setting function has two required parameters and one optional parameter.
Parameters
$setting_name
The $setting_name is a required parameter that is used as a unique identifier for each setting. It should be a string value. For this tutorial we will use the strings “setting_field_one”, “setting_field_two”, and “setting_field_three” from my defaults.
$option_group
The first parameter $option_group is a required parameter that tells WordPress what settings group to register. It should be a string value that corresponds to an allowed option key name. For this tutorial we will use the string “ltdi_theme_settings” because it is the unique identifier of our settings.
$option_name
The second parameter $option_name is a required parameter and the name of an option to sanitize and save. For this tutorial we use the string “ltdi_theme_settings” because it is also the name of the option we want to save.
$args ($arguments)
The third parameter $args is an array of a few parameters. Although it is not required, for security it is recommended that we use at least one of the $args. The suggested parameter is “sanitize_callback”. It is also a string value and is used by WordPress to sanitize the input value before it is saved to the database. For this tutorial we will use “ltdi_setting_sanitization”.
<?php
function ltdi_register_settings() {
/* Code for settings section, defaults and each setting field goes here. */
register_setting(
'ltdi_theme_settings',
'ltdi_theme_settings',
'ltdi_setting_sanitization'
);
}
add_action( 'admin_init', 'ltdi_register_settings' );
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 );
}
What is this code doing:
- Within the “ltdi_register_settings” function, just after the code for adding each of the form fields, we include the built-in function “register_setting” along with the required parameters.
- We then proceed to create our new “ltdi_setting_sanitization” callback function for sanitizing the input data.
- The first line of code creates an array for storing the validated settings.
- We then loop through each of the incoming settings to see if it has a value.
- If it does, we proceed to strip all HTML tags, PHP tags and properly handle quoted strings.
- Then we assign the value to the $output array.
- Finally we return the $output providing a filter so additional functions can process the data.
Putting It All Together
The final code is available for download on github. 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 three text inputs.
Remember: something as simple as a typo can take down a website. For this reason I recommend plenty of backups. I also recommend using a development environment to test the code before pushing it live.
Receive Tutorials Direct to Your Inbox