PHP遍历用blade标签表示,【laravel7.x中文文档】Blade 模板

Blade 模板

[TOC]

简介

Blade 是 Laravel 提供的一个简单而又强大的模板引擎。和其他流行的 PHP 模板引擎不同,Blade 并不限制你在视图中使用原生 PHP 代码。所有 Blade 视图文件都将被编译成原生的 PHP 代码并缓存起来,除非它被修改,否则不会重新编译,这就意味着 Blade 基本上不会给你的应用增加任何负担。Blade 视图文件使用 .blade.php作为文件扩展名,被存放在 resources/views 目录。

模板继承

定义布局

Blade 的两个主要优点是 模板继承和区块。为方便入门,让我们先通过一个简单的例子来上手。首先,我们来研究一个「主」页面布局。因为大多数 web 应用会在不同的页面中使用相同的布局方式,因此可以很方便地定义单个 Blade 布局视图:

App Name - @yield('title')

@section('sidebar')

This is the master sidebar.

@show

@yield('content')

如你所见,该文件包含了典型的 HTML 语法。不过,请注意

现在,我们已经定义好了这个应用程序的布局,接下来,我们定义一个继承此布局的子页面。

继承布局

在定义一个子视图时,使用 Blade 的

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')

@parent

This is appended to the master sidebar.

@endsection

@section('content')

This is my body content.

@endsection

在这个示例中, sidebar 片段利用

{tip} 和上一个示例相反,这里的 sidebar 片段使用 立即 yield 这个片段。

@yield('content', View::make('view.name'))

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

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

return view('child');

});

显示数据

可以将变量放在大括号中传递到 Blade 视图中显示。比如给出如下路由:

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

return view('welcome', ['name' => 'Samantha']);

});

就可以这样利用 name 变量显示其内容:

Hello, {{ $name }}.{tip} Blade 的 {{ }} 语句是自动经过 PHP 的 htmlspecialchars 函数转义以防范 XSS 攻击。

不仅仅可以显示传递给视图的数据,也可以显示任意 PHP 函数的执行结果。实际上,你可以在 Blade 的回显语句中放置你想要的任意 PHP 代码:

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

显示非转义字符

默认情况下, Blade 中 {{ }} 语句自动经由 PHP 的 htmlspecialchars 函数转义以防范 XSS 攻击。 如果你不希望数据被转义,可以使用下面的语法:

Hello, {!! $name !!}.{note} 在显示用户提供的内容时需要谨慎小心。在显示用户提供的数据时,有必要一直使用双花括号语法转义来防范 XSS 攻击。

渲染 JSON

有时,为了初始化一个 JavaScript 变量,你可能会向视图传递一个数组,并将其渲染成 JSON。例如:

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

然而,你可以使用 json_encode,而不是手动调用 json_encode。PHP 的 json_encode 函数拥有相同的参数。

var app = @json($array);

var app = @json($array, JSON_PRETTY_PRINT);

{note} 使用

data-* 属性:

{note} 在 HTML 标签的属性中使用

HTML 实体编码

默认情况下,Blade (和 Laravel 的 e 助手函数) 将对 HTML 实体进行双重编码。 如果你想要禁用双重编码,请从 AppServiceProvider 的 boot 方法中调用中 Blade::withoutDoubleEncoding方法:

namespace App\Providers;

use Illuminate\Support\Facades\Blade;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider

{

/**

* Bootstrap any application services.

*

* @return void

*/

public function boot()

{

Blade::withoutDoubleEncoding();

}

}

Blade & JavaScript 框架

由于许多 JavaScript 框架也使用 “大括号” 来表示预设的表达式应该显示在浏览器中,因此可以使用 @ 符号表示 Blade 渲染引擎表达式应保持不变。例如:

Laravel

Hello, @{{ name }}.

在这个例子中, @ 符号将被 Blade 删除;在 Blade 引擎中 {{ name }} 表达式将保持不变,取而代之的是 JavaScript 引擎来渲染该表达式。

如果你在模板中显示了很大一部分的 JavaScript 变量,可以将 HTML 套嵌在 Blade 回显语句前面加上 @ 符号:

@verbatim

Hello, {{ name }}.

@endverbatim

控制结构

