Skip to content

Admin Menus

Miguel Muscat edited this page Nov 30, 2022 · 2 revisions

Admin menus refer to the top-level menu items that appear in the WordPress admin sidebar. Submenus refer to the menu items that are nested under a top-level menu item.

Creating a top-level menu item

To create a top-level menu item, simply create an AdminMenu instance using the constructor and supply it with an AdminPage instance.

use RebelCode\WpSdk\Wp\AdminPage;
use RebelCode\WpSdk\Wp\AdminMenu;

$page = new AdminPage(/* ... */);

$menu = new AdminMenu(
    // The page to render
    $page,
    // The menu item's slug
    'my-menu',
    // The menu label
    'My Menu',
    // The required user capability
    'can_edit_posts',
    // The menu icon
    'dashicons-admin-generic',
    // The menu position
    15
);

Refer to the Admin Pages documentation for more information on how to create an AdminPage instance.

Adding submenu items

Submenu items can be added in different two ways: either for an admin page (similar to a top-level menu item), or for a URL.

use RebelCode\WpSdk\Wp\AdminPage;
use RebelCode\WpSdk\Wp\AdminSubMenu;

$page = new AdminPage(/* ... */);
$submenu1 = AdminSubMenu::forPage($page, 'my-submenu', 'My Submenu', 'capability', 10);

$submenu2 = AdminSubMenu::forUrl('https://example.com', 'My Submenu', 'capability', 11);

Submenu items can be added to top-level menus in 2 ways:

// Pass the submenu items as an array to the constructor
$menu = new AdminMenu(
    $page,
    'my-menu',
    'My Menu',
    'can_edit_posts',
    'dashicons-admin-generic',
    15,
    // Pass in constructor
    [
        $submenu1,
        $submenu2,
    ]
);

// Add the submenu via a method call
$menu->addSubmenu($submenu3);

Services

Factories for menus and submenus can be easily created using their corresponding static factory() methods.

use RebelCode\WpSdk\Wp\AdminMenu;
use RebelCode\WpSdk\Wp\AdminPage;
use RebelCode\WpSdk\Wp\AdminSubMenu;
use RebelCode\WpSdk\Module;
use Dhii\Services\Factories\FuncService;

class MyModule extends Module
{
    public function getFactories(): array
    {
        return [
            'my_page' => /* ... */,

            'my_menu' => AdminMenu::factory(
                'my_page', // <- The ID of the page service
                'my-menu',
                'My Menu',
                'capability',
                'dashicons-admin-generic',
                15,
                [
                    'my_menu/sub_1', // The IDs of the submenu services
                    'my_menu/sub_2',
                ]
            ),

            'my_menu/sub_1' => AdminSubMenu::forPage(
                'my_page', // <- The ID of the page service
                'my-submenu-page-1',
                'My Submenu Page 1',
                'capability',
                1
            ),

            'my_menu/sub_2' => AdminSubMenu::forUrl(
                'https://example.com',
                'My Submenu Page 2',
                'capability',
                2
            ),
        ];
    }
}

Note that the factory methods take the similar arguments as their corresponding constructors, with a few exceptions:

  1. The first argument for an AdminMenu must be the ID of the page service, not the page instance itself.
  2. The last argument for an AdminMenu must be an array of submenu IDs, not an array of submenu instances.
  3. The first argument for AdminSubMenu::forPage() must be the ID of the page service, not the page instance itself.

Admin menu pages can be registered to WordPress by extending the admin_menus service.

use RebelCode\WpSdk\Module;
use RebelCode\WpSdk\Wp\AdminMenu;

class MyModule extends Module
{
    public function getFactories()
    {
        return [
            'my_menu' => AdminMenu::factory(/* ... */),
        ];
    }

    public function getExtensions(): array
    {
        return [
            'wp/admin_menus' => [
                'my_menu',
            ],
        ];
    }
}

If you need to add a submenu page to menu page that your plugin did not create, you will need to manually register it using the AdminMenu::register() method in an admin_menu action handler.

use RebelCode\WpSdk\Module;
use RebelCode\WpSdk\Handler;
use RebelCode\WpSdk\Wp\AdminSubMenu;

class MyModule extends Module
{
    public function getHooks()
    {
        return [
            'admin_menu' => [
                new Handler(['my_submenu'], function (AdminSubMenu $submenu) {
                    $submenu->registerFor('parent_menu_slug');
                }),
            ],
        ];
    }
    
    public function getFactories()
    {
        return [
            'my_submenu' => AdminSubMenu::factoryForPage(/* ... */),
        ];
    }
}

Clone this wiki locally