鍍金池/ 教程/ PHP/ Blade 模板引擎
門面
Laravel Homestead
安裝及配置
測試
HTTP 中間件
加密
升級指南
幫助函數(shù)
應用目錄結(jié)構(gòu)
集合
新手入門指南-簡單任務管理系統(tǒng)
任務調(diào)度
查詢構(gòu)建器
視圖
驗證
Laravel Cashier(訂購&支付&發(fā)票)
本地化
隊列
調(diào)整器
分頁
文件系統(tǒng)/云存儲
貢獻代碼
哈希
HTTP 控制器
緩存
遷移
HTTP 請求
Laravel Elixir
發(fā)行版本說明
Envoy 任務運行器(SSH任務)
序列化
Session
起步
帶用戶功能的任務管理系統(tǒng)
起步
用戶授權(quán)
郵件
事件
填充數(shù)據(jù)
HTTP 路由
服務提供者
Blade 模板引擎
包開發(fā)
用戶認證
Artisan 控制臺
HTTP 響應
集合
服務容器
關聯(lián)關系
一次請求的生命周期
契約
Redis
錯誤&日志

Blade 模板引擎

1、簡介

Blade 是 Laravel 提供的一個非常簡單、強大的模板引擎,不同于其他流行的 PHP 模板引擎,Blade 在視圖中并不約束你使用 PHP 原生代碼。所有的 Blade 視圖都會被編譯成原生 PHP 代碼并緩存起來直到被修改,這意味著對應用的性能而言 Blade 基本上是零開銷。Blade 視圖文件使用.blade.php文件擴展并存放在 resources/views 目錄下。

2、模板繼承

2.1 定義布局

使用 Blade 的兩個最大優(yōu)點是模板繼承和切片,開始之前讓我們先看一個例子。首先,我們檢測一個“主”頁面布局,由于大多數(shù) web 應用在不同頁面中使用同一個布局,可以很方便的將這個布局定義為一個單獨的 Blade 頁面:

<!-- 存放在 resources/views/layouts/master.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>

正如你所看到的,該文件包含典型的 HTML 標記,然而,注意@section@yield 指令,前者正如其名字所暗示的,定義了一個內(nèi)容的片段,而后者用于顯示給定片段的內(nèi)容。 現(xiàn)在我們已經(jīng)為應用定義了一個布局,接下來讓我們定義繼承該布局的子頁面吧。

2.2 擴展布局

定義子頁面的時候,可以使用 Blade 的@extends 指令來指定子頁面所繼承的布局,繼承一個 Blade 布局的視圖將會使用@section 指令注入內(nèi)容到布局的片段中,記住,如上面例子所示,這些片段的內(nèi)容將會顯示在布局中使用@yield 的地方:

<!-- 存放在 resources/views/layouts/child.blade.php -->

@extends('layouts.master')

@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

在本例中,sidebar 片段使用@parent 指令來追加(而非覆蓋)內(nèi)容到布局中 sidebar,@parent 指令在視圖渲染時將會被布局中的內(nèi)容替換。

當然,和原生 PHP 視圖一樣,Blade 視圖可以通過view方法直接從路由中返回:

Route::get('blade', function () {
    return view('child');
});

3、數(shù)據(jù)顯示

可以通過兩個花括號包裹變量來顯示傳遞到視圖的數(shù)據(jù),比如,如果給出如下路由:

Route::get('greeting', function () {
    return view('welcome', ['name' => 'Samantha']);
});

那么可以通過如下方式顯示 name 變量的內(nèi)容:

Hello, {{ $name }}.

當然,不限制顯示到視圖中的變量內(nèi)容,你還可以輸出任何 PHP 函數(shù),實際上,可以將任何 PHP 代碼放到 Blade 模板語句中:

The current UNIX timestamp is {{ time() }}.

注意:Blade 的{{}}語句已經(jīng)經(jīng)過 PHP 的 htmlentities 函數(shù)處理以避免 XSS 攻擊。

