国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Laravel 5.8 ??? ?? ??? / Blade 模板

Blade 模板

Blade 模板


Blade 模板

簡(jiǎn)介

Blade 是 Laravel 提供的一個(gè)簡(jiǎn)單而又強(qiáng)大的模板引擎。和其他流行的 PHP 模板引擎不同,Blade 并不限制你在視圖中使用原生 PHP 代碼。所有 Blade 視圖文件都將被編譯成原生的 PHP 代碼并緩存起來,除非它被修改,否則不會(huì)重新編譯,這就意味著 Blade 基本上不會(huì)給你的應(yīng)用增加任何負(fù)擔(dān)。Blade 視圖文件使用 .blade.php 作為文件擴(kuò)展名,被存放在 resources/views 目錄。

模板繼承

定義布局

Blade 的兩個(gè)主要優(yōu)點(diǎn)是模板繼承區(qū)塊。為方便入門,讓我們先通過一個(gè)簡(jiǎn)單的例子來上手。首先,我們來研究一個(gè)「主」頁面布局。因?yàn)榇蠖鄶?shù) web 應(yīng)用會(huì)在不同的頁面中使用相同的布局方式,因此可以很方便地定義單個(gè) Blade 布局視圖:

<!-- 保存在  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>

如你所見,該文件包含了典型的 HTML 語法。不過,請(qǐng)注意 @section@yield 指令。 @section 指令定義了視圖的一部分內(nèi)容,而 @yield 指令是用來顯示指定部分的內(nèi)容。

現(xiàn)在,我們已經(jīng)定義好了這個(gè)應(yīng)用程序的布局,接下來,我們定義一個(gè)繼承此布局的子頁面。

擴(kuò)展布局

在定義一個(gè)子視圖時(shí),使用 Blade 的 @extends 指令指定子視圖要「繼承」的視圖。擴(kuò)展自 Blade 布局的視圖可以使用 @section 指令向布局片段注入內(nèi)容。就如前面的示例中所示,這些片段的內(nèi)容將由布局中的顯示在布局中 @yield 指令控制顯示:

<!-- 保存在 resources/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

在這個(gè)示例中, sidebar 片段利用 @parent 指令向布局的 sidebar 追加(而非覆蓋)內(nèi)容。 在渲染視圖時(shí),@parent 指令將被布局中的內(nèi)容替換。

{tip} 和上一個(gè)示例相反,這里的  sidebar 片段使用  @endsection 代替 @show 來結(jié)尾。 @endsection 指令僅定義了一個(gè)片段, @show 則在定義的同時(shí) 立即 yield 這個(gè)片段。

Blade 視圖可以使用全局  view 助手自路由中返回:

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

組件 & 插槽

組件和插槽提供了與片段和布局類似的好處;不過組件和插槽的思維模型更易于理解。我們先來看一個(gè)可復(fù)用的「alert」組件,我們想在應(yīng)用中復(fù)用它:

<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">   
 {{ $slot }}
</div>

{{ $slot }} 變量將包含我們想要注入到組件的內(nèi)容?,F(xiàn)在,我們使用 Blade 的 @component  指令構(gòu)建這個(gè)組件:

@component('alert') 
<strong>Whoops!</strong> Something went wrong!
@endcomponent

有時(shí)候?yàn)橐粋€(gè)組件定義多個(gè)插槽是很有用的。修改 alert 組件以允許其注入 「title」。命名插槽可以通過與其匹配的 「回顯」 變量顯示:

<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">  
  <div class="alert-title">{{ $title }}</div>    
  {{ $slot }}
 </div>

現(xiàn)在,我們能夠使用 @slot 指令向命名插槽注入內(nèi)容。不在  @slot 指令內(nèi)的內(nèi)容都將傳遞給組件中的  $slot 變量:

@component('alert')
    @slot('title')
        Forbidden
    @endslot
You are not allowed to access this resource!@endcomponent

向組件傳遞額外的數(shù)據(jù)

