Laravel. Использование View Composers
06.10.2020
Теги: Laravel • PHP • Web-разработка • Переменная • Теория • Фреймворк • Шаблонизатор • ШаблонСайта
При разработке сайтов часто возникает ситуация, когда некие данные являются общими для для многих или вообще всех страниц. Например — навигация в шапке или подвале, блок с популярными записами блога, меню каталога и т.д. Именно для таких случаев в Laravel предусмотрено готовое решение — View Composers.
Допустим, пункты меню мы будем хранить в базе данных.
> php artisan make:model MenuItems -m
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateMenuItemsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('menu_items', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('url'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('menu_items'); } }
> php artisan migrate
namespace App; use Illuminate\Database\Eloquent\Model; class MenuItem extends Model { // ..... }
Соответственно, при отрисовке какой-либо страницы, надо передать эти данные в представление. В первую очередь вынесем html-код навигации в отдельный файл. Для этого создадим в директории resources/views/layouts
поддиректорию parts
, в которой создадим файл menu.blade.php
— где и разместим наше меню.
<ul> @foreach($items as $item) <li><a href="{{ $item->url }}">{{ $item->name }}</a></li> @endforeach </ul>
Включим этот файл в шаблон с помощью @include()
:
@include('layouts.parts.menu')
Теперь создадим поставщика услуг:
> php artisan make:provider ComposerServiceProvider
И сразу добавим его в массив providers
файла конфигурации config/app.php
:
return [ /* ... */ 'providers' => [ /* ... */ App\Providers\ComposerServiceProvider::class, /* ... */ ], /* ... */ ];
Далее редактируем созданный app/Providers/ComposerServiceProvider.php
:
namespace App\Providers; use App\MenuItem; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // ..... } /** * Bootstrap services. * * @return void */ public function boot() { View::composer('layouts.parts.menu', function($view) { $view->with(['items' => MenuItem::all()]); }); } }
Если нужно отправить данные в несколько представлений:
class ComposerServiceProvider extends ServiceProvider { /* ... */ public function boot() { View::composer(['layouts.parts.header', 'layouts.parts.footer'], function($view) { $view->with(['items' => MenuItem::all()]); }); } }
Если нужно отправить данные во все представления:
class ComposerServiceProvider extends ServiceProvider { /* ... */ public function boot() { View::composer('*', function($view) { $view->with(['items' => MenuItem::all()]); }); } }
Если нужно отправить разные данные в разные представления:
class ComposerServiceProvider extends ServiceProvider { /* ... */ public function boot() { View::composer('layouts.parts.header', function($view) { $view->with(['items' => MenuItem::header()]); }); View::composer('layouts.parts.footer', function($view) { $view->with(['items' => MenuItem::footer()]); }); } }
namespace App; use Illuminate\Database\Eloquent\Model; class MenuItem extends Model { public static function header() { return self::where('place', 'header')->get(); } public static function footer() { return self::where('place', 'footer')->get(); } }
Метод composer()
может принимать не только callback-функцию, но и класс. Давайте в app/Http
создадим директорию ViewComposers
, а внутри нее два файла — NavHeaderComposer.php
и NavFooterComposer.php
.
namespace App\Http\ViewComposers; use App\MenuItem; use Illuminate\View\View; class NavHeaderComposer { public function compose(View $view) { return $view->with('items', MenuItem::header()); } }
namespace App\Http\ViewComposers; use App\MenuItem; use Illuminate\View\View; class NavFooterComposer { public function compose(View $view) { return $view->with('items', MenuItem::footer()); } }
Поскольку теперь мы используем класс, следует подкорректировать и файл ComposerServiceProvider.php
:
namespace App\Providers; use App\Http\ViewComposers\NavHeaderComposer; use App\Http\ViewComposers\NavFooterComposer; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider { /* ... */ public function boot() { View::composer('layouts.parts.header', NavHeaderComposer::class); View::composer('layouts.parts.footer', NavFooterComposer::class); /* view()->composer('layouts.parts.header', NavHeaderComposer::class); view()->composer('layouts.parts.footer', NavFooterComposer::class); */ } }
Перед началом отображения шаблона композер вызовет метод compose()
с экземпляром Illuminate\View\View
в качестве первого параметра.
- Laravel. Шаблонизатор Blade. Часть 2 из 2
- Laravel. Шаблонизатор Blade. Часть 1 из 2
- Магазин на Laravel 7, часть 7. Меню каталога товаров и популярные бренды в левой колонке
- Мини-блог на Laravel, часть 3. Постраничная навигация, layout-шаблон и поиск по блогу
- Блог на Laravel 7, часть 12. Доп.страницы сайта в панели управления и в публичной части
- Блог на Laravel 7, часть 11. Панель управления — назначение ролей и прав для пользователей
- Блог на Laravel 7, часть 10. Личный кабинет — CRUD-операции над постами и комментариями
Поиск: Laravel • PHP • Web-разработка • Переменная • Теория • Фреймворк • Шаблонизатор • Шаблон сайта