Blade & JavaScript 框架 由于很多 JavaScript 框架也是用花括號來表示要顯示在瀏覽器中的表達式,可以使用@符號來告訴 Blade 渲染引擎該表達式應該保持原生格式不作改動。比如:

<h1>Laravel</h1>

Hello, @{{ name }}.

在本例中,@符將會被 Blade 移除,然而,{{ name }}表達式將會保持不變,避免被 JavaScript 框架渲染。

輸出存在的數(shù)據(jù) 有時候你想要輸出一個變量,但是不確定該變量是否被設置,我們可以通過如下 PHP 代碼:

{{ isset($name) ? $name : 'Default' }}

除了使用三元運算符,Blade 還提供了更簡單的方式:

{{ $name or 'Default' }}

在本例中,如果$name 變量存在,其值將會顯示,否則將會顯示“Default”。

顯示原生數(shù)據(jù) 默認情況下,Blade 的{{ }}語句已經(jīng)通過 PHP 的 htmlentities 函數(shù)處理以避免 XSS 攻擊,如果你不想要數(shù)據(jù)被處理,可以使用如下語法:

Hello, {!! $name !!}.

注意:輸出用戶提供的內(nèi)容時要當心,對用戶提供的內(nèi)容總是要使用雙花括號包裹以避免直接輸出 HTML 代碼。

4、流程控制

除了模板繼承和數(shù)據(jù)顯示之外,Blade 還為常用的 PHP 流程控制提供了便利操作,比如條件語句和循環(huán),這些快捷操作提供了一個干凈、簡單的方式來處理 PHP 的流程控制,同時保持和 PHP 相應語句的相似。

4.1 If 語句

可以使用@if, @elseif, @else, 和 @endif 來構(gòu)造 if 語句,這些指令函數(shù)和 PHP 的相同:

@if (count($records) === 1)
    I have one record!
@elseif (count($records) > 1)
    I have multiple records!
@else
    I don't have any records!
@endif

為方便起見,Blade 還提供了@unless 指令:

@unless (Auth::check())
    You are not signed in.
@endunless

4.2 循環(huán)

除了條件語句,Blade 還提供了簡單指令處理 PHP 支持的循環(huán)結(jié)構(gòu),同樣,這些指令函數(shù)和 PHP 的一樣:

@for ($i = 0; $i < 10; $i++)
    The current value is {{ $i }}
@endfor

@foreach ($users as $user)
    <p>This is user {{ $user->id }}</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>No users</p>
@endforelse

@while (true)
    <p>I'm looping forever.</p>
@endwhile

4.3 包含子視圖

Blade 的@include 指令允許你很簡單的在一個視圖中包含另一個 Blade 視圖,所有父級視圖中變量在被包含的子視圖中依然有效:

<div>
    @include('shared.errors')

    <form>
        <!-- Form Contents -->
    </form>
</div>

盡管被包含的視圖繼承所有父視圖中的數(shù)據(jù),你還可以傳遞額外參數(shù)到被包含的視圖:

@include('view.name', ['some' => 'data'])

4.4 注釋

Blade 還允許你在視圖中定義注釋,然而,不同于 HTML 注釋,Blade 注釋并不會包含到 HTML 中被返回:

{{-- This comment will not be present in the rendered HTML --}}

5、服務注入

@inject 指令可以用于從服務容器中獲取服務,傳遞給@inject 的第一個參數(shù)是服務將要被放置到的變量名,第二個參數(shù)是要解析的服務類名或接口名:

@inject('metrics', 'App\Services\MetricsService')

<div>
    Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>

6、擴展 Blade

Blade 甚至還允許你自定義指令,可以使用 directive 方法來注冊一個指令。當 Blade 編譯器遇到該指令,將會傳入?yún)?shù)并調(diào)用提供的回調(diào)。 下面的例子創(chuàng)建了一個@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 的幫助函數(shù) with 被用在該指令中,with方法簡單返回給定的對象/值,允許方法鏈。最終該指令生成的 PHP 代碼如下:

<?php echo with($var)->format('m/d/Y H:i'); ?>
上一篇:用戶授權(quán)下一篇:測試