有時(shí)你可能需要向組件傳遞額外的數(shù)據(jù)。在這種情況下,可以把包含數(shù)據(jù)組織成數(shù)組,作為 @component 指令的第二個(gè)參數(shù)。所有的數(shù)據(jù)將作為變更提供給組件模板:

@component('alert', ['foo' => 'bar'])  
  ...
@endcomponent

給組件起別名

如果組件存儲(chǔ)在子目錄中,你可能希望給它們起個(gè)別名以方便訪問。舉例來說,如果一個(gè) Blade 組件存儲(chǔ)在 resources/views/components/alert.blade.php 中,. 就可以使用 component 方法將 components.alert 的別名命名為 alert。. 通常情況下,這一過程將在 AppServiceProvider 的  boot 方法中完成:

use Illuminate\Support\Facades\Blade;
Blade::component('components.alert', 'alert');

一旦組件有了別名,就可以使用一條指令渲染它:

@alert(['type' => 'danger'])
    You are not allowed to access this resource!@endalert

如果沒有額外的插槽,還可以省略組件參數(shù):

@alert
    You are not allowed to access this resource!@endalert

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

可以通過包裹在雙花括號(hào)內(nèi)的變量顯示傳遞給 Blade 視圖的數(shù)據(jù)。比如給出如下路由:

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

就可以這樣利用 name 變量顯示其內(nèi)容:

Hello, {{ $name }}.

{tip} Blade {{ }} 語句是自動(dòng)經(jīng)過  PHP 的 htmlspecialchars 函數(shù)傳遞來防范  XSS 攻擊的。

不限于顯示傳遞給視圖的變量的內(nèi)容,你還可以顯示任一 PHP 函數(shù)的結(jié)果。實(shí)際上,你可以在 Blade 的回顯語句中放置你想要的任意 PHP 代碼:

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

顯示非轉(zhuǎn)義字符

默認(rèn)情況下, Blade 中 {{ }} 語句自動(dòng)經(jīng)由 PHP 的 htmlspecialchars 函數(shù)傳遞以防范 XSS 攻擊。如果不希望數(shù)據(jù)被轉(zhuǎn)義,可以使用下面的語法:

Hello, {!! $name !!}.

{note} 在回顯應(yīng)用的用戶提供的內(nèi)容時(shí)需要謹(jǐn)慎小心。在顯示用戶提供的數(shù)據(jù)時(shí),有必要一直使用雙花括號(hào)語法轉(zhuǎn)義來防范 XSS 攻擊。

渲染 JSON

有時(shí),為了初始化一個(gè) JavaScript 變量,你可能會(huì)向視圖傳遞一個(gè)數(shù)據(jù),并將其渲染成 JSON:

<script>  
  var app = <?php echo json_encode($array); ?>;
</script>

不過,你可以使用 @json Blade 指令代替手動(dòng)調(diào)用 json_encode 函數(shù):

<script> 
   var app = @json($array);
</script>

HTML 實(shí)體編碼

默認(rèn)情況下,Blade (以及 Laravel 的 e 助手)將對(duì) HTML 實(shí)體雙重編碼。如果要禁用雙重編碼,可以在 AppServiceProviderboot 中調(diào)用 Blade::withoutDoubleEncoding 方法:

<?php
   namespace App\Providers;
   use Illuminate\Support\Facades\Blade;
   use Illuminate\Support\ServiceProvider;
   class AppServiceProvider extends ServiceProvider{   
    /**
     * 引導(dǎo)任意應(yīng)用服務(wù)。
     *
     * @return void
     */  
   public function boot()   
    {       
     Blade::withoutDoubleEncoding();   
     }
  }

Blade & JavaScript 框架

由于很多 JavaScript 框架也使用花括號(hào)表明給定的表達(dá)式將要在瀏覽器中顯示, 可以使用 @ 符號(hào)通知 Blade 渲染引擎某個(gè)表達(dá)式應(yīng)保持不變。示例如下:

<h1>Laravel</h1>Hello, @{{ name }}.

