Laravel: Как передать глобальные переменные в Blade.

Источник: «How to Pass Global Variables to Blade: View Share and Composer»
Представьте, что вы хотите показать некие глобальные данные в Blade: например, количество новых пользователей на этой неделе в верхнем блоке навигации. Не знаете от каких контроллеров будут поступать данные? Вы можете выполнить это действие в Service Provider тремя способами.

Например, вы хотите, чтобы это было в resources/layouts/app.blade.php, где-то в навигации:

<div class="flex flex-shrink-0 items-center mr-4">
Users this week: {{ $newUsersThisWeekCount }}
</div>

Это будет отображаться на всех страницах расширяющих этот макет. Итак, где инициализируем переменную?

Ответ: в Service Provider. В любом из них, кроме этого простого примера, мы будем использовать метод boot() стандартного AppServiceProvider поставляемого Laravel, поэтому не нужно генерировать какие-либо новые классы.

Вариант 1. View Share

app/Providers/AppServiceProvider.php:

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->share('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
}
}

Это позволит использовать значение переменной $newUsersThisWeekCount для всех представлений Blade, а не только в блоке навигации или боковой панели.

Вариант 2. Обратный вызов View Composer

Если вы хотите сделать значение доступным только в определённом представлении Blade, используйте это:

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->composer('layouts.app', function ($view) {
$view->with('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
});
}
}

Вы можете указать несколько представлений:

view()->composer(
['layouts.app', 'layouts.sidebar'],
function ($view) {
$view->with('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
}
);

Или даже используйте звёздочку * для указания всех представлений:

view()->composer('*', function ($view) {
$view->with('newUsersThisWeekCount',
User::where('created_at', '>', now()->subDays(7))->count());
});

Примечание: будьте ОЧЕНЬ осторожны с этой опцией звёздочки, потому что она будет загружать один и тот же SQL-запрос для КАЖДОГО представления, включая все частичные представления Blade.

Вариант 3. View Composer класс

Если у вас более сложная логика и вы не хотите загрязнять Service Provider большим количеством кода, вы можете создать отдельный класс View Composer.

В Artisan нет команды php artisan make:viewcomposer, поэтому класс нужно создать вручную, и вы сами выбираете где его разместить. Например:

app/View/Composers/NewUsersComposer.php:

namespace App\View\Composers;

use Illuminate\View\View;

class NewUsersComposer
{
public function compose(View $view)
{
$newUsersThisWeekCount = your_complicated_logic();

$view->with('newUsersThisWeekCount', $newUsersThisWeekCount);
}
}

Затем вы должны зарегистрировать его в Service Provider следующим образом:

app/Providers/AppServiceProvider.php:

use App\View\Composers\NewUsersComposer;

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
view()->composer('layouts.app', NewUsersComposer::class);
}
}

Дополнительные материалы

Предыдущая Статья

Laravel: Eloquent упорядочивание по hasMany отношениям

Следующая Статья

Laravel: Eloquent Наблюдатели не выполняются при массовых событиях