除了模板继承和显示数据之外,Blade 还为常见的 PHP 控制结构提供了便捷的书写方式,例如条件和循环语句。这些快捷方式提供了一种简洁的 PHP 控制语句的写法,同时保持了与 PHP 中的相应结构的语法特性。

If 语句

你可以使用 if 语句。这些指令的功能与它们在 PHP 中对应的语句功能相同:

@if (count($records) === 1)

我有一条记录!

@elseif (count($records) > 1)

我有好多条记录!

@else

我没有记录!

@endif

为了方便,Blade 也提供了一个

@unless (Auth::check())

You are not signed in.

@endunless

除了已经讨论过的条件指令之外,

@isset($records)

// 变量 $records 已定义且不为空...

@endisset

@empty($records)

// 变量 $records 为空...

@endempty

认证指令

@auth

// 用户身份已被验证…

@endauth

@guest

// 用户身份未被验证…

@endguest

如果需要,可以在使用

@auth('admin')

// 用户身份已被验证…

@endauth

@guest('admin')

// 用户身份未被验证…

@endguest

片段指令

您可以使用

@hasSection('navigation')

@yield('navigation')

@endif

Switch 语句@switch($i)

@case(1)

First case...

@break

@case(2)

Second case...

@break

@default

Default case...

@endswitch

循环

除了条件语句外,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{tip} 循环时,您可以使用 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 变量在循环内部可用。通过此变量可以访问一些有用的信息,例如当前循环索引以及这是循环的第一次还是最后一次迭代:

@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

如果您处于嵌套循环中,则可以借助 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->even

是否为循环中的偶数次迭代

$loop->odd

是否为循环中的奇数次迭代

$loop->depth

当前循环的嵌套深度

$loop->parent

嵌套循环中的父循环的循环变量

注释

Blade 也允许在视图中定义注释。不过与 HTML 注释不同,Blade 注释不会包含在返回给应用的 HTML 中:

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

PHP

某些情况下,在视图中嵌入 PHP 代码很有用。可以在模板中使用

@php

//

@endphp{tip} 尽管 Blade 提供了这个特性,但频繁使用意味着模板中嵌入了过多的逻辑。

表单

CSRF 域

只要您在应用中定义了 HTML 表单,就一定要在表单中包含隐藏的 CSRF 令牌域,这样一来 CSRF 保护 中间件就能校验请求。可以使用 Blade 的

@csrf

...

Method 域

HTML 表单不能发出 PUT、 PATCH 及 DELETE 请求,需要加入隐藏的 _method 域来模拟这些 HTTP 动作。Blade 的

@method('PUT')

...

错误验证

$message 变量以显示错误消息:

Post Title

@error('title')

{{ $message }}

@enderror

您也可以指定错误验证字段名字,作为第二个参数传递给

Email address

@error('email', 'login')

{{ $message }}

@enderror

组件

组件和插槽的作用与片段(Section)和布局(Layout)类似。不过,有些人可能认为组件和插槽使用起来更加方便。Laravel 支持两种编写组件的方法:基于类的组件和匿名组件。

我们可以用 Artisan 命令 make:component 来创建一个基于类的组件(组件类)。以下将通过创建一个简单的 Alert 组件来向你说明如何使用组件。使用 make:component 命令创建的组件将位于 app/View/Components 目录中。

php artisan make:component Alert

make:component 命令同时也自动为该组件建立了一个视图模板。该视图位于 resources/views/components 目录中

手动注册包组件

在默认情况下,Laravel 将会在 app/View/Components 和 resources/views/components 自动发现并注册组件。

不过,如果你的组件使用了 Blade 组件,则需要手动注册组件类并为其注册 HTML 标签别名。你可以在服务提供者(Service Provider)中的 boot 方法处注册组件:

use Illuminate\Support\Facades\Blade;

/**

* Bootstrap your package's services.

*/

public function boot()

{

Blade::component(AlertComponent::class, 'package-alert');

}

注册组件后,你将可以通过 HTML 标签别名来使用它:

显示组件

你可以在任一 Blade 模板中使用 Blade 组件标签来显示组件。Blade 组件标签以 x- 开头,后面接上组件类的 kebab case 名称(即单词与单词间使用连字符 -):

如果组件类位于 app/View/Components 目录中的子目录中,则可以使用 . 字符指定目录层级。例如,某组件位于 app/View/Components/Inputs/Button.php,则可以这样渲染:

