php渲染視圖,Laravel 視圖渲染:Blade 模板引擎

Laravel 視圖渲染:Blade 模板引擎

由 學院君 創建于3年前, 最后更新于 2年前

版本號 #1

53378 views

27 likes

0 collects

Blade 簡介

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

模板繼承

定義布局

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

應用名稱 - @yield('title')

@section('sidebar')

這里是側邊欄

@show

@yield('content')

正如你所看到的,該文件包含典型的 HTML 標記,不過,注意 @section 和 @yield 指令,前者正如其名字所暗示的,定義了一個內容片段,而后者用于顯示給定片段的內容。

現在我們已經為應用定義了一個布局,接下來讓我們定義繼承該布局的子頁面吧。

繼承布局

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

@extends('layouts.app')

@section('title', 'Laravel學院')

@section('sidebar')

@parent

Laravel學院致力于提供優質Laravel中文學習資源

@endsection

@section('content')

這里是主體內容,完善中...

@endsection

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

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

Route::get('blade', function () {

return view('child');

});

這樣在瀏覽器中訪問 http://blog.dev/blade,就可以看到頁面顯示如下:

eba49ac0920305adc855afff60414e7d.png

現在頁面還很粗糙,沒有任何樣式,后面學習前端組件后可以回來完善。

組件&插槽

組件和插槽給內容片段(section)和布局(layout)帶來了方便,不過,有些人可能會發現組件和插槽的模型更容易理解。首先,我們假設有一個可復用的“alert”組件,我們想要在整個應用中都可以復用它:

{{ $slot }}

{{ $slot }} 變量包含了我們想要注入組件的內容,現在,要構建這個組件,我們可以使用 Blade 指令 @component:

@component('alert')

Whoops! Something went wrong!

@endcomponent

有時候為組件定義多個插槽很有用。下面我們來編輯alert組件以便可以注入“標題”,命名插槽可以通過“echoing”與它們的名字相匹配的變量來顯示:

{{ $title }}

{{ $slot }}

現在,我們可以使用指令 @slot 注入內容到命名的插槽。任何不在 @slot 指令中的內容都會被傳遞到組件的 $slot 變量中:

@component('alert')

@slot('title')

Forbidden

@endslot

You are not allowed to access this resource!

@endcomponent

當我們在瀏覽器中查看這個組件內容的話,對應輸出如下:

f15614439bf42457dc81abfdb8d48f5c.png

這段代碼的意思是通過組件名 alert 去查找對應的視圖文件,裝載到當前視圖,然后通過組件中 @slot 定義的插槽內容去渲染插槽視圖中對應的插槽位,如果組件沒有為某個插槽位定義對應的插槽內容片段,則組件中的其他不在 @slot 片段中的內容將會用于渲染該插槽位,如果沒有其他多余內容則對應插槽位為空。

傳遞額外數據到組件

有時候你可能需要傳遞額外數據到組件,出于這個原因,你可以傳遞數組數據作為第二個參數到 @component 指令,所有數據都會在組件模板中以變量方式生效:

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

...

@endcomponent

數據顯示

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

Route::get('greeting', function () {

return view('welcome', ['name' => '學院君']);

});

那么可以通過如下方式顯示 name 變量的內容:

你好, {{ $name }}。

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

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

注:Blade 的 {{}} 語句已經經過 PHP 的 htmlentities 函數處理以避免 XSS 攻擊。

輸出存在的數據

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

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

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

{{ $name or 'Default' }}

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

顯示原生數據

默認情況下,Blade 的 {{ }} 語句已經通過 PHP 的 htmlentities 函數處理以避免 XSS 攻擊,如果你不想要數據被處理,比如要輸出帶 HTML 元素的富文本,可以使用如下語法:

Hello, {!! $name !!}.

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

渲染 JSON 內容

有時候你可能會將數據以數組方式傳遞到視圖再將其轉化為 JSON 格式以便初始化某個 JavaScript 變量,例如:

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

這樣顯得很麻煩,有更簡便的方式來實現這個功能,那就是 Blade 的 @json 指令:

var app = @json($array);

Blade & JavaScript 框架

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

Laravel

Hello, @{{ name }}.

在本例中,@ 符在編譯階段會被 Blade 移除,但是,{{ name }} 表達式將會保持不變,從而可以被 JavaScript 框架正常渲染。

@verbatim指令

如果你在模板中有很大一部分篇幅顯示 JavaScript 變量,那么可以將這部分 HTML 封裝在 @verbatim 指令中,這樣就不需要在每個 Blade 輸出表達式前加上 @ 前綴:

@verbatim

Hello, {{ name }}.

@endverbatim

流程控制

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

If 語句

可以使用 @if , @elseif , @else 和 @endif 來構造 if 語句,這些指令的功能和 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

