Creating Custom Options Pages

https://rudrastyh.com/wordpress/creating-options-pages.html

Creating Custom Options Pages

1. Create an Admin Page

There are primarily two functions for that:

  • add_menu_page() – to create a new top-level menu page,

  • add_submenu_page() – to create a submenu page.

To simplify the process, instead of add_submenu_page() you can use add_dashboard_page(), add_posts_page(), add_pages_page(), add_comments_page(), add_theme_page(), add_plugins_page(), add_users_page(), add_management_page() or add_options_page() depending on where you’re going to add your submenu page.

Okay, let’s dive into the examples.

Create a custom top-level menu page

Take a look at this code:

add_action( 'admin_menu', 'misha_menu_page' );
 
function misha_menu_page() {
 
	add_menu_page(
		'My Page Title', // page <title>Title</title>
		'My Page', // menu link text
		'manage_options', // capability to access the page
		'misha-slug', // page URL slug
		'misha_page_content', // callback function /w content
		'dashicons-star-half', // menu icon
		5 // priority
	);
 
}
 
function misha_page_content(){
 
	echo 'What is up?';
 
}

If you don’t understand how I have added an icon there, just check the Dashicons icon set.

Create a custom options page

Creating a new menu item with an icon is cool but the truth is when you create a plugin settings page, it is always better to add it as a submenu page under Settings.

It is the best practice and in most cases I recommend you to do it that way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
add_action( 'admin_menu', 'misha_options_page' );
 
function misha_options_page() {
 
	add_options_page(
		'My Page Title', // page <title>Title</title>
		'My Page', // menu link text
		'manage_options', // capability to access the page
		'misha-slug', // page URL slug
		'misha_page_content', // callback function with content
		2 // priority
	);
 
}
 
function misha_page_content(){
 
	echo 'What is up?';
 
}

Now you already know how to add any custom HTML to your options pages, but in the next chapter I will show you how to properly create settings fields there.

2. Add Fields with Settings API

First of all let’s populate our misha_page_content() function which we created in the previous step.

1
2
3
4
5
6
7
8
9
10
11
12
13
function misha_page_content(){
 
	echo '<div class="wrap">
	<h1>My Page Settings</h1>
	<form method="post" action="options.php">';
 
		settings_fields( 'misha_settings' ); // settings group name
		do_settings_sections( 'misha-slug' ); // just a page slug
		submit_button();
 
	echo '</form></div>';
 
}

We are not going to make any changes in this functions anymore. All you have to know is that we use two functions settings_fields() and do_settings_sections() to print all the settings fields and to populate them with data.

2.1 Register a setting and create a field

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
add_action( 'admin_init',  'misha_register_setting' );
 
function misha_register_setting(){
 
	register_setting(
		'misha_settings', // settings group name
		'homepage_text', // option name
		'sanitize_text_field' // sanitization function
	);
 
	add_settings_section(
		'some_settings_section_id', // section ID
		'', // title (if needed)
		'', // callback function (if needed)
		'misha-slug' // page slug
	);
 
	add_settings_field(
		'homepage_text',
		'Homepage text',
		'misha_text_field_html', // function which prints the field
		'misha-slug', // page slug
		'some_settings_section_id', // section ID
		array( 
			'label_for' => 'homepage_text',
			'class' => 'misha-class', // for <tr> element
		)
	);
 
}
 
function misha_text_field_html(){
 
	$text = get_option( 'homepage_text' );
 
	printf(
		'<input type="text" id="homepage_text" name="homepage_text" value="%s" />',
		esc_attr( $text )
	);
 
}

What is esc_attr() function and why it is here? There is a separate tutorial on my blog about escaping outputs where I said that database is not a trusted source of data and that’s why we must use escaping functions before we output anything into the page content.

2.2 Sanitization

Let’s come back for a moment to a register_setting() function from the previous piece of code.

register_setting(
	'misha_settings',
	'homepage_text',
	'sanitize_text_field' // sanitization function
);

The third parameter is the function name which is intended to sanitize (clean) the field data before saving into the database. For example sanitize_text_field() is the default WordPress function that removes all the characters that are not allowed in use in an input text field. If you would like to to pass an integer, you can use intval() or absint() function names instead. Or create a custom sanitization function for your purpose.

Example for positive integers:

register_setting( 'misha_settings', 'number_of_slides', 'absint' );

3. Easy example

We have some code above. Actually a lot of code. And it is all about to create a single input field.

I want to be honest with you – I never do all that manually on my projects. Because it is so time consuming. What is the solutions then? I also don’t like plugins, especially ACF-like ones. Because I’d better spend a couple more hours and create a fast website instead of using slow bloated plugins.

Finally I came to a solution – I created my own option pages plugin with the bare minimum of the functionality. It is lightning fast just like you code everything in functions.php, but at the same time it saves hours of development.

Just compare this code to everything we did above:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
add_filter( 'simple_register_option_pages', 'misha_option_page' );
 
function misha_option_page( $option_pages ) {
 
	$option_pages[] = array(
		'id'	=> 'misha_slug',
		'title' => 'My Page Settings',
		'menu_name' => 'My page',
		'fields' => array(
			array(
				'id' => 'homepage_text',
				'label' => 'Homepage text',
				'type' => 'text',
			),
 		),
	);
 
	return $option_pages;
 
}

Last updated