在這個(gè)例子中, @ 符號(hào)將被 Blade 刪除;在 Blade 引擎中 {{ name }} 表達(dá)式將保持不變,取而代之的是 JavaScript 引擎將渲染該表達(dá)式。

@verbatim 指令

如果要在大段的模板中 JavaScript 變量,可以將 HTML 包裹在 @verbatim 指令中,這樣就不需要為每個(gè) Blade 回顯語句添加 @ 符號(hào):

@verbatim   
 <div class="container">
        Hello, {{ name }}.  
  </div>@endverbatim

控制結(jié)構(gòu)

除了模板繼承和數(shù)據(jù)顯示, Blade 還為分支和循環(huán)等 PHP 控制結(jié)構(gòu)提供了方便的快捷方式。這些快捷方式提供了干凈、簡(jiǎn)捷地處理 PHP 控制結(jié)構(gòu)的方法,同時(shí)保持了與 PHP 中的對(duì)應(yīng)結(jié)構(gòu)的相似性。

If 語句

可以使用 @if@elseif、 @else@endif 指令構(gòu)造 if 語句。這些指令的功能與相應(yīng)的 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

除了已經(jīng)討論過的條件指令, @isset@empty 指令可以作為各自對(duì)應(yīng)的 PHP 函數(shù)的快捷方式:

@isset($records) 
   // $records 被定義且不是 null...
@endisset

@empty($records)   
 // $records 為空...
@endempty

身份驗(yàn)證指令

@auth@guest 指令能夠用于快速確定當(dāng)前用戶是經(jīng)過身份驗(yàn)證的,還是一個(gè)訪客:

@auth    // 此用戶身份已驗(yàn)證...@endauth
@guest    // 此用戶身份未驗(yàn)證...@endguest

如果需要,可以在使用 @auth@guest 指令時(shí)指定應(yīng)被校驗(yàn)的 身份 :

@auth('admin')    // 此用戶身份已驗(yàn)證...@endauth
@guest('admin')    // 此用戶身份未驗(yàn)證...@endguest

片段指令

可以使用 @hasSection 指令檢查片斷是否存在內(nèi)容:

@hasSection('navigation')
   <div class="pull-right">
 @yield('navigation')   
    </div>  
    <div class="clearfix">
    </div>
 @endif

Switch 指令

可以使用  @switch、 @case、 @break、 @default@endswitch 指令構(gòu)造 switch 語句:

@switch($i)
    @case(1)
        First case...
        @break
    @case(2)
        Second case...
        @break
    @default   
        Default case...@endswitch

循環(huán)

除了分支語句,Blade 還提供了與 PHP 的循環(huán)結(jié)構(gòu)相同的簡(jiǎn)化指令。這些指令的功能也與相應(yīng)的 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

{tip} 循環(huán)中可以使用 循環(huán)變量 獲取循環(huán)的可評(píng)估信息,比如現(xiàn)在是處于循環(huán)的第一次迭代還是最后一次迭代中:

在循環(huán)中,還可以終結(jié)循環(huán)或路過本次迭代:

@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

循環(huán)變量

循環(huán)過程中,在循環(huán)體內(nèi)有一個(gè)可用的 $loop 變量。該變量提供了用于訪問諸如當(dāng)前循環(huán)的索引、當(dāng)前是否為第一次或最后一次循環(huán)之類的少數(shù)有用的信息的途徑:

@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

在嵌套循環(huán)中,可以借助 parent 屬性訪問父循環(huán)的 $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當(dāng)前迭代的索引(從 0 開始計(jì)數(shù))。
$loop->iteration當(dāng)前循環(huán)迭代 (從 1 開始計(jì)算)。
$loop->remaining循環(huán)中剩余迭代的數(shù)量。
$loop->count被迭代的數(shù)組元素的總數(shù)。
$loop->first是否為循環(huán)的第一次迭代。
$loop->last是否為循環(huán)的最后一次迭代。
$loop->depth當(dāng)前迭代的嵌套深度級(jí)數(shù)。
$loop->parent嵌套循環(huán)中,父循環(huán)的循環(huán)變量