此外,Blade 還提供了 @isset 和 @empty 指令,分別對應 PHP 的 isset 和 empty 方法:

@isset($records)

// $records is defined and is not null...

@endisset

@empty($records)

// $records is "empty"...

@endempty

認證指令

@auth 和 @guest 指令可用于快速判斷當前用戶是否登錄:

@auth

// 用戶已登錄...

@endauth

@guest

// 用戶未登錄...

@endguest

如果需要的話,你也可以在使用 @auth 和 @guest 的時候指定登錄用戶類型:

@auth('admin')

// The user is authenticated...

@endauth

@guest('admin')

// The user is not authenticated...

@endguest

關于用戶登錄認證我們后面再講到用戶認證的時候再深入探討。

Switch 語句

switch 語句可以通過 @switch,@case,@break,@default 和 @endswitch 指令構建:

@switch($i)

@case(1)

First case...

@break

@case(2)

Second case...

@break

@default

Default case...

@endswitch

和 PHP 中的 switch 語句結構完全一致。

循環

除了條件語句,Blade 還提供了簡單的指令用于處理 PHP 的循環結構,同樣,這些指令的功能和 PHP 對應功能完全一樣:

@for ($i = 0; $i < 10; $i++)

The current value is {{ $i }}

@endfor

@foreach ($users as $user)

This is user {{ $user->id }}

@endforeach

@forelse ($users as $user)

{{ $user->name }}

@empty

No users

@endforelse

@while (true)

I'm looping forever.

@endwhile

注:在循環的時候可以使用 $loop 變量獲取循環信息,例如是否是循環的第一個或最后一個迭代。

使用循環的時候還可以結束循環或跳出當前迭代:

@foreach ($users as $user)

@if ($user->type == 1)

@continue

@endif

{{ $user->name }}

@if ($user->number == 5)

@break

@endif

@endforeach

還可以使用指令聲明來引入條件:

@foreach ($users as $user)

@continue($user->type == 1)

{{ $user->name }}

@break($user->number == 5)

@endforeach

$loop變量

在循環的時候,可以在循環體中使用 $loop 變量,該變量提供了一些有用的信息,比如當前循環索引,以及當前循環是不是第一個或最后一個迭代:

@foreach ($users as $user)

@if ($loop->first)

This is the first iteration.

@endif

@if ($loop->last)

This is the last iteration.

@endif

This is user {{ $user->id }}

@endforeach

如果你身處嵌套循環,可以通過 $loop 變量的 parent 屬性訪問父級循環:

@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

嵌套循環中的父級循環變量

注釋

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

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

PHP

在一些場景中,嵌入 PHP 代碼到視圖中很有用,你可以使用 @php 指令在模板中執行一段原生 PHP 代碼:

@php

//

@endphp

注:盡管 Blade 提供了這個特性,如果過于頻繁地使用它意味著你在視圖模板中嵌入了過多的業務邏輯,需要注意。

包含子視圖

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

@include('shared.errors')

上述指令會在當前目錄下的 shared 子目錄中尋找 errors.blade.php 文件并將其內容引入當前視圖。

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

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

當然,如果你嘗試包含一個不存在的視圖,Laravel 會拋出錯誤,如果你想要包含一個有可能不存在的視圖,可以使用 @includeIf 指令:

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

如果包含的視圖取決于一個給定的布爾條件,可以使用 @includeWhen 指令:

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

要包含給定數組中的第一個視圖,可以使用 @includeFirst 指令:

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

注:不要在 Blade 視圖中使用 __DIR__ 和 __FILE__ 常量,因為它們會指向緩存視圖的路徑。

曾經有人問過我 @include 和 @component 有什么區別,兩者有共同之處,都用于將其他內容引入當前視圖,我理解的區別在于 @include 用于粗粒度的視圖包含,@component 用于細粒度的組件引入,@component 通過插槽機制對引入視圖內容可以進行更加細粒度的控制,如果你只是引入一塊視圖內容片段,用 @include 即可,如果想要在當前視圖對引入視圖內容片段進行調整和控制,則可以考慮使用 @component。

渲染集合視圖

你可以使用 Blade 的 @each 指令通過一行代碼循環引入多個局部視圖:

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

該指令的第一個參數是數組或集合中每個元素要渲染的局部視圖,第二個參數是你希望迭代的數組或集合,第三個參數是要分配給當前視圖的變量名。舉個例子,如果你要迭代一個 jobs 數組,通常你需要在局部視圖中訪問 $job 變量。在局部視圖中可以通過 key 變量訪問當前迭代的鍵。

你還可以傳遞第四個參數到 @each 指令,該參數用于指定給定數組為空時渲染的視圖:

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

堆棧

