热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Laravel5.5视图Blade模板引擎

Blade简介Blade是由Laravel提供的非常简单但功能强大的模板引擎,不同于其他流行的PHP模板引擎,Blade在视图中并不约束你使用PHP原生代码。所有的Blade视图最

Blade 简介

Blade 是由 Laravel 提供的非常简单但功能强大的模板引擎,不同于其他流行的 PHP 模板引擎,Blade 在视图中并不约束你使用 PHP 原生代码。所有的 Blade 视图最终都会被编译成原生 PHP 代码并缓存起来直到被修改,这意味着对应用的性能而言 Blade 基本上是零开销。

Blade 视图文件(也叫模板文件)使用 .blade.php 文件扩展名,都存放在 resources/views 目录下。

模板继承

定义布局

使用 Blade 的两个最大优点是模板继承和片段组合,开始之前让我们先看一个例子。

首先,我们测试主页面布局,由于大多数 Web 应用在不同页面中使用同一个布局,可以很方便的将这个布局定义为一个单独的 Blade 页面。

在 resources/views/layouts 目录中,创建一个布局文件 layout.blade.php,内容如下:






@section('sidebar')
这里是侧边栏
@show


@yield('content')


该文件包含典型的 HTML 标记,不过,注意 @section 和 @yield 指令,前者定义了一个内容片段,而后者用于显示给定片段的内容。

现在我们已经为应用定义了一个布局,接下来定义继承该布局的子页面。

继承布局

定义子页面时,可以使用 Blade 的 @extends 指令来指定子页面所继承的布局,继承一个 Blade 布局的视图可以使用 @section 指令注入内容到布局定义的内容片段中。

如上面例子所示,这些片段的内容将会显示在布局中使用 @yield 的地方。

在 resources/views 目录中,创建视图文件 child.blade.php,内容如下:

@extends('layouts.layout')
@section('title', '视图标题')
@section('sidebar')
@parent

这是子页面的内容


@endsection
@section('content')

这里是主体内容,完善中...


@endsection

在本例中,sidebar 片段使用 @parent 指令来追加(而非覆盖)内容到布局的侧边栏,@parent 指令在视图渲染时将会被布局中的内容替换。

然后,在 routes/web.php 中定义路由以便访问该视图。

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

在浏览器中访问 http://www.adm.devp/blade ,查看显示效果。

组件&插槽

组件和插槽给内容片段(section)和布局(layout)带来了方便,不过,有些人可能会发现组件和插槽的模型更容易理解。

首先,我们假设有一个可复用的“alert”组件,我们想要在整个应用中都可以复用它。

创建 resources/views/alert.blade.php 文件,内容如下:


{
{ $slot }}

{ { $slot }} 变量包含了我们想要注入组件的内容,现在,要构建这个组件,我们可以使用 Blade 指令 @component。

@component('alert')
Whoops! Something went wrong!
@endcomponent

有时,为组件定义多个插槽很有用。下面我们来编辑 alert 组件。

修改 resources/views/alert.blade.php 文件:


{
{ $title }}

{
{ $slot }}

现在,我们可以使用指令 @slot 注入内容到命名的插槽。任何不在 @slot 指令中的内容都会被传递到组件的 $slot 变量中。

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

这段代码的意思是通过组件名 alert 去查找对应的视图文件,装载到当前视图,然后通过组件中 @slot 定义的插槽内容去渲染插槽视图中对应的插槽位,如果组件没有为某个插槽位定义对应的插槽内容片段,则组件中的其他不在 @slot 片段中的内容将会用于渲染该插槽位,如果没有其他多余内容则对应插槽位为空。

传递额外数据到组件

有时,你可能需要传递额外数据到组件,出于这个原因,你可以传递数组数据作为第二个参数到 @component 指令,所有数据都会在组件模板中以变量方式生效:

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

数据显示

可以通过两个花括号包裹变量的形式,来显示传递到视图的数据。

比如,如果给出如下路由:

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

在视图文件中,显示 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 变量,例如:

这样显得很麻烦,有更简便的方式来实现这个功能,那就是 Blade 的 @json 指令:

Blade & Javascript 框架