注釋

Blade 也允許在視圖中定義注釋。不過與 HTML 注釋不同,Blade 注釋不會(huì)包含在返回給應(yīng)用的 HTML 中:

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

PHP

某些情況下,在視圖中嵌入 PHP 代碼很有用。可以在模板中使用  @php 指令執(zhí)行原生的 PHP 代碼塊:

@php    //@endphp

{tip} 盡管 Blade 提供了這個(gè)特性,但頻繁使用意味著模板中嵌入了過多的邏輯。

表單

CSRF 域

只要在應(yīng)用中定義了 HTML 表單,就一定要在表單中包含隱藏的 CSRF 令牌域,這樣一來 CSRF 保護(hù) 中間件就能校驗(yàn)請(qǐng)求??梢允褂?Blade 的 @csrf 指令生成令牌域:

<form method="POST" action="/profile">
    @csrf   
    ...
</form>

Method 域

HTML 表單不能發(fā)出 PUTPATCHDELETE 請(qǐng)求,需要加入隱藏的 _method 域來模仿這些 HTTP 動(dòng)詞。Blade 的 @method 指令能夠幫你創(chuàng)建這個(gè)域:

<form action="/foo/bar" method="POST">
    @method('PUT')    
    ...
</form>

引入子視圖

Blade 的 @include 指令允許你從其它視圖中引入 Blade 視圖。父視圖中所有可用的變量都將在被引入的視圖中可用:

<div>
    @include('shared.errors')   
   <form>       
    <!-- Form Contents -->    
  </form>
</div>

被包含的視圖不僅會(huì)繼承父視圖的所有可用數(shù)據(jù),還能夠以數(shù)組形式向被包含的視圖傳遞額外數(shù)據(jù):

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

如果傳遞給  @include 一個(gè)不存在的視圖,Laravel 會(huì)拋出錯(cuò)誤。想要包含一個(gè)不能確定存在與否的視圖,需要使用 @includeIf 指令:

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

想要包含一個(gè)依賴于給定布爾條件的視圖,可以使用 @includeWhen 指令:

@includeWhen($boolean, 'view.name', ['some' => 'data'])

要包含給定視圖數(shù)組中第一個(gè)存在的視圖,可以使用 includeFirst 指令:

@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])

{note} 應(yīng)當(dāng)盡量避免在 Blade 視圖中使用 __DIR____FILE__ 魔術(shù)常量,因?yàn)樗鼈儗⒅赶蚓彺嬷薪?jīng)過編譯的視圖的位置。

給被包含的視圖起別名

如果你的 Blade 被包含視圖們存儲(chǔ)在子目錄中,你可能會(huì)希望為它們起個(gè)易于訪問的別名。例如,一個(gè)帶有如下內(nèi)容的 Blade 視圖內(nèi)容被存儲(chǔ)在 resources/views/includes/input.blade.php 文件中:

<input type="{{ $type ?? 'text' }}">

可以使用 include 方法為  includes.input 起一個(gè)叫做 input 的別名。通常,這會(huì)在 AppServiceProviderboot 方法中完成:

use Illuminate\Support\Facades\Blade;
Blade::include('includes.input', 'input');

一旦被包含的視圖擁有了別名,就可以像 Blade 指令一樣使用別名渲染它:

@input(['type' => 'email'])

為集合渲染視圖

可以使用 Blade 的 @each 指令在一行中整合循環(huán)和包含:

@each('view.name', $jobs, 'job')

第一個(gè)參數(shù)是渲染數(shù)組或集合的每個(gè)元素的視圖片段。第二個(gè)參數(shù)是希望被迭代的數(shù)組或集合,第三個(gè)參數(shù)則是將被分配給視圖中當(dāng)前迭代的變量名。例如,想要迭代 jobs 數(shù)組,通常會(huì)在視圖片段中使用 job 變量訪問每個(gè)任務(wù)。當(dāng)前迭代的 key 將作為視圖片段中的 key 變量。

