Creating Dynamic Nested Menus in Laravel with Relationships

0
3674
Dynamic-Nested-Menus

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.

LEAVE A REPLY

Please enter your comment!
Please enter your name here