Blade 是什麼?
Blade 是 Laravel 框架的 Template Engine。關於 Template Engine 可參考維基百科說明。
在 Server-side MVC 架構下按語言、框架不同,通常會有個 Template Engine 來幫助處理前端 View 的開發,例如在 Node.js
可以選擇使用 Pug
或 EJS
、ASP.NET MVC
使用 Razor
..等等。
除了(能透過 Controller)取得 Model 來的資料,也可以透過語法去做到邏輯判斷、迴圈渲染、HTML 段落 (Template) 拆分與引用,以此做到開發上 View 相關程式碼的共用、繼承,並最終可以 build 成 完整的 HTML。
需要擔心效能嗎?
按照 Laravel 文件說法,Blade 和其他 PHP Template Engine 不同之處在於 Blade 不限制在檔案內使用原生 PHP Code。且所有 Blade View 實際上還是被 Compile 成原生的 PHP 而非 HTML,效能不至於有太大影響,不用太擔心這個問題。
檔案命名
Blade 檔案通常放在resources/views
下,並使用 .blade.php
作為文件的副檔名後輟名稱。
例如:
- Blade 檔案:
header.blade.php
、footer.blade.php
- 一般 PHP:
header.php
、footer.php
官方範例:拆分 Layout
使用 Blase 拆分各個 Templete Layout,最重要的就是 @section
和 @yield
兩個語法了。
首先我們在 resource/views/
建立一個子資料夾 layout
,並在layout
資料夾裡頭建立一個 app.blade.php
:
- resources/views/layouts/app.blade.php
<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
接著在 resource/views/
建立一個 child.blade.php
- resource/views/child.blade.php
@extends('layouts.app')
@section('title', 'Page Title')
@section('sidebar')
@parent
<p>This is appended to the master sidebar.</p>
@endsection
@section('content')
<p>This is my body content.</p>
@endsection
最後到 /routes/web.php
加入這段
- routes/web.php
Route::get('/child', function () {
return view('child');
});
接著到網址輸入http://127.0.0.1:8000/child
可以看到網頁正常顯示
這個過程發生了什麼事呢?在上面的程式碼裡,我們看到了 @extends
、@yield
、@section
、@parent
、@show
使用 @extends() 繼承 Layout View
我們在 child.blade.php
的開頭@extends('layouts.app')
,繼承了app.blade.php
的內容,但 @extends()
括弧內的 layouts.app
是什麼意思?
layouts.app
其實指的是 layouts 資料夾下的 app 這個 blade 檔案,也就是 app.blade.php
若我們將 app.blade.php
改名成 test.blade.php
,那 @extends('layouts.app')
就要改成 @extends('layouts.test')
。
也就是說資料夾的階層區隔不是用 /
而是用 .
,若是 app.blade.php
和 child.blade.php
同一層,那麼 @extends
就要寫成 @extends('app')
總來得來說,因為使用了 @extends()
繼承了 app.blade.php
,我們可以在接下來用 @yield 和 @section 來設定填滿 app.blade.php
提供的 HTML 內容。
@yield 與 @section
@yield
和 @section
定義了 View 的內容,使用@yield('title')
對應到了 @section('title')
,靠的是彼此第一個參數 'title'
的聯繫,而第二個參數(這裡傳入'Page Title'
) 會被傳到 @yield('title')
設定的位置,也就是變成
<title>App Name - Page Title <title>
@section 與 @show
如 @section
字面含義,@section
表示一個段落,@show
表示執行到此時,將該 @section
中的內容顯示到頁面上,我們也可以重新覆蓋這個段落內容。
@section 與 @endsection
若使用 @section
要再加上其他的 HTML code 或 Blade 語法,亦可以在@section
後面加上 @endsection
,將我們要的內容置於其中。
@section 與 @parent
當我們用 @extends
繼承了某個 Layout View,並在 @section
、@endsection
定義了其他段落,預設會將 @extends
同區塊內容覆蓋掉,這時可以加入 @parent
同時呈現原本繼承而來的內容。
顯示數據
使用 {{ }} 顯示資料
Blade 數據顯示常見形式是使用 Mustache 語法(雙大括號) {{ }}
來顯示資料,若前端有寫過 Vue,看到 {{ }}
應該會倍感親切。例如現在有個變數 $name
,要將其顯示只要這樣:
<h1>{{ $name }}</h1>
和其他文字放一起也沒問題
<h1>Hello,{{ $name }} </h1>
{{ }}
不僅能在 HTML tag 內顯示資料,也可以置入 tag 的 attribute 來達到替換屬性,
例如若打開 Laravel 專案預設的 welcome.blade.php
,可以看到 a 標籤的 href 如下:
<a href="{{ url('/home') }}">Home</a>
顯示流程
@if 、 @elseif 與 @else
@if (count($records) === 1)
I have one records
@elseif (count($records) > 1)
I have more records
@else
I don't have any records
@endif
同樣的 code ,原生 PHP 則是會這樣寫:
<?php if(count($records) === 1): ?>
I have one records
<?php elseif(count($records) === 1): ?>
I have more records
<?php else: ?>
I don't have any records
<?php endif; ?>
所以 Blade 只是簡化了語法的部分,讓我們更好撰寫對畫面的顯示邏輯。
條列式渲染資料
面對多筆資料的條列式渲染,React 一般會使用 JavaScript .map()
、 Vue 一般使用 v-for
,那對於在 Server-side 的 Blade 呢?
@for 與 @endfor
相較於用 PHP 原生 for
迴圈的條列式渲染(迭代), Blade 幫我們簡化了語法,使用 @for
可以做到一樣的事情。
@for ($i = 0; $i < 10; $i++)
The current value is {{ $i }}
@endfor
@foreach
比起用 for
去跑,也可以使用 foreach
來條列渲染,使用 @foreach
和 @endforeach
即可,同樣也是開頭加上 @
符號就好。
@foreach ($users as $user)
<p>This is user {{ $user->id }}</p>
@endforeach
@forelse
初次看到 @forelse
,還要想一下 PHP 或 JS 有沒有類似 forelse
這個語法。
事實上 @forelse
是 Laravel Blade 包過的語法,當我們在使用 @for
、@foreach
迭代時,可能還會搭配 @if
、@else
去做到顯示邏輯的劃分:有資料(成立)時顯示什麼?沒有資料(不成立)顯示什麼?
例如:
@if ($users->count())
@foreach ($users as $user)
<li>{{ $user->name }}</li>
@endforeach
@else
<p>No users</p>
@endif
改用 @forelse
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>No users</p>
@endforelse
有資料顯示 <li>{{ $user->name }}</li>
,沒有就給個<p>
tag 和 No users 的文字,這樣語法就清晰許多了。
其他
註解
Blade 內當然也可以使用註解,並且這個註解不會在 Web client 端顯示出來:
{{-- 這是註解這是註解這是註解這是註解這是註解 --}}
auth 身份驗證
@auth
<p>已登入</p>
@endauth
@guest
<p>尚未登入</p>
@endguest
現在什麼時候會用到 Blade?
現代前端在前後端專案分離架構下,使用 Server-side Template Engine 機會降低不少,即便前後端專案沒分離多半也是在 Template Engine 上插入 React 或 Vue 的 Component,其他 View 邏輯一樣是用前端 Root Component 接著在這個元件內import
、export
元件寫來寫去其他的 Component。
但不可否認,若今天是一個小型的專案,直接從後端開始寫,使用 Blade 來處理前端也不會比較慢或差,前端也不必搞 SSR,因為就已經是 Server-side 的技術了,在 View 層去接資料,前端也不用等載入頁面後才 AJAX 資料一次。