Blade 允許你推送內容到命名堆棧,以便在其他視圖或布局中渲染。這在子視圖中引入指定 JavaScript 庫時很有用:

@push('scripts')

@endpush

推送次數不限,要渲染完整的堆棧內容,傳遞堆棧名稱到 @stack 指令即可:

@stack('scripts')

服務注入

@inject 指令可以用于從服務容器中獲取服務,傳遞給 @inject 的第一個參數是服務對應的變量名,第二個參數是要解析的服務類名或接口名:

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

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

擴展 Blade

Blade 甚至還允許你自定義指令,可以使用 directive 方法來注冊一個指令。當 Blade 編譯器遇到該指令,將會傳入參數并調用提供的回調。

下面的例子創建了一個 @datetime($var) 指令格式化給定的 DateTime 的實例 $var:

namespace App\Providers;

use Illuminate\Support\Facades\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 date('Y-m-d H:i:s', $expression); ?>";

});

}

/**

* 在容器中注冊綁定.

*

* @return void

*/

public function register()

{

//

}

}

正如你所看到的,我們可以將 datetime 方法應用到任何傳入指令的表達式上:

@datetime(1508888888)

最終該指令生成的 PHP 代碼如下:

注:更新完 Blade 指令邏輯后,必須刪除所有的 Blade 緩存視圖。緩存的 Blade 視圖可以通過 Artisan 命令 view:clear 移除。

自定義 If 語句

在定義一些簡單、自定義的條件語句時,編寫自定義指令往往復雜性大于必要性,因為這個原因,Blade 提供了一個 Blade::if 方法通過閉包的方式快速定義自定義的條件指令,例如,我們來自定義一個條件來檢查當前應用的環境,我們可以在 AppServiceProvider 的 boot 方法中定義這段邏輯:

use Illuminate\Support\Facades\Blade;

/**

* Perform post-registration booting of services.

*

* @return void

*/

public function boot()

{

\Blade::if('env', function ($environment) {

return app()->environment($environment);

});

}

定義好自定義條件后,就可以在模板中使用了:

@env('local')

The application is in the local environment...

@else

The application is not in the local environment...

@endenv

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/271086.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/271086.shtml
英文地址,請注明出處:http://en.pswp.cn/news/271086.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

項目管理基礎:系統切換相關知識筆記

1、系統試運行主要任務對新系統進行初始化、補錄各種原始數據記錄記錄系統運行過程中的數據和狀況核對新舊系統輸出結果是否正確對實際系統的輸入方式進行考察主要包括是否方便、效率、可靠性、誤操作保護等方面。對系統實際運行、響應速度進行實際測試&#xff0c;確定是否滿足…

sql 分組統計_leetcode-sql面試題十七篇精講合集

這可能是全網最干貨的sql講解系列文章。全系列共十七講。做了大量的知識點的拓展&#xff0c;涵蓋了sql的方方面面。歡迎關注點贊收藏&#xff0c;正在整理三年數據分析的點點滴滴。包括Excel、python、sql、power BI、各種分析模型框架。保證輸出最干的干貨。涉及知識點包括&a…

實時數據處理插件開發flume+kafka+storm:flume

有時間了再寫。。。。轉載于:https://www.cnblogs.com/wchb/p/5786582.html

項目管理基礎:系統維護相關知識筆記

1、系統的可維護性系統的可維護性就是項目維護人員理解、改正、改動和改進該軟件的難易程度。提高系統的可維護性是開發軟件吸引所有步驟的關鍵目的&#xff0c;系統能否被很好地維護&#xff0c;可用系統的可維護性這一指標來衡量。1.1 系統可維護性的評價指標可理解性&#x…

java ibm 2035,C# java 連接 IBM MQ時出現 2035 或 2013認證錯誤的解決方法

當C# 或 java 連接 IBM MQ 是出現 2035 或 2013的錯誤時java的錯誤提示&#xff1a;com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: 為隊列管理器“QM1”提供的安全性認證無效&#xff0c;連接方式為“Client”&#xff0c;主機名為“9.186.105.212(1414)”…

python給兩個列表排序方法_Python連接兩個字符串列表并對其元素排序的最佳方法...

假設我有兩個字符串列表&#xff1a;x[a,b] and b[c,d]我需要的最終結果是&#xff1a;^{pr2}$重要的一點是&#xff0c;我希望對列表元素的字母進行排序。在這里&#xff0c;他們是建設&#xff0c;但在我的實際問題&#xff0c;這不是這樣。所以如果我有“ba”&#xff0c;在…

mac搭建本地svn

1.終端&#xff0c;創建SVN資源文件庫 svnadmin create /Volumes/DATA/SVNTest 2配置權限 上面的語句執行完之后在相應路徑下可以找到該文件夾&#xff0c;打開之后 這里主要是修改conf里面的是三個文件&#xff1a;authz&#xff0c;passwd&#xff0c;scnserve.conf a.authz …

