Laravel - View Composer

在開始介紹 View composer 之前

首先關於 View 的一些用法為,指定 Template 以及要帶入的參數

<?php 
return view('view_name', ['key'=>'value',...]);

同樣的

也可以使用 with 來攜帶參數

view('view_name')->with('name', 'Victoria');

接下來,正式開始介紹 View composer:

View Composer

Laravel view composer 主要有兩種方式可以表示: 基於 Class 以及基於 Closure

Class based

<?php
View::composer('home', 'App\Http\ViewComposers\HomeComposer');

//OR
    
View::composer(['home', 'about', 'history'], ...);

//OR
// * 表示為全部 view 都會帶入
View::composer(['*'], ...);


// 表示為 ~/resource/views/admin/*
View::composer(['*admin.*'], ...);

Class based 基於關注點分離(spearation of concerns, SoC)的模組化做法,其中的優點在於可以程式碼可以被獨立測試,並且相當好維護。

首先,透過 View::composer 所帶入的第一個參數是 View name,可以是字串(string)或陣列(array)

當指定的 Template 被 render 時,就會觸發 view composer 並且帶入參數到 view

接著則是可以透過第二個參數,帶入 Class 載入 View template 中

Closure based

<?php 
View::composer('home' , function($view){
    $view->with('nav', [...mydata]);
});

//OR
    
View::composer(['home', 'about', 'history'], ...);

//OR
// * 表示為全部 view 都會帶入
View::composer(['*'], ...);


// 表示為 ~/resource/views/admin/*
View::composer(['*admin.*'], ...);

Closures based 的做法比較簡單,

首先,第一個參數同樣是表示 View name,可以是字串(string)或陣列(array)

第二個參數是要傳入 View 的變數,這裡可以看到是透過 with 方法將參數傳入 view

但是缺點就是效率比較差,在設定過程會重複載入 service provider 。

使用方式

首先,手動創建資料夾

app/Http/ViewComposers

接著建立一個 TestComposer

<?php 
namespace App\Http\ViewComposers;

class TestComposer
{
    public function compose($view)
    {
        $view->with('class_data', 'Hi this is class base data');
    }
}

接著,創建一個 service provider

php artisan make:provider TestServiceProvider

在 serivce provider boot 引入 view composer

<?php

namespace App\Providers;

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

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

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //class based
        View::composer(
            'welcome', 'App\Http\ViewComposers\TestComposer'
        );
        //closure based
        View::composer(
            'welcome', function($view) {
                $ivew->with('closure_data'=>'hi this is closure data')
            }
        );
    }
}

測試

這裏,最後建立一個測試,來檢驗 view composer 是否存在

php artisan make:test ViewComposerTest --unit
<?php

namespace Tests\Unit;

use Tests\TestCase;

class ViewComposerTest extends TestCase
{
    /**
     * Test Has Closure data
     *
     * @return void
     */
    public function testHasClosureData()
    {
        $this->get('/')->assertViewHas('closure_data');
    }
    /**
     * Test Has Class data
     *
     * @return void
     */
    public function testHasClassData()
    {
        $this->get('/')->assertViewHas('class_data');
    }
}