也可以向 @each 指令傳遞第四個(gè)參數(shù)。這個(gè)參數(shù)是當(dāng)給定數(shù)組為空時(shí)要渲染的視圖片段。

@each('view.name', $jobs, 'job', 'view.empty')

{note} 借助 @each 渲染視圖,無法從父視圖中繼承變量。如果子視圖需要這些變量,就必須使用 @foreach@include 代替它。

堆棧

Blade 允許你將視圖壓入堆棧,這些視圖能夠在其它視圖或布局中被渲染。這在子視圖中指定需要的 JavaScript 庫時(shí)非常有用:

@push('scripts')  
  <script src="/example.js">
  </script>
@endpush

如果需要,可以多次壓入堆棧。通過向  @stack 指令傳遞堆棧名稱來完成堆棧內(nèi)容的渲染:

<head> 
   <!-- 頭部?jī)?nèi)容 -->
    @stack('scripts')
 </head>

如果想要將內(nèi)容預(yù)置在棧頂,需要使用 @prepend 指令:

@push('scripts')
    This will be second...@endpush// 然后...
  @prepend('scripts')
    This will be first...
  @endprepend

Service 注入

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

@inject('metrics', 'App\Services\MetricsService')
<div>
    Monthly Revenue: {{ $metrics->monthlyRevenue() }}.</div>

擴(kuò)展 Blade

Blade 允許你使用 directive 方法自定義指令。當(dāng) Blade 編譯器遇到自定義指令時(shí),這會(huì)調(diào)用該指令包含的表達(dá)式提供的回調(diào)。

下面的例子創(chuàng)建了 @datetime($var) 指令,一個(gè)格式化給定的 DateTime 的實(shí)例 $var

<?php
  namespace App\Providers;
  use Illuminate\Support\Facades\Blade;
  use Illuminate\Support\ServiceProvider;
  class AppServiceProvider extends ServiceProvider{  
     /**
     * 執(zhí)行注冊(cè)后引導(dǎo)服務(wù).
     *
     * @return void
     */   
   public function boot()  
     {       
        Blade::directive('datetime', function ($expression) {           
        return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";       
      });    
    }   
    /**
     * 在容器中注冊(cè)綁定.
     *
     * @return void
     */ 
      public function register()  
        { 
             //    
         }
      }

如你所見,我們將在傳遞給該指令的任意表達(dá)式中鏈?zhǔn)秸{(diào)用  format 方法。在這個(gè)例子中,該指令將生成如下原生 PHP 代碼:

<?php echo ($var)->format('m/d/Y H:i'); ?>

{note} 在更新 Blade 指令的邏輯之后,需要 Blade 視圖的所有緩存??梢允褂? view:clear Artisan 命令刪除 Blade 視圖緩存。

自定義 If 語句

在定義簡(jiǎn)單的、自定義條件語句時(shí),編寫自定義指令比必須的步驟復(fù)雜。在這種情況下,Blade 提供了 Blade::if 方法,它允許你使用閉包快速度定義條件指令。例如,定義一個(gè)校驗(yàn)當(dāng)前應(yīng)用環(huán)境的自定義指令,可以在  AppServiceProviderboot 方法中這樣做:

use Illuminate\Support\Facades\Blade;
/**
 * 執(zhí)行注冊(cè)后引導(dǎo)服務(wù)
 *
 * @return void
 */
 public function boot(){  
   Blade::if('env', function ($environment) {     
   return app()->environment($environment);   
   });
 }

一旦定義了自定義條件指令,就可以在模板中輕松的使用:

@env('local')    
  // 應(yīng)用在本地環(huán)境中運(yùn)行...
@elseenv('testing')    
  // 應(yīng)用在測(cè)試環(huán)境中運(yùn)行...
@else    
  // 應(yīng)用沒有在本地和測(cè)試環(huán)境中運(yùn)行...
@endenv
本文章首發(fā)在 LearnKu.com 網(wǎng)站上。