组件传参

你可以使用 HTML 属性将数据传递给 Blade 组件。普通的值可以通过简单的 HTML 属性传递,而 PHP 表达式及变量应当通过以 : 为前缀的属性传递:

你可以在组件类的构造函数中定义组件所需的数据。组件类中的所有公共属性都将自动传递给组件视图。不必通过组件类的 render 方法传递:

namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component

{

/**

* 警告类型

*

* @var string

*/

public $type;

/**

* 警告消息

*

* @var string

*/

public $message;

/**

* 创建组件实例

*

* @param string $type

* @param string $message

* @return void

*/

public function __construct($type, $message)

{

$this->type = $type;

$this->message = $message;

}

/**

* 获取组件的视图 / 内容

*

* @return \Illuminate\View\View|string

*/

public function render()

{

return view('components.alert');

}

}

渲染组件时,可以通过变量名称来获取组件类公共属性的内容:

{{ $message }}

组件方法

除了可获取组件类的公共属性外,还可以在组件视图中执行组件类上的任何公共方法。例如,某组件具有一个 isSelected 方法:

/**

* 判断给定选项是否为当前选项

*

* @param string $option

* @return bool

*/

public function isSelected($option)

{

return $option === $this->selected;

}

你可以通过调用与方法名称相同的变量来执行该方法:

{{ $label }}

附加依赖项

如果你的组件需要使用 Laravel 的服务容器中的依赖项,则应当在组件所有数据属性之前列出它们,它们将会被容器自动注入:

use App\AlertCreator

/**

* 创建组件实例

*

* @param \App\AlertCreator $creator

* @param string $type

* @param string $message

* @return void

*/

public function __construct(AlertCreator $creator, $type, $message)

{

$this->creator = $creator;

$this->type = $type;

$this->message = $message;

}

管理属性

我们已将了解了如何将数据属性传递给组件。然而,有时候我们可能需要指定其他的 HTML 属性(如 class),这些属性不是组件所需要的数据。这种情况下,我们将会想要将这些属性向下传递到组件模板的根元素。例如,我们要渲染一个 alert 组件,如下所示:

所有不属于组件构造函数的属性都将自动添加到组件的「属性包」中。该属性包将会通过 $attributes 变量传递给组件视图。通过输出此变量,即可在组件中呈现所有属性:

默认 / 合并属性

某些时候,你可能需要指定属性的默认值,或将其他值合并到组件的某些属性中。为此,你可以使用属性包的 merge 方法:

merge(['class' => 'alert alert-'.$type]) }}>

{{ $message }}

假设我们如下方所示使用该组件:

最终呈现的组件 HTML 将如下所示:

插槽

通常,你需要通过 slots 向组件传递附加内容。 假设我们创建的 alert 组件具有以下标记:

{{ $slot }}

我门可以通过向组件注入内容的方式,将内容传递到 slots :

Whoops! Something went wrong!

有时候一个组件可能需要在它内部的不同位置放置多个不同的插槽。我们来修改一下alert组件,使其允许注入 title 。

{{ $title }}

{{ $slot }}

你可以使用 x-slot 标签来定义一个命名插槽的内容。而不在 x-slot 标签中的其它内容都将传递给 $slot 变量中的组件:

Server Error

Whoops! Something went wrong!

内联组件视图

对于非常小型的组件,管理组件类和视图模版的操作可能会显得过于复杂。因此,你可以直接通过 render 方法返回组件的内容:

/**

* Get the view / contents that represent the component.

*

* @return \Illuminate\View\View|string

*/

public function render()

{

return <<

{{ $slot }}

blade;

}

创建内联视图组件

如果需要创建一个能够渲染内联视图的组件,你可以在执行 make:component 命令时使用 inline 选项:

php artisan make:component Alert --inline

匿名组件

与内联组件类似,匿名组件也提供了通过单个文件管理组件的机制。然后,匿名组件使用的是一个没有关联类的单个视图文件。要定义匿名组件,只需在 resources/views/components 目录下创建一个Blade模版文件。例如,假设 你在 resources/view/components/alert.blade.php 中定义了一个组件:

你可以使用 . 字符来标明组件是否在 components 的深层目录中。比如,假设组件是定义在 resources/views/components/inputs/button.blade.php ,你可以像下面这样来渲染它:

