Way back in 2010, Ian Stewart added a sample WordPress theme options page to the Theme Shaper blog. I’ve been using that ever since as my go to snippet for creating admin pages. Unfortunately, over time I have slowly adapted it to my needs and every time I need to use it again, I ended up having to rewrite large chunks to suit newer ways of doing things and generally adding a little more code polish. With that in mind, the code below is my new go to snippet which I’ll be maintaining myself. Feel free to copy and paste it into your own projects. If you can see any ways to improve it, please let me know in the comments section.

<?php

/**
 * Ryan's example admin page.
 * 
 * @copyright Copyright (c), Ryan Hellyer
 * @author Ryan Hellyer <ryanhellyergmail.com>
 * @since 1.1
 */
class Example_Options_Page {

	/**
	 * Set some constants for setting options.
	 */
	const MENU_SLUG = 'example-page';
	const GROUP     = 'example-group';
	const OPTION    = 'example-option';

	/**
	 * Fire the constructor up :D
	 */
	public function __construct() {

		// Add to hooks.
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_action( 'admin_menu', array( $this, 'create_admin_page' ) );
	}

	/**
	 * Init plugin options to white list our options.
	 */
	public function register_settings() {
		register_setting(
			self::GROUP,               // The settings group name.
			self::OPTION,              // The option name.
			array( $this, 'sanitize' ) // The sanitization callback.
		);
	}

	/**
	 * Create the page and add it to the menu.
	 */
	public function create_admin_page() {
		add_options_page(
			__ ( 'Example admin page', 'plugin-slug' ), // Page title.
			__ ( 'Example page', 'plugin-slug' ),       // Menu title.
			'manage_options',                           // Capability required.
			self::MENU_SLUG,                            // The URL slug.
			array( $this, 'admin_page' )                // Displays the admin page.
		);
	}

	/**
	 * Output the admin page.
	 */
	public function admin_page() {

		?>
		<div class="wrap">
			<h1><?php esc_html_e( 'Example admin page', 'plugin-slug' ); ?></h1>
			<p><?php esc_html_e( 'Place a description of what the admin page does here to help users make better use of the admin page.', 'plugin-slug' ); ?></p>

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

				<table class="form-table">
					<tr>
						<th>
							<label for="<?php echo esc_attr( self::OPTION ); ?>"><?php _e( 'Enter your input string.', 'plugin-slug' ); ?></label>
						</th>
						<td>
							<input type="text" id="<?php echo esc_attr( self::OPTION ); ?>" name="<?php echo esc_attr( self::OPTION ); ?>" value="<?php echo esc_attr( get_option( self::OPTION ) ); ?>" />
						</td>
					</tr>
				</table>

				<?php settings_fields( self::GROUP ); ?>
				<p class="submit">
					<input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'plugin-slug' ); ?>" />
				</p>
			</form>
		</div><?php
	}

	/**
	 * Sanitize the page or product ID.
	 *
	 * @param string $input The input string.
	 * @return array The sanitized string.
	 */
	public function sanitize( $input ) {
		$output = wp_kses_post( $input );
		return $output;
	}

}
new Example_Options_Page();

?>
The view of the live example WordPress admin page.

The view of the live example WordPress admin page.