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 指令,分别对应 PHPissetempty 方法:

@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>
powered by GitbookEdit Time: 2023-04-08 10:28:32