youss
youss

Reputation: 57

How do I inject data in my sidebar that is included in every single blade of my project

I'm using a layout system and my sidebar is included in my master, and my master page is the layout for all my blades

//master.blade.php
<div clas="main-wrapper" id="app">
    @include('layout.sidebar')
    <div class="page-wrapper">
      @include('layout.header')
      <div class="page-content" >
        @yield('content')
      </div>
    </div>
  </div>

I want to display on the sidebar items the project names that belongs to the authenticated user.

So I tried the first solution which is to use the route function like this:

 //web.php
 Route::any('/home',function(){
  $p = DB::table('projets')
      ->join('users', 'users.id', '=', 'projets.ID_chercheur')
      ->select('projets.nom', 'users.name', 'users.prenom')
      ->where('projets.ID_chercheur','=',Auth::user()->id)
      ->get();
      return view('dashboard')->with(['projets' => $p]);    
  });

the problem with this solution that it works only in my dashboard view, any other view it won't work it will give me the following error:

ErrorException

    Undefined variable: projets (View: C:\laragon\www\Labo1\resources\views\layout\sidebar.blade.php)

I understand what the error means but I don't know how to fix it, I tried:

//web.php
Route::match(['get', 'post', 'PUT', 'PATCH','DELETE'], '/', function () {
  $p = DB::table('projets')
      ->join('users', 'users.id', '=', 'projets.ID_chercheur')
      ->select('projets.nom', 'users.name', 'users.prenom')
      ->where('projets.ID_chercheur','=',Auth::user()->id)
      ->get();
      return ['projets' => $p];
});

but it doesn't work either, could someone tell me what solution could I use?

Upvotes: 1

Views: 1124

Answers (4)

youss
youss

Reputation: 57

Hey guys thank you so much for your answers but i found a simple way to resolve my problem i wasn't familiar with the php syntax in laravel so my friend helped me and this solution seemed to help me:

@php
$projets=DB::table('projets')
       ->join('users', 'users.id', '=', 'projets.chefProjet')
       ->select('projets.nom', 'users.name', 'users.prenom')
       ->where('projets.chefProjet','=',Auth::user()->id)
       ->get();
@endphp

...

I puted this piece of code in the top of my sidebar.blade.php and now i can work with the data in the same page and also the data is loaded with every other blade

 if(count($projets)>0)
          @foreach ($projets as $p)
          <li class="nav-item {{ active_class(['forms/*']) }}">
            <a class="nav-link" data-toggle="collapse" href="#forms" role="button" aria-expanded="{{ is_active_route(['forms/*']) }}" aria-controls="forms">
              <i class="link-icon" data-feather="trello"></i>
              <span class="link-title" name="monspan">{{$p->nom}} </span>
              <i class="link-arrow" data-feather="chevron-down"></i>
            </a>
     </li>
....
          @endforeach
     @elseif(count($projets)==0)
           <li class="nav-item">
              <p class="text-muted">Aucun projet active</p>
           </li>
     @endif

i got to learn about the providers from your answers so once again thank you for your time

Upvotes: 0

Saddam
Saddam

Reputation: 1206

Another Approach

if you have limited data to access in all views like for only projects data then definitely go for view composers but if you think that in future you have to access multiple external data then you can make a separate helper file and write code there like make functions and then in your blade just simply call those functions.

Implmentation

Create a helpers.php file in your app folder and load it up with composer like:

"autoload": {
    "classmap": [
        ...
    ],
    "psr-4": {
        "App\\": "app/"
    },
    "files": [
        "app/helpers.php" // <---- ADD THIS
    ]
},

After adding that to your composer.json file, run the following command:

composer dump-autoload

If you don't like keeping your helpers.php file in your app directory (because it's not a PSR-4 namespaced class file), you can do what the laravel.com website does: store the helpers.php in the bootstrap directory. Remember to set it in your composer.json file:

"files": [
    "bootstrap/helpers.php"
]

Then in your helpers.php file make a function

<?php

function getProjects()
{

  $p = \DB::table('projets')
            ->join('users', 'users.id', '=', 'projets.ID_chercheur')
            ->select('projets.nom', 'users.name', 'users.prenom')
            ->where('projets.ID_chercheur','=',Auth::user()->id)
            ->get();

   return $p;

}

and access it in blade like {{ getProjects() }}

Upvotes: 0

Saddam
Saddam

Reputation: 1206

Use View Composer to tackle the issue. View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.

Implementation

Step 1 Create Service Provider

php artisan make:provider ViewServiceProvider

Step 2 Register Service Provider

You will need to add the service provider to the providers array in the config/app.php configuration file.

Like add this App\Providers\ViewServiceProvider::class, to providers array, then run config:cache to clear cache and regenerate config.

Step 3 Write Logic in Provider's Boot Method

<?php

namespace App\Providers;

use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class ViewServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        

        // Using Closure based composers...
        View::composer('layout.sidebar', function ($view) {
            $p = DB::table('projets')
            ->join('users', 'users.id', '=', 'projets.ID_chercheur')
            ->select('projets.nom', 'users.name', 'users.prenom')
            ->where('projets.ID_chercheur','=',Auth::user()->id)
            ->get();

                $view->with('projets', $p);
        });
    }
}

then you can access projets in your blade like {{projets}} and the foreach over it or whatever.

Further Refer to Documentation

Upvotes: 2

Flo Espen
Flo Espen

Reputation: 469

I think what you want is something like this in one of your ServiceProviders (e.g. AppServiceProvider)

View::composer('layout.sidebar', function ($view) {
$p = DB::table('projets')
  ->join('users', 'users.id', '=', 'projets.ID_chercheur')
  ->select('projets.nom', 'users.name', 'users.prenom')
  ->where('projets.ID_chercheur','=',Auth::user()->id)
  ->get();

                $view->with('projets', $p);
            });

I haven't tried it out myself. But I think it should also work for partials.

Upvotes: 0

Related Questions