一個棧楨對應著一個方法

一個棧楨對應著一個方法

php提交之前驗證數據ajax提示,在通過Ajax請求提交之前使用jQuery進行表單驗證

在嘗試使用Ajax請求將表單提交到我的php腳本之前,我試圖讓我的表單進行驗證.我查看了stackoverflow并沒有找到有用的東西.我有3個輸入和一個提交按鈕&#xff1a;$(document).ready(function() {function validator(){return $(form).validate();}$(form).on(submit, function(…

程序員幽默:39個奇葩代碼注釋,每一個都能笑抽

1. 只有上帝知道//我寫這一行的時候&#xff0c;只有上帝和我知道我在寫什么//現在&#xff0c;只有上帝知道了2. 相隔時空的diss//somedev1 - 6/7/02 添加對登錄屏幕的暫時追蹤功能//somedev2 - 5/22/07 暫時個屁&#xff08;仿佛看到兩個程序員相隔時空的diss&#xff09;3…

網絡安全用python嗎_使用Python進行網絡安全滲透——密碼攻擊測試器

相關文章&#xff1a;本篇將會涉及&#xff1a;HTTP 基本認證對HTTP Basic認證進行密碼暴力攻擊測試什么是HTTP 基本認證HTTP基本認證(HTTP Basic Authentication)是HTTP協議中實現Web資源訪問控制的最簡單的認證手段。其通過添加header頭域的方式或者在URL中附帶參數的方式提供…

EJB3 學習筆記六

開發表音映射的實體 Java持久化規范(JPA),即是實體bean通遠元數據在javaBean和數據庫之間建立映射關系,常見的hibernate toplink openjpa 在src目錄下添加META-INF/persistence.xml文件,示例代碼如下: <?xmlversion"1.0"encoding"UTF-8"?> <…

棧出現的異常和設置棧的大小-Xss

異常 java.lang.StackOverflowError 看下面的例子&#xff0c;默認的棧內存 設置棧內存 使用參數-Xss大小來設置棧的大小

bmp 像素點 php,讀取BMP圖像每一像素點RGB數據 | 學步園

對于24位bmp圖片&#xff0c;每一個像素點存放著此點的RGB值。首先定義一個結構體&#xff0c;包含紅(red)、綠(green)、藍(blue)這三個字段&#xff0c;如下&#xff1a;//像素顏色值typedef struct tagPOINT{BYTE b;BYTE g;BYTE r;} POINT;接下來定義用來存放每一像素點RGB值…

項目管理基礎:系統評價相關知識

1、概念軟件系統的評價分為廣義評價和狹義評價。廣義評價&#xff1a;主要是指系統從開發開始到結束的過程中&#xff0c;每個階段都要進行系統評價。狹義評價&#xff1a;主要是指在系統建成后并投入運行之后進行全面、綜合的評價。2、廣義評價分類根據時間與軟件系統所處的階…

AutoHotKey程序防止反編譯的簡單手段

可以使用AutoHotKey自帶的工具。 AutoHotKey安裝完成后&#xff08;我使用的是1.1.0.0&#xff09;&#xff0c;找到安裝所在目錄下的文件&#xff1a;\Compiler\Ahk2Exe.exe。 程序界面如下&#xff1a; 簡單使用&#xff1a; 1、選擇源文件&#xff08;script file) 2、選擇目…

table合并單元格_制作課程表3——合并單元格

由于瀏覽器兼容問題&#xff0c;、 以及 很少被使用&#xff0c;所以我們將課程表依然使用tr、td元素&#xff0c;結合樣式實現出前面案例中效果原來代碼&#xff1a;課程1 課程2 課程3 課程4 課程5 課程1 課程2 課程3 課程4 課程5 課程1 課程2 課程3 課程4 課程5 課程1 …

php join a.id b.id,mysql求助 請問where a.id=b.id 和join on a.id=b.id 在效率上的區別

下面是ecshop 的商品表和品牌表的查詢&#xff0c;請問它們的查詢效率有什么區別呢&#xff1f;還有一個問題是 left join 和join的效率哪個高一點呢。謝謝 &#xff01;&#xff01;SELECT a.goods_id , a.goods_name , b.brand_nameFROM ecs_goods AS aLEFT JOIN ecs_brand A…

數據庫設計:數據庫應用系統的生命周期

數據庫應用系統的生命周期可以劃分為&#xff1a;數據庫規劃、需求描述與分析、數據庫與應用程序設計、數據庫設計實現、數據庫測試、數據庫運維。1、數據庫規劃 數據庫規劃是創建數據庫應用系統的第一步&#xff0c;也是數據庫應用系統的任務描述和目標的明確。數據庫規劃的內…