blade模板引擎
blade模板引擎
Blade
是由 Laravel
提供的非常简单但功能强大的模板引擎,不同于其他流行的 PHP 模板引擎,Blade
在视图中并不约束你使用 PHP
原生代码。所有的 Blade
视图最终都会被编译成原生 PHP
代码并缓存起来直到被修改,这意味着对应用的性能而言 Blade
基本上是零开销。Blade
视图文件使用 .blade.php
文件扩展并存放在 resources/views
目录下。
模板继承
定义布局
<!-- 存放在 resources/views/layouts/app.blade.php -->
<html>
<head>
<title>应用名称 - @yield('title')</title>
</head>
<body>
@section('sidebar')
这里是侧边栏
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
继承布局
<!-- 存放在 resources/views/child.blade.php -->
@extends('layouts.app')
@section('title', 'Laravel')
@section('sidebar')
@parent
<p>Laravel侧边栏内容</p>
@endsection
@section('content')
<p>这里是主体内容,完善中...</p>
@endsection
组件 & 插槽
组件和插槽给内容片段(section)
和布局(layout)
带来了方便,不过,有些人可能会发现组件和插槽的模型更容易理解。首先,我们假设有一个可复用的alert
组件,我们想要在整个应用中都可以复用它:
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
{{ $slot }}
变量包含了我们想要注入组件的内容,现在,要构建这个组件,我们可以使用 Blade 指令
@component('alert')
<strong>Whoops!</strong> Something went wrong!
@endcomponent
有时候为组件定义多个插槽很有用。下面我们来编辑alert
组件以便可以注入标题
,命名插槽可以通过echoing
与它们的名字相匹配的变量来显示:
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
<div class="alert-title">{{ $title }}</div>
{{ $slot }}
</div>
现在,我们可以使用指令 @slot
注入内容到命名的插槽。任何不在 @slot
指令中的内容都会被传递到组件的 $slot
变量中:
@component('alert')
@slot('title')
Forbidden
@endslot
You are not allowed to access this resource!
@endcomponent
数据显示
Route::get('greeting', function () {
return view('welcome', ['name' => '学院君']);
});
那么可以通过如下方式显示 name
变量的内容:
你好, {{ $name }}。
输出 PHP
函数的结果
The current UNIX timestamp is {{ time() }}.
输出存在的数据
{{ isset($name) ? $name : 'Default' }}
//除了使用三元运算符,Blade 还提供了更简单的方式:
{{ $name or 'Default' }}
显示原生数据
要输出带 HTML
元素的富文本,可以使用如下语法:
Hello, {!! $name !!}.
渲染 JSON 内容
有时候你可能会将数据以数组方式传递到视图再将其转化为 JSON
格式以便初始化某个 JavaScript
变量,例如:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
这样显得很麻烦,有更简便的方式来实现这个功能,那就是 Blade
的 @json
指令:
<script>
var app = @json($array);
</script>
Blade & JavaScript 框架
由于很多 JavaScript
框架也是用花括号来表示要显示在浏览器中的表达式,如 Vue
,我们可以使用 @
符号来告诉 Blade
渲染引擎该表达式应该保持原生格式不作改动。比如:
<h1>Laravel</h1>
Hello, @{{ name }}.
流程控制
If 语句
@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
的时候指定认证 guard
:
@auth('admin')
// The user is authenticated...
@endauth
@guest('admin')
// The user is not authenticated...
@endguest
Section 指令
你可以使用 @hasSection
指令判断某个 section 中是否有内容:
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
<div class="clearfix"></div>
@endif
Switch 语句
switch
语句可以通过 @switch,@case,@break,@default
和 @enswitch
指令构建:
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
循环
@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
使用循环的时候还可以结束循环或跳出当前迭代:
@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
$loop
变量
在循环的时候,可以在循环体中使用 $loop
变量,该变量提供了一些有用的信息,比如当前循环索引,以及当前循环是不是第一个或最后一个迭代:
@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
如果你身处嵌套循环,可以通过 $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 的 @include
命令来引入一个已存在的视图,所有在父视图的可用变量在被引入的视图中都是可用的。
<div>
@include('shared.errors')
<form>
<!-- 表单内容 -->
</form>
</div>
被引入的视图会继承父视图中的所有数据,同时也可以向引入的视图传递额外的数组数据:
@include('view.name', ['some' => 'data'])
当然,如果尝试使用 @include
去引入一个不存在的视图,Laravel
会抛出错误。如果想引入一个可能存在或可能不存在的视图,就使用 @includeIf
指令:
@includeIf('view.name', ['some' => 'data'])
如果要根据给定的布尔条件 @include
视图,可以使用 @includeWhen
指令:
@includeWhen($boolean, 'view.name', ['some' => 'data'])
要包含来自给定数组视图的第一个视图,可以使用 includeFirst
指令:
@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
请避免在 Blade 视图中使用 __DIR__
及 __FILE__
常量,因为它们会引用编译视图时缓存的位置。
堆栈
Blade 可以被推送到在其他视图或布局中的其他位置渲染的命名堆栈。这在子视图中指定所需的 JavaScript
库时非常有用:
@push('scripts')
<script src="/example.js"></script>
@endpush
你可以根据需要多次压入堆栈,通过 @stack
命令中传递堆栈的名称来渲染完整的堆栈内容:
<head>
<!-- Head Contents -->
@stack('scripts')
</head>