![](https://ahmedshaltout.com/wp-content/uploads/2023/09/view-composers.jpg)
Learn How to use Service Providers and View Composers of Laravel to share data with multiple views or specific views. Avoid repeating your code and write better clean maintainable code.
We will explain two important method of sharing the data, the View
facade’s share
method and View composers.
The benefits of using these methods:
- They allow you to centralize the logic for fetching and binding sharing data in a single location. This makes your code more DRY and easier to maintain.
- The Data that is shared using the
share()
method can be accessed by all views. This saves you time and effort, and helps to ensure that your views are consistent. - View composers can be reused across multiple views. This saves you time and effort, and helps to ensure that your views are consistent.
- The
share()
and View composers method can be used to share any type of data with views. This makes it a very flexible tool that can be used to solve a variety of problems.
Sharing data with all views in Laravel
Sometimes we need to share some data all over our views in Laravel and that is hard to do via controllers or route functions but Laravel has got our back with the View
facade’s share
method.
use Illuminate\Support\Facades\View;
View::share('key', 'value');
This syntax of the View facade’s method is simple key and value, and we will use the key as a variable all over our application’s views $key
.
We should use this method in a boot
method in a service provider to be loaded with the application instance. for example, we can use it in App\Providers\AppServiceProvider.php
or in a new service provider but make sure it’s in the boot function. The boot()
method is called when the application is booting up and is a good place to register any application services that need to be available before the application starts handling requests.
If you want to learn more about Service Providers and Dependency Injection In Laravel, check out this tutorial: Service Providers & Dependency Injection In Laravel Explained With Examples.
Let’s share our data, let’s say you want to share the current application language and the direction (right to left) or (left to right) so you can localize your web pages.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
//sharing app lang data and direction
$localeDirs = config('app.localeDirs');
/* This array at Application Locale Configuration in app.php
'localeDirs'=>[
'ar'=>'rtl',
'en'=>'ltr'
],
*/
$locale = app()->getLocale();
$dir = $localeDirs[$locale];
View::share('locale',$locale);
View::share('dir', $dir);
}
}
The View::share()
method is used to share data with the Blade view engine. This data will be available in all views and can be accessed using the {{ $variable }}
syntax.
<!-- view blade -->
<main class="content" dir="{{$dir}}">
<div>
{{ __('current lang') }} : {{$locale}}
</div>
</main>
Share Data With Specific Views With View Composers.
We use View Composers when we have a view that can be part of another main view or when we want to share data with specific views, not all views. So instead of repeating the code of getting these data in every controller, we can create a view composer class to be called when the view gets rendered.
View composers must be registered with a service provider such as App\Providers\ViewServiceProvider
.
View Composers Example.
Let’s say the website header header.blade.php
and you want to include it in the website layout app.blade.php
. The header will include the navbar that has the categories list that comes from the database. The best way to achieve that create a view composer class that holds all the logic like the controller and the class will be called automatically when the view gets rendered.
Let’s demonstrate that with a code example, first, we need to create a composer class. we could create a app/View/Composers
directory to house all of your application’s view composers
<?php
namespace App\View\Composers;
use Illuminate\View\View;
use App\Models\Category;
class CategoriesComposer
{
/**
* Create a new profile composer.
*/
public function __construct(
) {}
/**
* Bind data to the view.
*/
public function compose(View $view): void
{
$view->with('categories', Category::where('lang_id',app()->getLocale())->where('status','active')->get());
}
}
The CategoriesComposer
class has a single method, compose()
, which is called when a view is rendered. The compose()
method takes a View object as its argument and can be used to bind data to the view.
In this case, the compose()
method is used to bind the categories to the view. The categories are fetched from the database using the Category::where('lang_id',app()->getLocale())->where('status','active')->get()
query.
The lang_id
and status
filters are used to ensure that only the categories for the current locale and that are active are returned.
Once the categories have been fetched, they are bound to the view using the with()
method. This means that all views that use the CategoriesComposer
will have access to the categories data.
As mentioned above to bind the view composer with a view we must register it within one of our application’s service providers.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
use App\View\Composers\CategoriesComposer;
class ViewDataServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
//
}
/**
* Bootstrap services.
*/
public function boot(): void
{
View::composer(
['header'],
CategoriesComposer::class
);
}
}
We register the CategoriesComposer
class within ViewDataServiceProvider
service provider in the boot function. View::composer
takes the first argument as an array of the views that will call the CategoriesComposer
in the second argument.
Now we can use the categories as variables {{$categories}}
in the header.blende.php
<ul>
@foreach ($categories as $category)
<li>{{ $category->name }}</li>
@endforeach
</ul>
Attaching A Composer To Multiple Blade Views
Let’s create another class that gets us the website information from the database such as the name and logo.
<?php
namespace App\View\Composers;
use Illuminate\View\View;
use App\Models\Info;
class InfoComposer
{
/**
* Create a new profile composer.
*/
public function __construct(
) {}
/**
* Bind data to the view.
*/
public function compose(View $view): void
{
$view->with('info', Info::where('lang_id', app()->getLocale())->first());
}
}
Let’s register our class.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
use App\View\Composers\InfoComposer;
use App\View\Composers\CategoriesComposer;
class ViewDataServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
//
}
/**
* Bootstrap services.
*/
public function boot(): void
{
View::composer(
['header'],
CategoriesComposer::class
);
View::composer(
['layouts.app', 'layouts.adminLayoutParts.sideBar'],
InfoComposer::class
);
}
}
In the View::composer we add two views to bind the website info with resources\views\layouts\app.blade.php
and resources\views\layouts\adminLayoutParts\sidebar.blade.php
We can use it in the blade like that.
<a class="navbar-brand" href="{{ url('/') }}">
<img src="{{url($info->logo)}}" width="140" alt="{{$info->name}}">
</a>
More methods of binding and registering view composer
Creating view composers in a separate class is the best way to write clean maintainable code. but according to the Laravel documentation, there are some more methods that achieve the same result of binding data to views.
namespace App\Providers;
use App\View\Composers\ProfileComposer;
use Illuminate\Support\Facades;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\View;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
// Using class based composers...
Facades\View::composer('profile', ProfileComposer::class);
// Using closure based composers...
Facades\View::composer('welcome', function (View $view) {
// ...
});
Facades\View::composer('dashboard', function (View $view) {
// ...
});
}
}
Conclusion
The View
facade’s share()
method is a powerful tool for sharing data with multiple views in your Laravel application. It allows you to bind data to the view engine, which means that it will be available to all views that are rendered.
View composers are a powerful tool for sharing data with multiple views in your Laravel application. By centralizing the logic for fetching and binding data in view composers, you can keep your code DRY and easy to maintain.
View composers are a powerful tool for sharing data with multiple views in your Laravel application. By centralizing the logic for fetching and binding data in view composers, you can keep your code DRY and easy to maintain. View composers can be used to share a variety of data with views, such as User data, Site settings, Navigation menus, And much more.
To use view composers, simply register them in your Laravel service provider. You can then use them in your views by binding the necessary data to them.
I hope that was useful for you, thank you.