Admin Menu Registration
Extending the Admin Navigation Menu
GeniXCMS v2.0.0 introduces a programmable admin menu system via the AdminMenu class. This allows modules and themes to add, remove, or reorder navigation items in the admin panel sidebar and top navbar without modifying any core file.
🏗️ Architecture Overview
The admin navigation is driven by a central registry. When the system boots, it:
- Loads all active Modules (
new Mod()) - Loads the active Theme (
new Theme()) - Fires the
inithook - Initializes AdminMenu (
new AdminMenu()) — which registers core items and processes any items modules have already queued
This means you can safely call AdminMenu::add() from anywhere in your module or theme's function.php or index.php.
🔌 Registration in a Module
The recommended location to register your admin menu items is your module's function.php file (loaded automatically on every page load when the module is active).
Minimal Example
// inc/mod/my_shop/function.php
AdminMenu::add([
'id' => 'my_shop',
'label' => _('My Shop'),
'icon' => 'bi bi-cart3',
'url' => 'index.php?page=mods&mod=my_shop',
'access' => 3,
'position' => 'external',
'order' => 10,
]);
Full Example with Sub-Menu
// inc/mod/inventory/function.php
AdminMenu::add([
'id' => 'inventory',
'label' => _('Inventory'),
'icon' => 'bi bi-box-seam-fill',
'url' => 'index.php?page=mods&mod=inventory',
'access' => 2, // Editor and above
'position' => 'external',
'order' => 20,
'children' => [
[
'label' => _('Products'),
'icon' => 'bi bi-boxes',
'url' => 'index.php?page=mods&mod=inventory&tab=products',
'access' => 2,
],
[
'label' => _('Orders'),
'icon' => 'bi bi-receipt',
'url' => 'index.php?page=mods&mod=inventory&tab=orders',
'access' => 2,
],
[
'label' => _('Stock Report'),
'icon' => 'bi bi-bar-chart-line',
'url' => 'index.php?page=mods&mod=inventory&tab=report',
'access' => 1, // Supervisor only for reports
],
],
]);
🎨 Registration in a Theme
If your theme provides its own admin utilities (e.g., a Theme Options shortcut), register the item in your theme's function.php.
// inc/themes/my_theme/function.php
AdminMenu::add([
'id' => 'my_theme_options',
'label' => _('Theme Options'),
'icon' => 'bi bi-brush-fill',
'url' => 'index.php?page=themes&act=options',
'access' => 0, // Administrator only
'position' => 'external',
'order' => 5,
]);
📐 Menu Positions
Choose the right position to place your item in the correct region:
| Position | Sidebar Section | Top Navbar Behavior |
|---|---|---|
main |
Under "Main Navigation" | Shown as top-level nav links |
management |
Under "Management" | Shown as top-level or dropdown |
settings |
Under Settings group | Shown inside "Settings" dropdown |
external |
Under "External" | Shown inside "External" dropdown |
external for module-specific items. Reserve main and management for items that have broad, primary importance across the whole site.🌲 Adding Sub-Menus to Existing Items
If you want to inject a sub-menu into an existing parent item (e.g., adding a "Draft Store" link under the "Posts" menu or a "Custom Settings" under "Settings"), use AdminMenu::addChild().
Adding a Single Sub-Menu
// Add a custom link under the core "Posts" menu
AdminMenu::addChild('posts', [
'label' => _('My Post Type'),
'url' => 'index.php?page=posts&type=custom',
'icon' => 'bi bi-star',
'access' => 4, // Author level and above
]);
Adding Multiple Sub-Menus at Once
Use AdminMenu::addChildren() to inject a batch of items into a parent.
AdminMenu::addChildren('settings', [
[
'label' => _('Store Settings'),
'url' => 'index.php?page=settings&tab=store',
],
[
'label' => _('API Configuration'),
'url' => 'index.php?page=settings&tab=api',
]
]);
posts, pages, users, settings, themes, modules, permissions, comments, and media.🔄 Removing Core Menu Items
You can remove any core menu item using its id. This is useful for building specialized or restricted admin panels.
// Remove core items your custom installation does not need
AdminMenu::remove('comments'); // Remove Comments from sidebar
AdminMenu::remove('permissions'); // Remove ACL Manager link
🔢 Controlling Order
All core items use order values that are multiples of 10. Use values between them to inject items precisely:
order: 10 → Posts
order: 15 → 📌 My Custom Item ← injected between Posts and Pages
order: 20 → Pages
order: 30 → Comments
AdminMenu::add([
'id' => 'newsletter',
'label' => _('Newsletter'),
'icon' => 'bi bi-envelope-paper',
'url' => 'index.php?page=mods&mod=newsletter',
'position' => 'main',
'order' => 15, // Appears between Posts (10) and Pages (20)
]);
🧩 Using Access Control
The access key controls which user levels can see the menu item. It uses the same numeric role system as User::access():
| Value | Role |
|---|---|
0 |
Administrator |
1 |
Supervisor |
2 |
Editor |
3 |
Author |
4 |
Contributor |
5 |
VIP Member |
6 |
General Member |
// Only administrators see this item
AdminMenu::add([
...
'access' => 0,
]);
// Authors and above
AdminMenu::add([
...
'access' => 3,
]);
Child items can also have their own access level, which overrides the parent:
'children' => [
['label' => 'Public Stats', 'url' => '...', 'access' => 4], // Authors+
['label' => 'Private Stats', 'url' => '...', 'access' => 0], // Admin only
],
🔌 Using the init Hook (Advanced)
For items that depend on runtime conditions (e.g., feature flags or options), you can defer registration to the init hook:
// inc/mod/my_module/function.php
Hooks::attach('init', function() {
if (Options::v('my_module_premium') === 'on') {
AdminMenu::add([
'id' => 'my_module_premium',
'label' => _('Premium Features'),
'icon' => 'bi bi-star-fill',
'url' => 'index.php?page=mods&mod=my_module&tab=premium',
'position' => 'external',
'order' => 30,
]);
}
});
init hook fires before new AdminMenu(), so items registered via init are available when the core menu is being built.📋 Complete Reference
| Method | Description |
|---|---|
AdminMenu::add(array $item) |
Register a new menu item. |
AdminMenu::remove(string $id) |
Unregister a menu item by ID. |
AdminMenu::getItems(?string $pos) |
Get sorted array of items, optionally filtered by position. |
AdminMenu::renderSidebar(?string $pos) |
Output sidebar <li> HTML for given position. |
AdminMenu::renderTopNav(?string $pos) |
Output top navbar <li> HTML for given position. |
See Also
- AdminMenu Class Reference — Full API documentation.
- Create a Module — How to build a complete GeniXCMS module.
- Create a Theme — How to build a custom admin-aware theme.
- Using Hooks — Deferred registration using the
inithook.