数据 / 属性

由于匿名组件没有任何关联的类,您可能想知道如何区分哪些数据应该作为变量传递给组件,而哪些属性应该放在组件的[属性包](管理属性)中。

你可以使用组件Blade模板顶部的

@props(['type', 'message'])

merge(['class' => 'alert alert-'.$type]) }}>

{{ $message }}

引入子视图

Blade模版的

@include('shared.errors')

除了可以在子视图中继承父视图中的所有可用数据,你也可以通过数组形式将数据传递给子视图:

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

如果你尝试

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

如果你想要在给定布尔表达式结果为 true 时

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

如果你想要在给定布尔表达式结果为 false 时

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

要包含给定视图数组中的第一个视图,你可以使用

@includeFirst(['custom.admin', 'admin'], ['some' => 'data']){注意} 你应该避免在视图中使用 __DIR__ 和 __FILE__ 常量,因为他们会引用缓存和编译过的视图位置。

给被包含的视图起别名

如果你的 Blade 被包含视图们存储在子目录中,你可能会希望为它们起个易于访问的别名。例如,一个带有如下内容的 Blade 视图内容被存储在 resources/views/includes/input.blade.php 文件中:

你可以使用 include 方法为 includes.input 起一个叫做 input 的别名。通常,这会在 AppServiceProvider 的 boot 的方法中完成:

use Illuminate\Support\Facades\Blade;

Blade::include('includes.input', 'input');

一旦被包含的视图拥有了别名,就可以像 Blade 指令一样使用别名渲染它:

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

为集合渲染视图

可以使用 Blade 的

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

第一个参数是渲染数组或集合的每个元素的视图片段。第二个参数是希望被迭代的数组或集合,第三个参数则是将被分配给视图中当前迭代的变量名。例如,想要迭代 jobs 数组,通常会在视图片段中使用 job 变量访问每个任务。当前迭代的 key 将作为视图片段中的 key 变量。

你也可以向

@each('view.name', $jobs, 'job', 'view.empty'){note} 借助

堆栈

Blade 允许你将视图压入堆栈,这些视图能够在其它视图或布局中被渲染。这在子视图中指定需要的 JavaScript 库时非常有用:

@push('scripts')

@endpush

如果需要,可以多次压入堆栈。通过向

@stack('scripts')

如果想要将内容预置在栈顶,需要使用

@push('scripts')

This will be second...

@endpush

// Later...

@prepend('scripts')

This will be first...

@endprepend

Service 注入

The 服务容器中获取服务。传递给

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

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

扩展 Blade

Blade 允许你使用 directive 方法自定义指令。当 Blade 编译器遇到自定义指令时,这会调用该指令包含的表达式提供的回调。

下面的例子创建了 DateTime 的实例 $var:

namespace App\Providers;

use Illuminate\Support\Facades\Blade;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider

{

/**

* 在容器中注册绑定.

*

* @return void

*/

public function register()

{

//

}

/**

* 执行注册后引导服务.

*

* @return void

*/

public function boot()

{

Blade::directive('datetime', function ($expression) {

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

});

}

}

如你所见,我们将在传递给该指令的任意表达式中链式调用 format 方法。在这个例子中,该指令将生成如下原生 PHP 代码:

<?php echo ($var)->format('m/d/Y H:i'); ?>{note} 在更新Blade 指令的逻辑之后,需要删除 Blade 视图的所有缓存。可以使用 view:clear Artisan 命令删除 Blade 视图缓存。

自定义 If 语句

在定义简单的、自定义条件语句时,编写自定义指令有时会比必须的步骤复杂。在这种情况下,Blade 提供了 Blade::if 方法,它允许你使用闭包快速度定义条件指令。例如,定义一个校验当前应用环境的自定义指令,可以在 AppServiceProvider 的 boot 方法中这样做:

use Illuminate\Support\Facades\Blade;

/**

* 执行注册后引导服务

*

* @return void

*/

public function boot()

{

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

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

});

}

一旦定义了自定义条件指令,就可以在模板中轻松的使用:

@env('local')

// 应用在本地环境中运行...

@elseenv('testing')

// 应用在测试环境中运行...

@else

// 应用没有在本地和测试环境中运行...

@endenv

@unlessenv('production')

// 应用不在生产环境中运行...

@endenv

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值