Web dev hints, tips and tricks to help you become an expert.

If you’re developing a WordPress plugin with a page in the admin dashboard, you might want to redirect users away from that page according to certain conditions.

For instance, you could deny access if the user doesn’t have a certain capability or force them to add data before displaying it.

Add menu pages to the WordPress dashboard

There is a very simple way to link to new admin screens in the WordPress dashboard using add_menu_page() and add_submenu_page():

class Myplugin_My_Plugin {

	static $instance;
	
	public function __construct() {
			
		add_action( 'admin_menu', array( $this, 'myplugin_my_plugin_menu' ) );
		
	}
	
	public function myplugin_my_plugin_menu() {
		
		add_menu_page( __( 'My Plugin', 'my-plugin' ), __( 'My Plugin', 'my-plugin' ), 'edit_others_posts', 'myplugin-data', array( $this, 'myplugin_plugin_admin_page_data' ) );
		
		add_submenu_page( 'myplugin-data', __( 'My Plugin', 'my-plugin' ), __( 'My Plugin Data', 'my-plugin' ), 'edit_others_posts', 'myplugin-data', array( $this, 'myplugin_plugin_admin_page_data' ) );
		
		add_submenu_page( 'myplugin-data', __( 'My Plugin Add Data', 'my-plugin' ), __( 'My Plugin Add Data', 'my-plugin' ), 'edit_others_posts', 'myplugin-add-data', array( $this, 'myplugin_plugin_admin_page_add_data' ) );
		
	}
	
}

The above example adds three menus (one parent and two children) that link to two pages. The parent and first child link to the same screen, myplugin-data, and the second child links to myplugin-add-data.

Create the admin screens for your WordPress plugin

To display something on these screens all we have to do is add the functions that we specified as the callbacks:

public function myplugin_plugin_admin_page_data() {

	// Show content for myplugin-data here

}

public function myplugin_plugin_admin_page_add_data() {

	// Show content for myplugin-add-data here

}

Redirect away from a WordPress admin page

If there was no data to show in myplugin-data, you may want to redirect users to myplugin-add-data.

It might feel logical to add such a redirect at the start of myplugin_plugin_admin_page_data() but, by the time this function has been called, other elements of the WordPress dashboard have already loaded.

You’ll probably find that the redirect doesn’t execute and encounter PHP warnings like:

Warning: Cannot modify header information - headers already sent by (output started at /home/username/public_html/wp-includes/class-wp-styles.php:290) in /home/username/public_html/wp-includes/pluggable.php on line 1427

Warning: Cannot modify header information - headers already sent by (output started at /home/username/public_html/wp-includes/class-wp-styles.php:290) in /home/username/public_html/wp-includes/pluggable.php on line 1430

Avoiding a ‘headers already sent by’ error by redirecting before the page begins to load

To implement the redirect before the WordPress dashboard sends any headers or outputs anything we can create a callback function and register it with a hook that is called prior to the page load.

You can add this action by adjusting the myplugin_my_plugin_menu() function:

public function myplugin_my_plugin_menu() {
	
	$hook = add_menu_page( __( 'My Plugin', 'my-plugin' ), __( 'My Plugin', 'my-plugin' ), 'edit_others_posts', 'myplugin-data', array( $this, 'myplugin_plugin_admin_page_data' ) );
	
	add_action( 'load-' . $hook, array( $this, 'myplugin_plugin_admin_page_data_load' ) );
	
	add_submenu_page( 'myplugin-data', __( 'My Plugin', 'my-plugin' ), __( 'My Plugin Data', 'my-plugin' ), 'edit_others_posts', 'myplugin-data', array( $this, 'myplugin_plugin_admin_page_data' ) );
	
	add_submenu_page( 'myplugin-data', __( 'My Plugin Add Data', 'my-plugin' ), __( 'My Plugin Add Data', 'my-plugin' ), 'edit_others_posts', 'myplugin-add-data', array( $this, 'myplugin_plugin_admin_page_add_data' ) );
	
}

Now we can put the redirect, or anything else you want to do before myplugin_plugin_admin_page_data is run, in the callback function we’ve specified as myplugin_plugin_admin_page_data_load.

You may want to do something like the following:

public function myplugin_plugin_admin_page_data_load() {

	// Get data
	
	if ( is_empty( $data ) ) {
		
		wp_safe_redirect( menu_page_url( 'myplugin-add-data', false ), 307 );
			
		exit;
		
	}
	
}

This uses wp_safe_redirect() to redirect the user with an HTTP 307 Temporary Redirect to the URL for myplugin-add-data, generated by menu_page_url().

As mentioned in the code reference, wp_safe_redirect() does not exit automatically and should almost always be followed by a call to exit;.

Leave a Reply

Your email address will not be published. Required fields are marked *