在Laravel 5中进行动态导航的正确方法

I'm building my first Laravel application using 5.1, it's an ecommerce site.

I've started by creating the "static" pages. I quote because the pages are not dynamically generated from product lists etc, but the html is still retrieved from the database.

I've created a PagesController, a Page model, the pages/index.blade.php and pages/show.blade.php views, as well as a MasterTemplate.blade.php template file.

My routes.php looks like:

$router->get('/', [
    'uses' => 'PagesController@index',
    'as' => 'pages.index'
]);

$router->get('/{page}', [
    'uses' => 'PagesController@show',
    'as' => 'pages.show'
]);

This works fine, I can view my index and individual pages that are in the DB.

My problem occurs when I go to add my navigation. Since I plan on using two different navigation bars (one for user, one for admins), I opted to create a _navDefault.php file to include in the MasterTemplate.

Stripping out the excess html it looks like:

@foreach ($pages as $page)
    <li>{!! link_to_route('pages.show', $page->title, [$page->slug]) !!}</li>
@endforeach

This generates the links just fine and they work. But because my PagesController:

...
public function index()
{
    $pages = $this->page->get();
    return view('pages.index', compact('pages'));
}
...

$pages only exists on the index view, and so navigating to a show view gives me an error that $pages is undefined, which makes perfect sense.

I could define $pages in the show method, but I will also have other controllers such as ProductController and CartController that will have their own pages I will need in the navigation bar, and I can't very well include $pages, $products, and $cart in every index and show method for each controller.

I'm still fairly new to MVC so I'm not sure of the best way to handle this, with a nav controller/model or something else.

What is the proper way to achieve dynamic navigation bars using multiple controllers?

This is how I'm able to have my dynamic navbar everywhere in my app.

Test the following within the boot method of the AppServiceProvider:

View::composer('*', function($view)
{
    $view->with('pages', Page::all());
});

The * means all views will receive $pages.

You can now extract it to a Service Provider dedicated to view composers.

If I understood your question right, you need to create a partial view for your navigation and use a view composer to make sure that partial view has the proper data.

docs

For Laravel 5.2

public function boot()
{
    //I use categories in my case and call model category at start of this file
    view()->composer('*', function ($view) {
        $categories = Category::all();
        $view->with('categories', $categories);
    });
}

[edit] It is my project and I am always available for its contribution on github.

A perfect-for-your-issue Laravel 5.4 Supported Package for Creating Dynamic, Database Driven, Bootstrap supported, Drop Down Menu is available.

https://github.com/secrethash/dropmenu

Install it using:

composer require secrethash/dropmenu

Usage:

use Dropmenu;

class SampleController extends Controller {
    public function index() {
            $menu = Dropmenu:: display('menuName');

            return view('some.view', ['menu' => $menu]);
    }
}

OR simply use it in the blade template

@extends('demoLayout')

@section('menu')
    {!! Dropmenu:: display('menuName') !!}
@endsection

Full Documentation: https://secrethash.github.io/dropmenu