In Laravel, you can create dynamic nested menus by making use of relationships between your models. In this blog, we will be covering how to create dynamic nested menus in Laravel using relationships.
When building a web application, menus play a crucial role in making the navigation of the application easier for the users. In some cases, the menus are simple and can be easily managed through static HTML or in Laravel’s case, Blade templates. However, when you have a large number of menu items, or you want to allow for dynamic updates to your menus, a static solution may not be the best option.
Step 1: Create a Model for the Main Menu Items
To begin, we will create a model for the main menu items. Let’s call it MenuItem
. To create the model, you can run the following command in your terminal:
php artisan make:model MenuItem
Step 2: Define the Relationship Between the Parent and Child Menu Items
Next, we will define the relationship between the parent and child menu items in the MenuItem
model. We will use the hasMany
relationship method to define the relationship.
class MenuItem extends Model
{
public function children()
{
return $this->hasMany(self::class, 'parent_id');
}
}
In the code above, we are defining a relationship between the MenuItem
model and itself. The children
method returns all the menu items that have a parent_id
equal to the current menu item’s id
.
Step 3: Create a Migration for the Menu Item Table
We will now create a migration for the menu item table. In your terminal, run the following command:
php artisan make:migration create_menu_items_table
This will create a new migration file in the database/migrations
directory. In the migration file, add the following code:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMenuItemsTable extends Migration
{
public function up()
{
Schema::create('menu_items', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('url')->nullable();
$table->unsignedInteger('parent_id')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('menu_items');
}
}
Step 4: Populate the Menu Item Table
Next, we will populate the menu item table with some sample data. In your seeder file, add the following code:
use Illuminate\Database\Seeder;
use App\MenuItem;
class MenuItemSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
MenuItem::create([
'title' => 'Home',
'url' => '/',
]);
MenuItem::create([
'title' => 'About Us',
'url' => '/about-us',
]);
$services = MenuItem::create([
'title' => 'Services',
'url' => '/services',
]);
MenuItem::create([
'title' => 'Web Development',
'url' => '/services/web-development',
'parent_id' => $services->id,
]);
MenuItem::create([
'title' => 'Mobile Development',
'url' => '/services/mobile-development',
'parent_id' => $services->id,
]);
MenuItem::create([
'title' => 'Contact Us',
'url' => '/contact-us',
]);
}
}
In the code above, we are using the MenuItem
model to create new menu items in the database. We are also setting the parent_id
of some menu items to the id
of the parent menu item. This will create a nested relationship between the menu items and allow us to display the dynamic nested menus in our view.
Now, add this file in DatabaseSeeder.php file.
$this->call(MenuItemSeeder::class);
After that, seed the database using following command.
php artisan db:seed
Step 5: Display the Dynamic Nested Menus in Your View
Finally, we will display the dynamic nested menus in our view. We will use a recursive blade component to render the menu items and their child items.
Create a new blade component called menu-item
using the following command:
php artisan make:component MenuItem
In the component file, add the following code:
<li>
<a href="{{ $menuItem->url }}">{{ $menuItem->title }}</a>
@if($menuItem->children->count())
<ul>
@foreach($menuItem->children as $child)
<x-menu-item :menuItem="$child"/>
@endforeach
</ul>
@endif
</li>
In the code above, we are using a foreach loop to iterate through the children
of the current menu item and rendering the menu-item
component for each child item.
Finally, in your view, you can use the following code to display the dynamic nested menus:
<ul>
@foreach(\App\MenuItem::whereNull('parent_id')->get() as $menuItem)
<x-menu-item :menuItem="$menuItem"/>
@endforeach
</ul>
In the code above, we are using a foreach loop to iterate through all the menu items that have a parent_id
equal to null
and rendering the menu-item
component for each of these items.
Conclusion
In this blog, we covered how to create dynamic nested menus in Laravel using relationships. By using models and relationships, you can easily manage your menus and make updates to them without having to manually update your HTML or Blade templates. With the help of blade components, you can make the process of rendering your menus in your views much simpler.