When you write your own plugin, you often want to add dedicated page for its settings. In this post I will show you how to do this.
How to add menu page in wordpress admin panel
Step 1
To add new page to wordpress menu on admin side, we must use admin_menu hook, which allows us add function: add_menu_page() and set it’s arguments.
add_action( 'admin_menu', 'lovecoding_add_new_page' );
function lovecoding_add_new_page() {
add_menu_page(
'My Page Title', // $page_title
'Title visible in menu', // $menu_title
'manage_options', // $capability -> "manage_options" - only for admins
'my-page-slug', // $menu_slug
'lovecoding_page_html_content', // $function with content code
plugin_dir_url(__FILE__) . 'images/icon_wporg.png', // $icon_url
90 // $position
);
}
Step 2
Now we have empty page added to our menu. We can add content to it:
lovecoding_page_html_content {
?>
<div class="wrap">
<h2><?php echo esc_html( 'My page title') ?></h2>
<form action="options.php" method="post">
<?php
// outpus settings fields (without this there is error after clicking save settings button)
settings_fields( 'jl_options' ); // A settings group name. This should match the group name used in register_setting()
// output setting sections and their fields
do_settings_sections( 'lovecoding-slug' ); // The slug name of settings sections you want to output.
// output save settings button
submit_button( 'Save Settings', 'primary', 'submit', true ); // Button text, button type, button id, wrap, any other attribute
?>
</form>
</div>
<?php
}
So, we displayed content to our site, but… it’s still empty (except page title and submit button). We need some fields and settings matched to it.
Step 3
Let’s create new section and text field in it (and setting matched to it).
add_action( 'admin_init', 'lovecoding_add_new_settings' );
function lovecoding_add_new_settings() {
// adding section
add_settings_section( 'lovecoding_section_1', 'Setion 1 title', null, 'lovecoding-slug' ); // id (slug-name to identify the section), title, callback, page slug
// adding fields for section
add_settings_field( 'field-1', 'My field title', 'lovecoding_field_1_callback', 'lovecoding-slug', 'jlplg_lovecoding_section_1_configuration' ); // id (slug-name to identify the field), title, function displaying text input, slug-name of the settings page on which to show the section, section, args (attributes for field - no need to add it here)
// register setting
$args = array(
'type' => 'string',
'sanitize_callback' => 'lovecoding_sanitize_input_field',
'default' => 'Default setting'
);
register_setting( 'lovecoding_options', 'lovecoding-field1', $args); // option group, option name, args
}
// field 1 - displaying text field
function lovecoding_field_1_callback() {
echo '<input type="text" name="lovecoding-field1" value="'.esc_html( get_option( "lovecoding-field1" ) ).'" />';
}
// sanitize input field
function lovecoding_sanitize_input_field( $input ) {
if ( isset( $input ) ) {
$input = sanitize_text_field( $input );
}
return $input;
}
OK! So we created a page on admin menu, with fields and settings, but what if you want to add page to already existing menu (e.g. Settings or Tools)?
How to add submenu page to existing menu page
To do this, we need to use add_submenu_page() function, together with admin_menu hook.
Step 1
Let’s add new page to Settings page in menu:
add_action( 'admin_menu', 'lovecoding_add_submenu_page' );
function lovecoding_add_submenu_page() {
add_submenu_page(
'options-general.php', // $parent_slug -> 'settings' site slug
'Page Title', // $page_title
'Menu Title', // $menu_title
'manage_options', // $$capability -> "manage_options" - only for admins
'my-page-slug', // $menu_slug
'lovecoding_page_html_content' // $function that adds content to site
);
}
Step 2 and 3 are the same as in adding menu page, so if you want to add content to your site, read instructions above.