基礎(chǔ) ―― Blade模板

2018-02-24 15:38 更新

基礎(chǔ) —— Blade 模板引擎

1、簡(jiǎn)介

Blade中并不約束你使用PHP原生代碼。所有的Blade視圖都會(huì)被編譯成原生PHP代碼并緩存起來(lái)直到被修改,這意味著對(duì)應(yīng)用的性能而言Blade基本上是零開(kāi)銷(xiāo)。Blade視圖文件使用.blade.php文件擴(kuò)展并存放在resources/views目錄下。

2、模板繼承

2.1 定義布局

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

<!-- 存放在 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標(biāo)記,然而,注意@section@yield指令,前者正如其名字所暗示的,定義了一個(gè)內(nèi)容的片段,而后者用于顯示給定片段的內(nèi)容。

現(xiàn)在我們已經(jīng)為應(yīng)用定義了一個(gè)布局,接下來(lái)讓我們定義繼承該布局的子頁(yè)面吧。

2.2 擴(kuò)展布局

定義子頁(yè)面的時(shí)候,可以使用Blade的@extends指令來(lái)指定子頁(yè)面所繼承的布局,繼承一個(gè)Blade布局的視圖將會(huì)使用@section指令注入內(nèi)容到布局的片段中,記住,如上面例子所示,這些片段的內(nèi)容將會(huì)顯示在布局中使用@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指令來(lái)追加(而非覆蓋)內(nèi)容到布局中sidebar,@parent指令在視圖渲染時(shí)將會(huì)被布局中的內(nèi)容替換。

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

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

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

可以通過(guò)兩個(gè)花括號(hào)包裹變量來(lái)顯示傳遞到視圖的數(shù)據(jù),比如,如果給出如下路由:

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

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

Hello, {{ $name }}.

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

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

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

Blade & JavaScript框架

由于很多JavaScript框架也是用花括號(hào)來(lái)表示要顯示在瀏覽器中的表達(dá)式,可以使用@符號(hào)來(lái)告訴Blade渲染引擎該表達(dá)式應(yīng)該保持原生格式不作改動(dòng)。比如:

<h1>Laravel</h1>

Hello, @{{ name }}.

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

輸出存在的數(shù)據(jù)

有時(shí)候你想要輸出一個(gè)變量,但是不確定該變量是否被設(shè)置,我們可以通過(guò)如下PHP代碼:

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

除了使用三元運(yùn)算符,Blade還提供了更簡(jiǎn)單的方式:

{{ $name or 'Default' }}

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

顯示原生數(shù)據(jù)

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

Hello, {!! $name !!}.

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

4、流程控制

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

4.1 If語(yǔ)句

可以使用@if,?@elseif,?@else, 和?@endif來(lái)構(gòu)造if語(yǔ)句,這些指令函數(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

為方便起見(jiàn),Blade還提供了@unless指令:

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

4.2 循環(huán)

除了條件語(yǔ)句,Blade還提供了簡(jiǎn)單指令處理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指令允許你很簡(jiǎn)單的在一個(gè)視圖中包含另一個(gè)Blade視圖,所有父級(jí)視圖中變量在被包含的子視圖中依然有效:

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

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

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

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

4.4?注釋

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

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

5、服務(wù)注入

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

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

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

6、擴(kuò)展Blade

Blade甚至還允許你自定義指令,可以使用directive方法來(lái)注冊(cè)一個(gè)指令。當(dāng)Blade編譯器遇到該指令,將會(huì)傳入?yún)?shù)并調(diào)用提供的回調(diào)。

下面的例子創(chuàng)建了一個(gè)@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'); ?>";
        });
    }

    /**
     * 在容器中注冊(cè)綁定.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

正如你所看到的,Laravel的幫助函數(shù)with被用在該指令中,with方法簡(jiǎn)單返回給定的對(duì)象/值,允許方法鏈。最終該指令生成的PHP代碼如下:

<?php echo with($var)->format('m/d/Y H:i'); ?>
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)