【PHP実践|実務向け】LaravelのView Composersでビューの共通部分を効率的に管理しよう

Webサイトを開発していると、ヘッダー、サイドバー、フッターといった、ページ間で共通して表示されるパーツが多く存在します。これらのパーツに表示するデータ(例えば、サイドバーの新着記事一覧やカテゴリー一覧など)は、各ページで同じような処理をコントローラーに記述し、ビューに渡すのが一般的です。しかし、ページ数が増えれば増えるほど、この共通の記述が各コントローラーに重複してしまい、コードの保守性が低下する原因となります。

基礎知識:View Composersとは?

Laravelの「View Composers」は、このようなビューの共通部分のデータ取得処理を、より効率的かつ DRY(Don’t Repeat Yourself)に管理するための機能です。View Composer を使うと、特定のビューが読み込まれる際に、あらかじめ定義しておいた処理を自動的に実行させ、必要な変数をビューに渡すことができます。これにより、各コントローラーでの重複した記述をなくし、コードをスッキリさせることができます。

View Composer には、大きく分けて2つの実装方法があります。

1. クロージャーを使用する方法: `ComposerServiceProvider` 内の `boot()` メソッドに直接、ビューとそれに渡すデータを定義します。
2. 専用のComposerクラスを作成する方法: 別途Composerクラスを作成し、そのクラス内でデータの取得とビューへの受け渡しを行います。

実装/解決策:View Composersの実装方法

ここでは、両方の実装方法を解説します。

1. クロージャーを使用する方法

まず、`app/Providers/ComposerServiceProvider.php` を作成(または編集)します。

  • Bootstrap services.
    • @return void

    /
    public function boot()
    {
    // ‘sidebar’ という名前のビューが読み込まれる際に実行される
    View::composer(‘sidebar’, function ($view) {
    // Categoryモデルから全てのカテゴリーを取得
    $categories = Category::all();
    // 取得したカテゴリー一覧を ‘categories’ という変数名でビューに渡す
    $view->with(‘categories’, $categories);
    });
    }

    /

    • Register services.
    • @return void

    /
    public function register()
    {
    //
    }
    }

    解説:

    • `View::composer(‘sidebar’, function ($view) { … });` のように記述します。
    • 第一引数 `’sidebar’` は、Laravelのビューファイル名を指定します。もしビューが `resources/views/layouts/sidebar.blade.php` のようにサブディレクトリにある場合は、`’layouts.sidebar’` と指定します。
    • 第二引数には、ビューに渡したいデータを取得し、`$view->with(‘変数名’, $データ)` の形式でビューに渡すクロージャー関数を記述します。
    • この `ComposerServiceProvider` を Laravel に認識させるために、`config/app.php` の `providers` 配列に `’App\Providers\ComposerServiceProvider::class’` を追加する必要があります。

    2. 専用のComposerクラスを作成する方法

    より複雑な処理や、コードの分離を行いたい場合に適しています。

    まず、Composerクラスを作成します。例として `app/Http/ViewComposers/SidebarComposer.php` というファイルを作成します。

  • The category repository implementation.
    • @var Category

    /
    protected $categories;

    /

    • Create a new controller instance.
    • @param Category $categories
    • @return void

    /
    public function __construct(Category $categories)
    {
    // コンストラクタでカテゴリー一覧を取得
    $this->categories = $categories->all();
    }

    /

    • Bind data to the view.
    • @param View $view
    • @return void

    /
    public function compose(View $view)
    {
    // 取得したカテゴリー一覧を ‘categories’ という変数名でビューに渡す
    $view->with(‘categories’, $this->categories);
    }
    }

    次に、`ComposerServiceProvider` の `boot()` メソッドを以下のように編集します。

  • Bootstrap services.
    • @return void

    /
    public function boot()
    {
    // ‘sidebar’ という名前のビューに対し、SidebarComposerクラスを適用する
    View::composer(‘sidebar’, ‘App\Http\ViewComposers\SidebarComposer’);
    }

    /

    • Register services.
    • @return void

    /
    public function register()
    {
    //
    }
    }

    解説:

    • `View::composer(‘sidebar’, ‘App\Http\ViewComposers\SidebarComposer’);` のように記述します。
    • 第一引数はクロージャーの場合と同様にビュー名を指定します。
    • 第二引数には、作成したComposerクラスのフルネームスペースを指定します。
    • Composerクラスの `compose()` メソッド内で、`$view->with()` を使用してビューに変数を渡します。

    サンプルプログラム

    ここでは、`resources/views/sidebar.blade.php` というビューファイルを作成し、上記のどちらかの方法で `categories` 変数が利用できるようにしたと仮定します。

    `resources/views/sidebar.blade.php`:

    `app/Http/Controllers/PostController.php` (例):

  • ブログ投稿一覧を表示するメソッド
    • @return \Illuminate\View\View

    /
    public function index()
    {
    // ここで投稿一覧などのメインコンテンツのデータを取得する
    $posts = \App\Post::latest()->take(10)->get(); // 仮のデータ取得

    // sidebar.blade.php は View Composer によって自動的に categories 変数が利用可能になる
    // そのため、ここで明示的に $categories を渡す必要はない
    return view(‘posts.index’, compact(‘posts’));
    }
    }

    `resources/views/posts/index.blade.php` (例):




    ブログ記事一覧

    最新記事

    @foreach ($posts as $post)

    @endforeach

    {{– sidebar.blade.php をインクルードする –}}
    {{– ここで sidebar.blade.php が読み込まれる際に View Composer が実行される –}}
    @include(‘sidebar’)


    応用・注意点

    • View Composer の登録場所: `ComposerServiceProvider` は、Laravelのデフォルトのプロバイダーの一つなので、通常は自動的に読み込まれます。もしカスタムプロバイダーを作成した場合は、`config/app.php` の `providers` 配列に追記することを忘れないでください。
    • `composer dump-autoload`: `ComposerServiceProvider` や Composer クラスのファイルパスを変更したり、新しく追加した場合は、Composer のオートローダーを再生成するために、プロジェクトルートで `composer dump-autoload` コマンドを実行する必要がある場合があります。
    • 複雑なロジックの分離: データの取得ロジックが複雑になる場合は、Composer クラスを作成する方がコードの見通しが良くなります。また、依存性注入(DI)を活用して、Eloquent モデルだけでなくリポジトリパターンなどを利用することも可能です。
    • 複数ビューへの適用: `View::composer()` メソッドは、複数のビューに対して適用することも可能です。例えば、`View::composer([‘sidebar’, ‘another_sidebar’], ‘App\Http\ViewComposers\SidebarComposer’);` のように記述できます。
    • `@include` と `View::composer` の連携: 上記のサンプルコードのように、`@include` ディレクティブでビューを読み込む際に、そのビューに紐づけられた View Composer が自動的に実行されます。これにより、ビューの共通パーツにデータを渡す作業が非常に効率化されます。

    View Composers を活用することで、Laravel アプリケーションのビューにおけるデータ管理が格段にシンプルになり、開発効率とコードの保守性を向上させることができます。

    タイトルとURLをコピーしました