sharf sharf - 16 days ago 9
PHP Question

Proper way to make a dynamic navigation in 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?

Answer

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.