PHP laravel系列之Blade模版
一、什麼是Blade模版?
Blade 是 Laravel 提供的一個既簡單又強大的模板引擎。
和其他流行的 PHP 模板引擎不一樣,Blade 並不限制你在檢視中使用原生 PHP 程式碼。所有 Blade 檢視檔案都將被編譯成原生的 PHP 程式碼並快取起來,除非它被修改,否則不會重新編譯,這就意味著 Blade 基本上不會給你的應用增加任何額外負擔。
Blade 檢視檔案使用 .blade.php 副檔名,一般被存放在 resources/views 目錄。
像之前實驗中的 welcome.blade.php 和 home.blade.php 等都是 blade 模板檔案,只是我們之前還沒有用到模板的功能,在本次實驗我們將體驗強大的 blade 模板功能。
二、模板繼承
模板繼承是最常用的一個 blade 模板功能。
平時訪問網站的時候,可以發現,一般一個網站的不同頁面都應該是類似的,比如都有相同的導航欄和底部資訊欄,或者都有相同的左側選單欄。
我們在寫程式碼的時候不可能每個頁面都要把重複的東西寫一遍,這樣不僅效率低下,還不易維護,所以就有了模板繼承。
下面我們通過一個很簡單的例子來使用模板繼承。
首先,建立相關路由:
app/Http/routes.php
<?php
//home page
Route::get('/', '[email protected]')->name('home');
//about page
Route ::get('/about', '[email protected]')->name('about');
然後,使用 artisan 建立控制器:
cd ~/Code/myweb
php artisan make:controller StaticPagesController --plain
開啟控制器,建立相應方法:
app/Http/Controllers/StaticPagesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App \Http\Requests;
use App\Http\Controllers\Controller;
class StaticPagesController extends Controller
{
public function home()
{
return view('home');
}
public function about()
{
return view('about');
}
}
然後,在 resources/views 目錄下建立對應的檢視檔案 home.blade.php
和about.blade.php
開啟這兩個檢視檔案,分別輸入以下程式碼:
resources/views/home.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>Home</h1>
<p>Welcome to My web</p>
</body>
</html>
resources/views/about.blade.php
<!DOCTYPE html>
<html>
<head>
<title>About</title>
</head>
<body>
<h1>About</h1>
<p>This is my first Laravel web</p>
<p>Author: SadCreeper</p>
<!-- 可以更改為你自己的資訊 -->
</body>
</html>
然後,開啟瀏覽器,輸入 localhost 和 localhost/about 可以看到我們建立的兩個檢視。
但是到現在為止,我們還沒有使用 blade 模板繼承,可以看到兩個檢視中有很多的重複程式碼,下面建立一個基礎檢視,其他的所有檢視都將繼承這個基礎檢視。
在 resources/views 目錄下新建一個目錄 layouts 然後在 resources/views/layouts 目錄下新建一個檢視檔案 app.blade.php。
開啟這個 app.blade.php 加入如下程式碼:
resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Myweb</title>
</head>
<body>
@yield('content')
</body>
</html>
然後修改 home.blade.php 和 about.blade.php:
resources/views/home.blade.php
@extends('layouts.app')
@section('content')
<h1>Home</h1>
<p>Welcome to My web</p>
@endsection
resources/views/about.blade.php
@extends('layouts.app')
@section('content')
<h1>About</h1>
<p>This is my first Laravel web</p>
<p>Author: SadCreeper</p>
<!-- 可以更改為你自己的資訊 -->
@endsection
其中頂部程式碼:
@extends('layouts.app')
就是表示當前檢視繼承自 layouts 資料夾下的 app.blade.php 檢視。
然後用下面這種方式就可以把 section(‘content’) 中包含的內容放到被繼承的檢視 app.blade.php 中的 yield(‘content’) 部分。
@section('content')
//
@endsection
使用模板繼承後,你如果想對網站進行一些基礎的公用程式碼的修改時,就可以修改 app.blade.php。
下面我們給這個基礎檢視新增一個非常簡單的頂部導航欄和底部資訊欄。
resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Myweb</title>
</head>
<body style="margin:0;padding:0;">
<!-- header -->
<div style="padding:10px 50px 10px 50px;border-bottom: 1px solid #eeeeee;">
<div style="display:inline-block;">
<a href="{{ route('home') }}"><h2>Myweb</h2></a>
</div>
<div style="display:inline-block;margin-left:20px;">
<a href="{{ route('about') }}">about</a>
</div>
</div>
<div style="text-align:center;">
@yield('content')
</div>
<!-- footer -->
<div style="padding:10px 50px 10px 50px;background-color:gray;">
<p>contact me : 1234567</p>
</div>
</body>
</html>
在本教程中,我把樣式寫到了 style 裡,是為了簡化流程,通常來說,樣式程式碼應該儘量寫到 css 檔案中,以方便複用和維護。
此時我們訪問localhost 和 localhost/about 都可以看到完整的包含導航欄和底部資訊欄的檢視。
二、引入子檢視
你可以使用 Blade 的 @include 命令來引入一個已存在的檢視,所有在父檢視的可用變數在被引入的檢視中都是可用的。
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
儘管被引入的檢視會繼承父檢視中的所有資料,你也可以通過傳遞額外的陣列資料至被引入的頁面:
@include('view.name', ['some' => 'data'])
下面我們建立一個子檢視,用來顯示網站作者資訊,你可以在網站上任何想顯示作者資訊的地方引用這個檢視。
在 resources/views 目錄下新建一個資料夾 shared 然後在 resources/views/shared 目錄下新建一個檔案 author.blade.php 開啟該檔案。
resources/views/shared/author.blade.php
<div style="width:200px;margin:20px auto 20px auto;padding:20px;border:1px solid black;">
<h3>Author</h3>
<p>name : SadCreeper</p>
<p>age : 22</p>
<p>Tel : 150-XXXX-XXXX</p>
</div>
然後在 resources/views/about.blade.php 中引用該子檢視:
resources/views/about.blade.php
@extends('layouts.app')
@section('content')
<h1>About</h1>
<p>This is my first Laravel web</p>
@include('shared.author')
@endsection
然後訪問localhost/about 看下效果:
此時如果你想在任何地方顯示這個子檢視,只需要在相應位置加入下面一行程式碼即可~
@include('shared.author')
三、資料顯示
你可以使用 「中括號」 包住變數以顯示傳遞至 Blade 檢視的資料。如假設你有下面這樣一個路由:
Route::get('greeting', function () {
return view('welcome', ['name' => 'Samantha']);
});
你在檢視檔案中可以像這樣顯示 name 變數的內容:
Hello, {{ $name }}.
你也可以顯示 PHP 函式的結果。事實上,你可以在 Blade 中顯示任意的 PHP 程式碼:
The current UNIX timestamp is {{ time() }}.
有時候你可能想要輸出一個變數,但是你並不確定這個變數是否已經被定義,我們可以這樣:
{{ $name or 'Default' }}
在這個例子中,如果 $name 變數存在,它的值將被顯示出來。但是,如果它不存在,則會顯示 Default 。
在預設情況下,Blade 模板中的 {{ }} 表示式將會自動呼叫 PHP htmlentities 函式來轉義資料以避免 XSS 的攻擊。如果你不想你的資料被轉義,你可以使用下面的語法:
Hello, {!! $name !!}.
四、控制輸出
除了“模板繼承” 與 “資料顯示”的功能以外,Blade 也給一般的 PHP 結構控制語句提供了方便的縮寫,比如條件表示式和迴圈語句。這些縮寫提供了更為清晰簡明的方式來使用 PHP 的控制結構,而且還保持與 PHP 語句的相似性。
1.IF
你可以通過 @if , @elseif , @else 及 @endif 指令構建 if 表示式,這些命令的功能等同於在 PHP 中的語法:
@if (count($records) === 1)
我有一條記錄!
@elseif (count($records) > 1)
我有多條記錄!
@else
我沒有任何記錄!
@endif
為了方便,Blade 也提供了一個 @unless 命令:
@unless (Auth::check())
你尚未登入。
@endunless
2.迴圈
@for ($i = 0; $i < 10; $i++)
目前的值為 {{ $i }}
@endfor
@foreach ($users as $user)
<p>此使用者為 {{ $user->id }}</p>
@endforeach
@forelse ($users as $user)
<li>{{ $user->name }}</li>
@empty
<p>沒有使用者</p>
@endforelse
@while (true)
<p>我永遠都在跑迴圈。</p>
@endwhile
當使用迴圈時,你可能也需要一些結束迴圈或者跳出當前迴圈的命令:
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
<li>{{ $user->name }}</li>
@if ($user->number == 5)
@break
@endif
@endforeach
或者也可以簡寫:
@foreach ($users as $user)
@continue($user->type == 1)
<li>{{ $user->name }}</li>
@break($user->number == 5)
@endforeach
當迴圈進行時,你可以使用 迴圈變數 $loop 來獲取迴圈中有價值的資訊,比如當前迴圈的索引,當前迴圈是不是首次迭代,又或者當前迴圈是不是最後一次迭代。
@foreach ($users as $user)
@if ($loop->first)
This is the first iteration.
@endif
@if ($loop->last)
This is the last iteration.
@endif
<p>This is user {{ $user->id }}</p>
@endforeach
如果你是在一個巢狀的迴圈中,你可以通過使用
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is first iteration of the parent loop.
@endif
@endforeach
@endforeach
$loop 變數也包含了其它各種有用的屬性:
屬性 | 描述 |
---|---|
$loop->index | 當前迴圈所迭代的索引,起始為 0。 |
$loop->iteration | 當前迭代數,起始為 1。 |
$loop->remaining | 迴圈中迭代剩餘的數量。 |
$loop->count | 被迭代項的總數量。 |
$loop->first | 當前迭代是否是迴圈中的首次迭代。 |
$loop->last | 當前迭代是否是迴圈中的最後一次迭代。 |
$loop->depth | 當前迴圈的巢狀深度。 |
loop->parent | 當在巢狀的迴圈內時,可以訪問到父迴圈中的 $loop變數。 |
五、註釋
Blade 也允許在頁面中定義註釋,然而,跟 HTML 的註釋不同的是,Blade 註釋不會被包含在應用程式返回的 HTML 內:
{{-- 此註釋將不會出現在渲染後的 HTML --}}
六、包含子檢視
Blade的@include指令允許你很簡單的在一個檢視中包含另一個Blade檢視,所有父級檢視中變數在被包含的子檢視中依然有效:
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
儘管被包含的檢視繼承所有父檢視中的資料,你還可以傳遞額外引數到被包含的檢視:
@include('view.name', ['some' => 'data'])
七、服務注入
@inject指令可以用於從服務容器中獲取服務,傳遞給@inject的第一個引數是服務將要被放置到的變數名,第二個引數是要解析的服務類名或介面名:
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
6、擴充套件Blade
Blade甚至還允許你自定義指令,可以使用directive方法來註冊一個指令。當Blade編譯器遇到該指令,將會傳入引數並呼叫提供的回撥。
下面的例子建立了一個@datetime($var)指令:
<?php
namespace App\Providers;
use Blade;use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function($expression) {
return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});
}
/**
* 在容器中註冊繫結.
*
* @return void
*/
public function register()
{
//
}
}
正如你所看到的,Laravel的幫助函式with被用在該指令中,with方法簡單返回給定的物件/值,允許方法鏈。最終該指令生成的PHP程式碼如下:
<?php echo with($var)->format('m/d/Y H:i'); ?>
八、小結
用於封裝和繼承用的,還是比較實用的!!!