Skip to content

marko/admin-panel

Server-rendered admin panel UI --- provides login, dashboard, and permission-filtered sidebar navigation out of the box. Admin Panel delivers the server-rendered HTML interface for the admin area. It includes a login/logout flow, a dashboard that displays registered admin sections, and a menu builder that filters navigation items by the current user’s permissions. Templates are rendered via ViewInterface using the admin-panel:: namespace. All routes are protected by AdminAuthMiddleware.

Terminal window
composer require marko/admin-panel

Requires marko/admin, marko/admin-auth, and a view driver (e.g., marko/view-latte).

The panel registers these routes automatically:

MethodPathDescription
GET/admin/loginLogin form
POST/admin/loginAuthenticate
POST/admin/logoutLogout
GET/adminDashboard (requires auth)

AdminMenuBuilderInterface produces a navigation structure filtered by the user’s permissions:

use Marko\AdminPanel\Menu\AdminMenuBuilderInterface;
use Marko\AdminAuth\Entity\AdminUserInterface;
class LayoutHelper
{
public function __construct(
private readonly AdminMenuBuilderInterface $adminMenuBuilder,
) {}
public function getSidebar(
AdminUserInterface $user,
string $currentPath,
): array {
return $this->adminMenuBuilder->build($user, $currentPath);
// Returns: [
// ['section' => ..., 'items' => [...], 'active' => true, 'activeItemId' => 'products'],
// ['section' => ..., 'items' => [...], 'active' => false, 'activeItemId' => null],
// ]
}
}

Each entry includes:

  • section --- the AdminSectionInterface instance
  • items --- filtered and sorted MenuItemInterface array
  • active --- whether this section contains the current page
  • activeItemId --- the ID of the active menu item, or null

Get sections the user can access for the dashboard overview:

$sections = $this->adminMenuBuilder->buildDashboardSections($user);
// Returns AdminSectionInterface[] with at least one accessible menu item

Admin panel templates live under the admin-panel:: namespace. Override them by placing templates in your module’s resources/views/ directory with the same path:

mymodule/
resources/
views/
admin-panel/
dashboard/
index.latte # Overrides the default dashboard

Replace the menu builder via Preferences to customize navigation behavior:

use Marko\Core\Attributes\Preference;
use Marko\AdminPanel\Menu\AdminMenuBuilder;
use Marko\AdminAuth\Entity\AdminUserInterface;
#[Preference(replaces: AdminMenuBuilder::class)]
class CustomMenuBuilder extends AdminMenuBuilder
{
public function build(
AdminUserInterface $user,
string $currentPath = '',
): array {
$menu = parent::build($user, $currentPath);
// Add custom sections or reorder
return $menu;
}
}
interface AdminMenuBuilderInterface
{
public function build(AdminUserInterface $user, string $currentPath = ''): array;
public function buildDashboardSections(AdminUserInterface $user): array;
}
use Marko\Routing\Attributes\Get;
use Marko\Routing\Attributes\Post;
#[Get(path: '/admin/login')] // showLoginForm
#[Post(path: '/admin/login')] // authenticate
#[Post(path: '/admin/logout')] // logout
use Marko\Routing\Attributes\Get;
use Marko\Routing\Attributes\Middleware;
use Marko\AdminAuth\Middleware\AdminAuthMiddleware;
#[Get(path: '/admin')] // index
#[Middleware(AdminAuthMiddleware::class)] // requires auth
interface AdminPanelConfigInterface
{
public function getPageTitle(): string;
public function getItemsPerPage(): int;
}