9

I have a navigation bar like this.

<li>Account</li>
   <ul>
      <li>Register</li>
      <li>Login/li>
      ...

I want to update this dynamically depending on Auth::check(). For example, if the user is logged in, "Account" will be changed with "My Profile Page" and child siblings will be replaced with an appropriate array.

I need to do this without editing View::make calls in my controllers. It looks pretty bad.

A solution like this is what I'm looking for;

View::composer('home.*', function($view) {
    if(Auth::check())
       return $view->nest('accountArea', 'home.navigation-loggedIn', null);
    else
       return $view->nest('accountArea', 'home.navigation-visitor', null);
});

If there are better alternatives, I would like to hear them too!

Raymond Ativie
  • 1,747
  • 2
  • 26
  • 50
Aristona
  • 8,611
  • 9
  • 54
  • 80
  • 1
    What about binding the view composer to your layout instead? – Phill Sparks May 23 '13 at 11:04
  • Can you elaborate this a bit? – Aristona May 23 '13 at 11:54
  • Well, I'm assuming that you're using layouts, and that you want to nest onto the layout (not your actual content's view). So you'd do something like `View::composer('layouts.default', ...)`. – Phill Sparks May 23 '13 at 12:02
  • @PhillSparks Yes. I have a layout.blade.php which contains the general markup plus @yield('content'). So, doing `View::composer('home.layout', ...)` does automatically bind all the content files yielding on defined layout? Also I want to ask one more thing. (similar question) How do the people using Laravel handle 'always has to be binded' things like `'{{ $title }}'`. Is there any good-practice uses I can have a look at? – Aristona May 23 '13 at 12:35
  • @Imaqtpie, [this may help you](http://heera.it/laravel-4-view-composer-master-layout). – The Alpha May 28 '13 at 23:12

3 Answers3

13

Seems like the wildcards in Laravel works. They're just undocumented as of now.

View::composer('admin.layouts.*', function($view)
{
     if (Sentry::check()) $view->with('navigation', View::make('admin._partials.navigation'));
     else                 $view->with('navigation', null);
});

That's what I was looking for.

Update: Here is an alternative solution

You can also bind it to the layout, so all the subviews that extend that layout will benefit from composer.

View::composer('admin.layouts.main_layout', function($view)
{
     if (Sentry::check()) $view->with('navigation', View::make('admin._partials.navigation'));
     else                 $view->with('navigation', null);
});

It will bind composers to every view that does @extend('admin.layouts.main_layout').

Aristona
  • 8,611
  • 9
  • 54
  • 80
  • The view composer thing didn't work in my case. I sent a variable to a layout. but it was only available in the layout and not in views that extended it. I userd `View::share(key, value)` – Shashank Jain May 06 '15 at 14:45
  • Is it possible to have it not apply to some views? So reverse the wildcard? – Miguel Stevens Aug 07 '19 at 14:19
3

You can use View::share('variable', 'value') to share a variable across all views.

Maxime Fabre
  • 2,252
  • 3
  • 20
  • 24
0

Like Aristona says (thanks for de advice!): wildcards are allowed. Glancing at the code, we can see how Composers are Event Listeners, and in that section of the documentation is pointed out: Wildcard event listeners.

Adding a little bit more, ultimately, Str::is() is used by Events\Dispatcher to detect wildcar listeners. For example, something like this:

str_is('namespace::*.view', 'namespace::folder.view')

In short, I agree that would not hurt a small informative phrase :)

seus
  • 661
  • 10
  • 11