Building an admin system

The Admin module provides the admin shell and navigation. Each feature contributes its admin pages through a sibling <Module>Admin module. The site includes Admin and the *Admin modules, then calls Admin::Route('/admin') to render it.

The Admin module owns the shell

The Admin module provides the admin login, the top navigation, users, groups and permissions. It does not know about your features. Each feature adds its own section to the shell through a sibling admin module: a Shop module gets a ShopAdmin module, a Member module gets a MemberAdmin module. Keeping the admin pages in a separate *Admin module keeps admin code out of the module that serves the public site.

A feature module registers a section

A *Admin module registers its section by calling AdminConfig::Section during load. It takes a button label, a URL name, and the callback that routes the section's pages:

// in ShopAdmin/index.php
require_once $MODULE_PATH . '/Admin/index.php';

Loader::Require(__DIR__ . '/src/ShopAdmin.php');
Loader::Require(__DIR__ . '/src/ShopAdminUi.php');

AdminConfig::Section('Shop', 'shop', 'ShopAdminUi::Section');

The label is the navigation button. The URL name places the section under the admin path. The callback renders the section when a request lands on it. The Admin module collects every registered section and builds the navigation from them.

The site wires it together

The site's index.php includes the Admin module and each *Admin module. Including a *Admin module runs its AdminConfig::Section call, so by the time routing starts every section is registered. Then, inside the request, the site calls Admin::Route('/admin') once to mount the whole admin system:

// include the admin shell and the feature admin modules
require_once $MODULE_PATH . '/Admin/index.php';
require_once $MODULE_PATH . '/ShopAdmin/index.php';
require_once $MODULE_PATH . '/MemberAdmin/index.php';

// ... inside NetworkWeb::Server, during the request ...
Admin::Route('/admin');

One Admin::Route call renders every registered section. Adding a feature to the admin is one new *Admin module and one require_once. The site code that calls Admin::Route never changes.

Next: Objects and types.