This is a real-life sample of a plugin I am working on. It is called TVTrax, the inner workings is unimportant, this is just a clip of how to handle multiple custom post types and Herbert panels, all within one top-level Admin Menu.
What I am using for Custom Post Types
I am using an alternative custom post type library, other than the one in the Herbert docs. As of 0.9 the docs listed JJGraingers custom post class requirement as "jjgrainger/wp-custom-post-type-class": "dev-master" for a composer install.
There is a newer version from jjgrainger called PostTypes. You can include this in your plugin composer.json with $ composer require jjgrainger/posttypes.
Whether you use this package or not, there are only two CPT settings that you need concern yourself with ... they are the show_ui and show_in_menu arguments for registering your custom post type. More on this later.
First, Create Your Plugin Panel and subPanels
In this case, I have one main panel and a subpanel for settings. Eventually, I want the main panel on the top, and settings on the bottom of the top-level menu. Additionally, I want the main panel renamed to 'Dashboard'.
Add the following code to your `app/panels.php' file:
You will notice that the show_in_menu label refers to the tvtrax-index in the previous main panel addition. This is !important.
At this point, you will get a top-level menu for your plugin and an unordered list of submenus in the order of panels then CPTs (or vice-versa). Now we need to list them in the correct order.
Get your hooks in order
I like to have all of my actions and filters in one file. I call it hooks.php and it sits in my \app folder.
Create an apps\hooks.php file. Include it in your herbert.congig.php file with:
Before we can hook something, we need something to hook it to. In this case, we need an AdminController.
Create a controller in /controllers called AdminController.php. Add the following:
<?php
namespace TVTrax\Controllers;
class AdminController {
public function index() {
echo '<h1>TV Trax Dashboard</h1>';
}
public function settings() {
echo '<h1>TV Trax Settings</h1>';
}
/**
* Reorders submenu items for TVTrax Admin Toplevel menu
*
* While the filter passes a menu order array, we don't use it.
* Instead, we alter the global variable $submenu to accomplish
* our reording.
*
* @uses filter 'custom_menu_order'
*
* @param array $menu_order
* @return array
*/
public static function custom_menu_order( $menu_order ) {
global $submenu;
$tv_menu = 'tvtrax-index';
// Reorder the submenu array
$arr = array();
$arr[] = $submenu[$tv_menu][3];
$arr[] = $submenu[$tv_menu][0];
$arr[] = $submenu[$tv_menu][1];
$arr[] = $submenu[$tv_menu][2];
$arr[] = $submenu[$tv_menu][4];
// Assign re-ordered array to our top level menu
$submenu[$tv_menu] = $arr;
return $menu_order;
}
}
Inside the hooks.php file, add the following:
// Adjust the order of TVTrax submenu items
add_filter( 'custom_menu_order', [ '\TVTrax\Controllers\AdminController', 'custom_menu_order' ] );
Remember to change your namespaces and mind your R's. Help me improve on this too!
Overview
This is a real-life sample of a plugin I am working on. It is called TVTrax, the inner workings is unimportant, this is just a clip of how to handle multiple custom post types and Herbert panels, all within one top-level Admin Menu.
What I am using for Custom Post Types
I am using an alternative custom post type library, other than the one in the Herbert docs. As of 0.9 the docs listed JJGraingers custom post class requirement as
"jjgrainger/wp-custom-post-type-class": "dev-master"
for a composer install.There is a newer version from jjgrainger called PostTypes. You can include this in your plugin composer.json with
$ composer require jjgrainger/posttypes
.Whether you use this package or not, there are only two CPT settings that you need concern yourself with ... they are the
show_ui
andshow_in_menu
arguments for registering your custom post type. More on this later.First, Create Your Plugin Panel and subPanels
In this case, I have one main panel and a subpanel for settings. Eventually, I want the main panel on the top, and settings on the bottom of the top-level menu. Additionally, I want the main panel renamed to 'Dashboard'.
Add the following code to your `app/panels.php' file:
This code assumes that you have an AdminController with index and settings methods. Also, the two methods are to be seperated on the main plugin menu.
You will get an Admin Menu with TV Trax on the top and two submenu items labled 'Dashboard' and 'Settings'.
Register Your Custom Post Types
No matter how you register your custom post types, there are only two arguments that you need to worry about.
In your options, set the following:
You will notice that the
show_in_menu
label refers to thetvtrax-index
in the previous main panel addition. This is !important.At this point, you will get a top-level menu for your plugin and an unordered list of submenus in the order of panels then CPTs (or vice-versa). Now we need to list them in the correct order.
Get your hooks in order
I like to have all of my actions and filters in one file. I call it
hooks.php
and it sits in my\app
folder.Create an
apps\hooks.php
file. Include it in yourherbert.congig.php
file with:Before we can hook something, we need something to hook it to. In this case, we need an AdminController.
Create a controller in /controllers called AdminController.php. Add the following:
Inside the
hooks.php
file, add the following:Remember to change your namespaces and mind your R's. Help me improve on this too!