由于很多 Javascript 框架也是用花括号来表示要显示在浏览器中的表达式,如 Vue,我们可以使用 @ 符号来告诉 Blade 引擎该表达式应该保持原生格式不作改动。比如:

Laravel


Hello, @{
{ name }}.

在本例中,@ 符号在编译阶段会被 Blade 移除,但是,{ { name }} 表达式将会保持不变,从而可以被 Javascript 框架正常渲染。

@verbatim指令

如果你在模板中有很大一部分篇幅显示 Javascript 变量,那么可以将这部分 HTML 封装在 @verbatim 指令中,这样就不需要在每个 Blade 输出表达式前加上 @ 前缀。

@verbatim


Hello, {
{ name }}.

@endverbatim

流程控制

除了模板继承和数据显示之外,Blade 还为常用的 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

循环语句

Blade 还提供了简单的指令用于处理 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__ 常量,因为它们会指向缓存视图的路径。

    渲染集合视图

    可以使用 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 "";
    });
    }
    /**
    * 在容器中注册绑定.
    *
    * @return void
    */
    public function register()
    {
    //
    }
    }

    在视图文件中使用该自定义指令:

    @datetime(1508888888)

    注:更新完 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

    推荐阅读
    • 如何提高PHP编程技能及推荐高级教程
      本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
    • 如何通过swoole加速laravel的问题?
      这篇文章主要介绍了关于如何使用swoole加速laravel,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下再来复习一下吧,导致php慢的各种因素中解析性语言的 ... [详细]
    • JVM(三)虚拟机栈 多合一总述
      虚拟机栈概述虚拟机栈出现背景:由于跨平台性的设计,Java的指令都是根据栈来设计的。不同CPU架构不同,所以不能设计为基于寄存器的跨平台的优点:指令集小,编译器容易实现,缺点是性能 ... [详细]
    • 后台获取视图对应的字符串
      1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
    • 猜字母游戏
      猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
    • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
    • PHP引用的概念和用法详解
      本文详细介绍了PHP中引用的概念和用法。引用是指不同的变量名访问同一个变量内容,类似于Unix文件系统中的hardlink。文章从引用的定义、作用、语法和注意事项等方面进行了解释和示例。同时还介绍了对未定义变量使用引用的情况,以及在函数和new运算符中使用引用的注意事项。 ... [详细]
    • 微信小程序导航跟随的实现方法
      本文介绍了在微信小程序中实现导航跟随的方法。通过设置导航的position属性和绑定滚动事件,可以实现页面向下滚动到导航位置时,导航固定在页面最上方;页面向上滚动到导航位置时,导航恢复到原始位置;点击导航可以平滑跳转到相应位置。代码示例也给出了具体实现方法。 ... [详细]
    • 本文介绍了一个Magento模块,其主要功能是实现前台用户利用表单给管理员发送邮件。通过阅读该模块的代码,可以了解到一些有关Magento的细节,例如如何获取系统标签id、如何使用Magento默认的提示信息以及如何使用smtp服务等。文章还提到了安装SMTP Pro插件的方法,并给出了前台页面的代码示例。 ... [详细]
    • 前端开发工程师必读书籍有哪些值得推荐?我们直接进入代码复杂版式设置,如下所示,先写些标签,源码在这个链接里面:https://codepen.io/Shadid ... [详细]
    • 1.imac睡眠快捷键是啥苹果电脑强制退出程序快捷键是Command+Option+Shift+Esc。苹果电脑 ... [详细]
    • android:EditText属性去边框EditText继承关系:View--TextView--EditTextEditText的属性很多,这里介绍几个:android:h ... [详细]
    • 依赖注入_php 依赖注入容器
      篇首语:本文由编程笔记#小编为大家整理,主要介绍了php依赖注入容器相关的知识,希望对你有一定的参考价值。原文: http://blog.csdn.net/r ... [详细]
    • 根据自己的PHP版本号选出对应的laravel版本Laravel5.1PHP对应的版本5.5.9Laravel5.2PHP对应的版本5.5.9Laravel5.3PHP对应 ... [详细]
    • 带添加按钮的GridView,item的删除事件
      先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
    author-avatar
    木木爱上林
    这个家伙很懒,什么也没留下!
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有