Laravel中获取当前路由Slug及实现侧边栏菜单请求时自动展开并高亮
Hey there! Let's fix up your Laravel sidebar menu so it automatically expands and highlights the active item based on the current route's slug. I'll walk you through refactoring your code to make it dynamic and reusable, no more hardcoded paths!
First: How to Get the Current Route's Slug
There are a couple of reliable ways to grab the slug from your current route:
- If your route defines a
{slug}parameter (likeRoute::get('backend/{slug}', ...)), useRoute::current()->parameter('slug')to get the direct slug value. - For nested routes (e.g.,
backend/parent-slug/child-slug), you can get all parameters withRoute::current()->parameters()and check against your menu's slug values. - Alternatively, use
request()->segment(2)(for the second segment inbackend/{slug}) orrequest()->segment(3)for nested slugs.
Refactored Sidebar Menu Code
The main issues with your current code are hardcoded active checks and variable overwriting in loops. Let's rewrite it with recursion (for nested menus) and dynamic checks:
First, create a reusable Blade partial for submenus (e.g., resources/views/partials/sidebar-submenu.blade.php):
<li class="nav-item has-treeview {{ request()->is('backend/' . $menu->slug . '*') ? 'menu-open' : '' }}"> <a href="{{ url('backend/' . $menu->slug) }}" class="nav-link {{ request()->is('backend/' . $menu->slug) || request()->is('backend/' . $menu->slug . '/*') ? 'active' : '' }}"> {{ $menu->name }} @if(count($menu->children) > 0) <i class="fas fa-angle-left right"></i> @endif </a> {{-- Render child menus recursively --}} @if(count($menu->children) > 0) <ul class="nav nav-treeview {{ request()->is('backend/' . $menu->slug . '*') ? 'show' : '' }} dropdown" aria-labelledby="dropdownBtn"> @foreach($menu->children as $childMenu) @include('partials.sidebar-submenu', ['menu' => $childMenu]) @endforeach </ul> @endif </li>
Then update your main sidebar code to use this partial:
{{-- Top-level menu items --}} <li class="nav-item has-treeview {{ request()->is('backend/' . $menu->slug . '*') ? 'menu-open' : '' }}"> <a href="#" class="nav-link {{ request()->is('backend/' . $menu->slug) || request()->is('backend/' . $menu->slug . '/*') ? 'active' : '' }}"> {{ $menu->name }} @if(count($menu->children) > 0) <i class="fas fa-angle-left right"></i> @endif </a> {{-- Load submenus using the partial --}} @if(count($menu->children) > 0) <ul class="nav nav-treeview {{ $menu->parent_id === 0 ? 'dropdown' : '' }}"> @foreach($menu->children as $childMenu) @include('partials.sidebar-submenu', ['menu' => $childMenu]) @endforeach </ul> @endif </li>
What Changed & Why
Dynamic Active/Open Checks:
request()->is('backend/' . $menu->slug . '*'): This checks if the current route starts with the menu's slug path (works for both the menu's direct page and its nested subpages).- The
activeclass is added if the route is exactly the menu's URL or any subroute under it.
Recursive Rendering:
- By moving submenu logic into a partial, we can handle infinite levels of nested menus without repeating code.
- We renamed the loop variable to
$childMenuto avoid overwriting the parent$menuvariable (a common bug in nested loops!).
Cleaner Conditional Classes:
- Removed hardcoded checks like
request()->is('backend/library-setting*')— now every menu uses its own slug for checks.
- Removed hardcoded checks like
Bonus: Using Route Names (Even More Reliable)
If you've named your routes (e.g., Route::get('backend/{slug}', [MenuController::class, 'show'])->name('backend.menu')), you can use route names instead of URL paths for more stable checks:
{{-- For active class --}} class="nav-link {{ request()->routeIs('backend.' . $menu->route_name . '*') ? 'active' : '' }}" {{-- For menu-open class --}} class="nav-item has-treeview {{ request()->routeIs('backend.' . $menu->route_name . '*') ? 'menu-open' : '' }}"
Just make sure your menu model has a route_name field that matches your route names.
That should do it! Your sidebar will now automatically expand and highlight the correct menu item based on the current route's slug.
内容的提问来源于stack exchange,提问作者Munindra kanxa

