Adding Administration Pages
By using this template software, you automatically get an Options page under the Plugins menu. How this is set up is documented in Options Administration Page.
But often plugins need more than that rather simplistic options page. One option to to create another administration page. This will create another menu item somewhere in the administration menus. Sometimes that is what you want, but more often what is better is to have one menu item in the administration area for all your configuration information. You don’t want users to have to look around for different menu items for different things. It is also not a good idea to unnecessarily pollute the administration menus with lots of stuff.
A second option is to split existing options page into a page with tabs on it, wherein one tab is the stock options page you already get for free, and other tabs have whatever you want on them. I recommend this option for most cases.
Option 1: Creating New Administration Pages & Menu Items
Creating new pages in the administration section is a matter of calling the right WP function to register a function that outputs page contend. These WP APIs are described in http://codex.wordpress.org/Administration_Menus.
To use in this plugin, you need to know two things. First, you can create a function in your XXX_Plugin class to output such page content. When a WP function parameter takes an input function for a callback, use the object-oriented form of that. In other words, pass “array(&$this, ‘yourFunctionName’)”.
Second, you need to know where to make those calls. The calls to these APIs must originate in the XXX_Plugin::addActionsAndFilters() function. Looking at the template you, you will see the following call:
1 2 3 | public function addActionsAndFilters() { // Add options administration page add_action('admin_menu', array(&$this, 'addSettingsSubMenuPage')); |
This hooks into the admin_menu action a call to $this->addSettingsSubMenuPage(). In that function a call is made to add_submenu_page to set up a menu item that will display the contents of $this->settingsPage():
1 2 3 4 5 6 7 8 9 10 | protected function addSettingsSubMenuPageToPluginsMenu() { $this->requireExtraPluginFiles(); $displayName = $this->getPluginDisplayName(); add_submenu_page('plugins.php', $displayName, $displayName, 'manage_options', $this->getSettingsSlug(), array(&$this, 'settingsPage')); } |
Note: if you are creating other pages, you will need to create a “slug” for each that is a unique string to identify your page. In the above, we use the function “getSettingsSlug()”
1 2 3 | protected function getSettingsSlug() { return get_class($this) . 'Settings'; } |
Here we use “get_class($this)” as a prefix to another string, ‘Settings’ in this case. The point of this is to add a prefix so that your slug is unique and doesn’t collide with some other plugin’s slugs. I recommend as a best practice to use this “get_class($this) . ‘SomeString'” convention for admin page slugs.
Note also, that in the above add_submenu_page example, we pass in the ‘manage_options’ WP capability name. With this template code, you have the option to make this configurable by defining a “role option” where the plugin administrator can set what level of user (Admin, Editor, etc) gets the menu item. In that case you define a role option (see Handling Options and Enforcing Role Security) the replace ‘manage_options’ above with $this->roleToCapability($this->getRoleOption(‘TheOptionName’)
The best way to go about adding administration pages is to look at that example in the code and in Options Administration Page.
Option 2: Changing the Existing Options Page into a set of Tabs
The idea here is that your existing options page is changed into a page with JQuery UI Tabs. One tab is the current options page, the rest of the tabs include content you create. Here are the steps to create this.
First, you will need to get a copy of the JQuery UI CSS. To get it, you need to download JQuery UI and pull it out. Here is a version you can download: jquery-ui.css quickly. Place this file in your plugin’s css/ sub-directory.
In your XXX_Plugin.php file, find the addActionsAndFilters() function. Add the following code. Notice that we are checking the for the options page “slug”. This is a way of only adding these styles and scripts if the options/settings page is being viewed. We don’t want to add these on all pages.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public function addActionsAndFilters() { add_action('admin_enqueue_scripts', array(&$this, 'enqueueAdminPageStylesAndScripts')); } public function enqueueAdminPageStylesAndScripts() { // Needed for the Settings Page if (strpos($_SERVER['REQUEST_URI'], $this->getSettingsSlug()) !== false) { wp_enqueue_style('jquery-ui', plugins_url('/css/jquery-ui.css', __FILE__)); wp_enqueue_script('jquery-ui-core'); wp_enqueue_script('jquery-ui-tabs'); // enqueue any othere scripts/styles you need to use } } |
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 | public function settingsPage() { if (!current_user_can('manage_options')) { wp_die(__('You do not have sufficient permissions to access this page.', 'TEXT-DOMAIN')); } ?> <div> Header section above all the tabs </div> <script type="text/javascript"> jQuery(function() { jQuery("#plugin_config_tabs").tabs(); }); </script> <div class="plugin_config"> <div id="plugin_config_tabs"> <ul> <li><a href="#plugin_config-1">Tab 1 Label</a></li> <li><a href="#plugin_config-2">Tab 2 Label</a></li> <li><a href="#plugin_config-3">Options</a></li> </ul> <div id="plugin_config-1"> <?php $this->outputTab1Contents(); ?> </div> <div id="plugin_config-2"> <?php $this->outputTab2Contents(); ?> </div> <div id="plugin_config-3"> <?php parent::settingsPage(); ?> </div> </div> </div> <?php } |
Hey michael,
My name is Dean, Im trying to build a plugin. Ive been struggling a bit with your template,
I couldn’t get any extra admin pages to work ,when I did, you could only go to one as the other told me I didnt have the correct permissions!
So I decided to just go with your Jquery tabs. So I downloaded a fresh plugin template to start again and when I went to install it I got this error
Warning: Invalid argument supplied for foreach() in /home/a2287993/public_html/wp-admin/includes/class-wp-upgrader.php on line 558
I went through your upgrade documentaion but couldnt find anything pertaining to this,
any ideas??
Dean
Adding a top-level menu page instead of a submenu page is an easy edit. Add a new function to your XXX_LifeCycle.php file directly underneath the other
protected function addSettingsSubMenuPageToSettingsMenu()
function:protected function addSettingsSubMenuPageToTopLevelMenu() {
$this->requireExtraPluginFiles();
$displayName = $this->getPluginDisplayName();
add_menu_page($displayName,
$displayName,
'manage_options',
$this->getSettingsSlug(),
array(&$this, 'settingsPage'
//, $icon_path
//, $menu_position
));
}
Then head back up to line 123 of XXX_LifeCycle.php and adjust the
addSettingsSubMenuPage()
function:public function addSettingsSubMenuPage() {
//$this->addSettingsSubMenuPageToPluginsMenu();
//$this->addSettingsSubMenuPageToSettingsMenu();
$this->addSettingsSubMenuPageToTopLevelMenu();
}
I’ve tried your example without modifying anything. This is the same copy of your example but I’ve got this “notice”:
Notice: wp_enqueue_style was called incorrectly. Scripts and styles should not be registered or enqueued until the wp_enqueue_scripts, admin_enqueue_scripts, or login_enqueue_scripts hooks.
Where I’ve made a error? My plugin doesn’t nothing so far. I’m just in begining of writing
I’m on wordpress 3.8.1, no-plugin except this one. default theme 20-14.
Thank a lot,
Francois
P.S.: Sorry for my poor english, i’m french!
Francois – can you upload your code to http://pastebin.com/ and link it here? The “XXX_Plugin.php” file should be a good start.
@eric: this is my code
http://pastebin.com/b6ZGgJhE
and this is my settingsPage() function
http://pastebin.com/RvLSHL0q
Thanks for sending those Francois. I tested your two pastes in a default plugin and they seem to work fine… so perhaps the problem lies elsewhere? If you would like to compare my version to yours, here’s a zip of the files I’m working with: http://emc2innovation.com/test-plugin.zip
Let us know if you get it working!
Thank Eric for the work. But I’ve got the same error. https://drive.google.com/file/d/0B7w9umPK79uEcFIyZFQ5UUt6dUk/edit?usp=sharing
I don’t thing it’s a plugin conflict because I don’t have any other plugin on my localhost test setup. And i’ve put your complete zip inside my plugin directory. I can’t see where it could be because i don’t modified anything else except the menu name and the html output(same as yours)… I continue my search for an anwser! 🙂
Thank again for the work!!!
Francois.
Very interesting. Have you tried switching to a default theme like TwentyTwelve?
yes I’ve tried 20-12 and 20-14 (the two default theme with WP). One thing I will try is with a english version of WP. I don’t reallt think this will change anything, but it’s for my clear conscience!
Just to add to Francois’ message above I am getting the same error.:
Notice: wp_enqueue_style was called incorrectly. Scripts and styles should not be registered or enqueued until the wp_enqueue_scripts, admin_enqueue_scripts, or login_enqueue_scripts hooks.
For your information I am using the Twenty Fourteen theme version 1. I am also using localhost, I wonder if that may play a part?
This should be fixed in the latest version of the template.
Hi i just manage to do a Main Menu a Top level menu in admin. but I cant manage to understand slug..
I cant make a submenu for my mainmenu.. it only work if i made it plugins.php submenu, instead of plugins.php y try to send the value of $this->getSettingsSlug() , wich supouse to be the main slug… it dosent work
protected function addCategorySubMenuPageToSettingsMenu() {
$this->requireExtraPluginFiles();
$displayName = $this->getPluginDisplayName();
add_submenu_page($this->getSettingsSlug(),
$displayName,
$displayName,
‘manage_options’,
$this->getSettingsSlug(),
array(&$this, ‘settingsPage’));
}
Of course i trigger the function before
public function addSettingsSubMenuPage() {
$this->addSettingsSubMenuPageToTopLevelMenu();
$this->addCategorySubMenuPageToSettingsMenu();
}