How To Create A Simple WordPress Theme Options Page

While we are a huge fan of the WordPress customizer for adding theme options some people prefer a simple admin panel for their theme or are looking to incorporate a basic admin panel in addition to the Customizer. In this post I’ll show you how you can easily create your own admin panel using the WordPress native settings API via a simple class that can be easily extended to add more options. This is not so much of a tutorial but more of a starter code that you can use to create your admin panel so you should know your way around code before getting started 😉

Creating The Theme Options Panel

Below is a class you can use to create your admin panel. The class will add a new theme options panel with 3 different settings for an example (checkbox, input and select). Simply insert the following code right into your functions.php file at the very bottom or create a new file and then use the require_once function to call it into your functions.php file (preferable).

Screenshot Of The Theme Admin Page

Before showing you the code I wanted to share with you a screenshot of what the admin panel you will create look like.

simple-wordpress-theme-options-panel

The Admin Screen Code

Here is the code you need to create the admin panel and include the helper function to getting the values of any setting:

<?php
/**
 * Create A Simple Theme Options Panel
 *
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// Start Class
if ( ! class_exists( 'WPEX_Theme_Options' ) ) {

	class WPEX_Theme_Options {

		/**
		 * Start things up
		 *
		 * @since 1.0.0
		 */
		public function __construct() {

			// We only need to register the admin panel on the back-end
			if ( is_admin() ) {
				add_action( 'admin_menu', array( 'WPEX_Theme_Options', 'add_admin_menu' ) );
				add_action( 'admin_init', array( 'WPEX_Theme_Options', 'register_settings' ) );
			}

		}

		/**
		 * Returns all theme options
		 *
		 * @since 1.0.0
		 */
		public static function get_theme_options() {
			return get_option( 'theme_options' );
		}

		/**
		 * Returns single theme option
		 *
		 * @since 1.0.0
		 */
		public static function get_theme_option( $id ) {
			$options = self::get_theme_options();
			if ( isset( $options[$id] ) ) {
				return $options[$id];
			}
		}

		/**
		 * Add sub menu page
		 *
		 * @since 1.0.0
		 */
		public static function add_admin_menu() {
			add_menu_page(
				esc_html__( 'Theme Settings', 'text-domain' ),
				esc_html__( 'Theme Settings', 'text-domain' ),
				'manage_options',
				'theme-settings',
				array( 'WPEX_Theme_Options', 'create_admin_page' )
			);
		}

		/**
		 * Register a setting and its sanitization callback.
		 *
		 * We are only registering 1 setting so we can store all options in a single option as
		 * an array. You could, however, register a new setting for each option
		 *
		 * @since 1.0.0
		 */
		public static function register_settings() {
			register_setting( 'theme_options', 'theme_options', array( 'WPEX_Theme_Options', 'sanitize' ) );
		}

		/**
		 * Sanitization callback
		 *
		 * @since 1.0.0
		 */
		public static function sanitize( $options ) {

			// If we have options lets sanitize them
			if ( $options ) {

				// Checkbox
				if ( ! empty( $options['checkbox_example'] ) ) {
					$options['checkbox_example'] = 'on';
				} else {
					unset( $options['checkbox_example'] ); // Remove from options if not checked
				}

				// Input
				if ( ! empty( $options['input_example'] ) ) {
					$options['input_example'] = sanitize_text_field( $options['input_example'] );
				} else {
					unset( $options['input_example'] ); // Remove from options if empty
				}

				// Select
				if ( ! empty( $options['select_example'] ) ) {
					$options['select_example'] = sanitize_text_field( $options['select_example'] );
				}

			}

			// Return sanitized options
			return $options;

		}

		/**
		 * Settings page output
		 *
		 * @since 1.0.0
		 */
		public static function create_admin_page() { ?>

			<div class="wrap">

				<h1><?php esc_html_e( 'Theme Options', 'text-domain' ); ?></h1>

				<form method="post" action="options.php">

					<?php settings_fields( 'theme_options' ); ?>

					<table class="form-table wpex-custom-admin-login-table">

						<?php // Checkbox example ?>
						<tr valign="top">
							<th scope="row"><?php esc_html_e( 'Checkbox Example', 'text-domain' ); ?></th>
							<td>
								<?php $value = self::get_theme_option( 'checkbox_example' ); ?>
								<input type="checkbox" name="theme_options[checkbox_example]" <?php checked( $value, 'on' ); ?>> <?php esc_html_e( 'Checkbox example description.', 'text-domain' ); ?>
							</td>
						</tr>

						<?php // Text input example ?>
						<tr valign="top">
							<th scope="row"><?php esc_html_e( 'Input Example', 'text-domain' ); ?></th>
							<td>
								<?php $value = self::get_theme_option( 'input_example' ); ?>
								<input type="text" name="theme_options[input_example]" value="<?php echo esc_attr( $value ); ?>">
							</td>
						</tr>

						<?php // Select example ?>
						<tr valign="top" class="wpex-custom-admin-screen-background-section">
							<th scope="row"><?php esc_html_e( 'Select Example', 'text-domain' ); ?></th>
							<td>
								<?php $value = self::get_theme_option( 'select_example' ); ?>
								<select name="theme_options[select_example]">
									<?php
									$options = array(
										'1' => esc_html__( 'Option 1', 'text-domain' ),
										'2' => esc_html__( 'Option 2', 'text-domain' ),
										'3' => esc_html__( 'Option 3', 'text-domain' ),
									);
									foreach ( $options as $id => $label ) { ?>
										<option value="<?php echo esc_attr( $id ); ?>" <?php selected( $value, $id, true ); ?>>
											<?php echo strip_tags( $label ); ?>
										</option>
									<?php } ?>
								</select>
							</td>
						</tr>

					</table>

					<?php submit_button(); ?>

				</form>

			</div><!-- .wrap -->
		<?php }

	}
}
new WPEX_Theme_Options();

// Helper function to use in your theme to return a theme option value
function myprefix_get_theme_option( $id = '' ) {
	return WPEX_Theme_Options::get_theme_option( $id );
}

Using The Options In Your Theme

Using your options is very easy especially with the included helper function in the code above. Here is an example on how you would use the helper function to get and display the value for the dropdown field which has an ID of “select_example”.

$value = myprefix_get_theme_option( 'select_example' );
echo $value;

More Info On Creating Admin Screens

I have seen TONS of admin pages all created in very distinct ways but I personally like the method I showed you above. It’s very simple and straight to the point. There is no need to get so crazy with your theme options! If you need more information for creating admin screens you will want to check out the Administration Screens Codex.

AJ Clarke
Post Author: AJ Clarke

Hey. My name is AJ and I am the boss around here. I own and operate WPExplorer. A website dedicated to everything I love about WordPress.

Disclosure: This page contains external affiliate links that may result in us receiving a comission if you choose to purchase said product. The opinions on this page are our own. We do not receive payment for positive reviews.
Got something to say? Join the discussion.
  1. Kevin Marshall (@kevinruess) says:
    You're the best!! This is the first tutorial on the subject that I could actually follow. Very clear.
  2. Pete says:
    Thanks, I've had a look at some of those. Your code above is simple, easy and quick compared to any of the others.
  3. Akram ul haq says:
    Thanks a lot Sir, you are really awesome .... I really searched google but could not find useful to me ... at last I came here and made my client happy :) Loved your work ... thanks again ... wanna subscribe and follow you now ....
    • haery h says:
      hanks a lot Sir, you are really awesome .... I really searched google but could not find useful to me ... at last I came here and made my client happy :) Loved your work ... thanks again ... wanna subs

Leave a Reply