Blade 是 Laravel 提供的一個既簡單又強大的模板引擎。php
和其餘流行的 PHP 模板引擎不同,Blade 並不限制你在視圖中使用原生 PHP 代碼。全部 Blade 視圖文件都將被編譯成原生的 PHP 代碼並緩存起來,除非它被修改,不然不會從新編譯,這就意味着 Blade 基本上不會給你的應用增長任何額外負擔。css
Blade 視圖文件使用 .blade.php 擴展名,通常被存放在 resources/views 目錄。html
像以前實驗中的 welcome.blade.php 和 home.blade.php 等都是 blade 模板文件,只是咱們以前尚未用到模板的功能,在本次實驗咱們將體驗強大的 blade 模板功能。java
2、模板繼承web
模板繼承是最經常使用的一個 blade 模板功能。express
平時訪問網站的時候,能夠發現,通常一個網站的不一樣頁面都應該是相似的,好比都有相同的導航欄和底部信息欄,或者都有相同的左側菜單欄。數組
咱們在寫代碼的時候不可能每一個頁面都要把重複的東西寫一遍,這樣不只效率低下,還不易維護,因此就有了模板繼承。瀏覽器
下面咱們經過一個很簡單的例子來使用模板繼承。緩存
首先,建立相關路由: app/Http/routes.php
ruby
<?php
//home page Route::get('/', 'StaticPagesController@home')->name('home'); //about page Route::get('/about', 'StaticPagesController@about')->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;"> <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 語句的類似性。
你能夠經過 @if , @elseif , @else 及 @endif 指令構建 if 表達式,這些命令的功能等同於在 PHP 中的語法:
@if (count($records) === 1) 我有一條記錄! @elseif (count($records) > 1) 我有多條記錄! @else 我沒有任何記錄! @endif
爲了方便,Blade 也提供了一個 @unless 命令:
@unless (Auth::check())
你還沒有登陸。
@endunless
@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
若是你是在一個嵌套的循環中,你能夠經過使用 loop變量的parent屬性來獲取父循環中的loop變量的parent屬性來獲取父循環中的loop 變量:
@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>
六、擴展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'); ?>
用於封裝和繼承用的,仍是比較實用的!!!