13.x 與 Framework v13.37.0 的實作,深入探討套件開發基礎。一般的模板語法請參閱 Blade,View 的命名空間與公開請參閱套件 View 的覆寫與更新。
區分註冊、編譯與執行
傳給Blade::directive() 的回呼函式回傳的不是要顯示的值,而是要產生的 PHP 程式碼字串。參數 $expression 也不是已求值的值,而是寫在模板中的 PHP 運算式。
view:cache 也會進行編譯。在指令的產生用回呼函式中,應設計成不取得目前使用者、不寫入資料庫、也不呼叫外部 API。
以套件專屬名稱註冊
以下範例提供@acmeCourierLabel($code),在配送代碼前顯示所設定的標籤。前提是透過 Composer 的 PSR-4 設定將 Acme\Courier\ 對應到 src/,並以自動探索或手動方式註冊提供者。
src/CourierServiceProvider.php
courier.label 是字串,courier.enabled 是 boolean。設定檔的發布與合併請參閱套件設定的合併與快取。
註冊在一般提供者的 boot() 中進行,不要以 runningInConsole() 條件包住。HTTP 渲染與 Artisan 的 view:cache 都需要相同的擴充。也請避免將只註冊 Blade 擴充的提供者設為延遲提供者,使其直到其他服務被解析時才啟動。
參數以運算式而非值的形式接收
$code。產生的 PHP 如下所示。
config() 與 $code 的求值發生在執行此 PHP 的時間點。這與回呼函式本身讀取 config() 並回傳固定字串的實作不同。
經確認,callCustomDirective() 會移除外側的括號並 trim 運算式後,再傳給回呼函式。它不會將參數轉換為 PHP 的值,也不會拆分成個別參數。此範例以傳入一個必要運算式的語法公開。
處理多個參數時,請不要單純以逗號進行 explode()。陣列、方法呼叫與字串常值中也可能含有逗號。若要處理屬性或複雜的 HTML,以 Blade 元件的形式提供,較容易劃分職責。
名稱衝突也是相容性問題
directive() 會以名稱為鍵,將處理器儲存到陣列中。若名稱相同就會覆寫先前的註冊,而 compileStatement() 會優先選擇自訂指令,而非內建的轉換方法。官方測試中也有以自訂註冊覆寫 foreach 的案例。
請避免 label 或 enabled 這類通用名稱與內建名稱,並加上套件專屬的前綴。使用者在模板中使用的名稱與參數應視為公開 API,變更時請提供遷移步驟。
條件分支以 Blade::if 在執行時判斷
上方提供者所註冊的條件可以如下使用。Blade::if() 會先儲存條件回呼函式,再註冊開始、unless、else 與結束用的指令。此範例的開始部分會轉換為以下 PHP。
check() 呼叫。這並不是在編譯時固定 true 或 false 結果的處理。即使是使用已編譯 View 的 HTTP 程序,也需要註冊條件的回呼函式。
此語法是用來切換顯示內容,而非配送操作的授權。存取控制也要在路由或操作端實施。
套件更新不一定會自動重新產生 View
經確認,Compiler::isExpired() 會檢查快取是否存在,並依設定比對原始 View 與已編譯檔案的更新時間。它不會將提供者中所寫指令的變更作為相依檔案來追蹤。
官方文件也建議在變更指令的邏輯後,以
view:clear 刪除快取。請在使用端應用程式的部署流程中,於更新後的套件與使用者的 View 一致之後執行。
view:cache 是在正式環境中預先編譯時執行。請不要從套件的 boot() 每次都清除快取,也不要在安裝時擅自改寫使用端應用程式的部署流程。設定快取的更新與常駐程序的重新載入,也請依照使用環境的一般部署步驟進行。
分別驗證編譯結果與渲染結果
首先,在已註冊上述提供者的測試用 Laravel 應用程式中,驗證所產生的 PHP。以下是要加入繼承Tests\TestCase 的 Feature 測試中的方法。
相關頁面
套件 View 的覆寫與更新
確認命名空間的搜尋順序,以及維護已公開模板的方法。
套件快取與 optimize 的整合
確認將自訂快取的建立與刪除整合到部署流程的方法。