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.mzph.cn/news/271086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目管理基础:系统切换相关知识笔记

1、系统试运行主要任务对新系统进行初始化、补录各种原始数据记录记录系统运行过程中的数据和状况核对新旧系统输出结果是否正确对实际系统的输入方式进行考察主要包括是否方便、效率、可靠性、误操作保护等方面。对系统实际运行、响应速度进行实际测试&#xff0c;确定是否满足…

sql 分组统计_leetcode-sql面试题十七篇精讲合集

这可能是全网最干货的sql讲解系列文章。全系列共十七讲。做了大量的知识点的拓展&#xff0c;涵盖了sql的方方面面。欢迎关注点赞收藏&#xff0c;正在整理三年数据分析的点点滴滴。包括Excel、python、sql、power BI、各种分析模型框架。保证输出最干的干货。涉及知识点包括&a…

项目管理基础:系统维护相关知识笔记

1、系统的可维护性系统的可维护性就是项目维护人员理解、改正、改动和改进该软件的难易程度。提高系统的可维护性是开发软件吸引所有步骤的关键目的&#xff0c;系统能否被很好地维护&#xff0c;可用系统的可维护性这一指标来衡量。1.1 系统可维护性的评价指标可理解性&#x…

一个栈桢对应着一个方法

一个栈桢对应着一个方法

程序员幽默:39个奇葩代码注释,每一个都能笑抽

1. 只有上帝知道//我写这一行的时候&#xff0c;只有上帝和我知道我在写什么//现在&#xff0c;只有上帝知道了2. 相隔时空的diss//somedev1 - 6/7/02 添加对登录屏幕的暂时追踪功能//somedev2 - 5/22/07 暂时个屁&#xff08;仿佛看到两个程序员相隔时空的diss&#xff09;3…

栈出现的异常和设置栈的大小-Xss

异常 java.lang.StackOverflowError 看下面的例子&#xff0c;默认的栈内存 设置栈内存 使用参数-Xss大小来设置栈的大小

项目管理基础:系统评价相关知识

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 …

数据库设计:数据库应用系统的生命周期

数据库应用系统的生命周期可以划分为&#xff1a;数据库规划、需求描述与分析、数据库与应用程序设计、数据库设计实现、数据库测试、数据库运维。1、数据库规划 数据库规划是创建数据库应用系统的第一步&#xff0c;也是数据库应用系统的任务描述和目标的明确。数据库规划的内…

从零开始,做一个NodeJS博客(四):服务器渲染页面与Pjax

标签&#xff1a; NodeJS 0 一个星期没更新了 一直在忙着重构代码&#xff0c;以及解决重构后出现的各种bug 现在CSS也有一点了&#xff0c;是时候把遇到的各种坑盘点一下了 1 听歌排行 API 修复与重构 1.1 修复 在加载云音乐听歌排行的时候&#xff0c;有时会出现一个奇怪的…

java 简单事件的使用,如何正确的使用Java事件通知(1)

如何正确的使用Java事件通知(1)通过实现观察者模式来提供 Java 事件通知(Java event notification)似乎不是件什么难事儿&#xff0c;但这过程中也很容易就掉进一些陷阱。本文介绍了我自己在各种情形下&#xff0c;不小心制造的一些常见错误。Java 事件通知让我们从一个最简单的…

Java 自动装箱与拆箱

Java 自动装箱与拆箱 装箱就是自动将基本数据类型转换为包装器类型&#xff08;int–>Integer&#xff09;&#xff1b;调用方法&#xff1a;Integer 的 valueOf(int) 方法 拆箱就是自动将包装器类型转换为基本数据类型&#xff08;Integer–>int&#xff09;。调用方法…

基本系统设备感叹号_win7系统网络图标显示感叹号的问题

有系统之家的小伙伴&#xff0c;在使用win764位纯净版系统上网的时候&#xff0c;出现网络图标显示感叹号的问题。这种问题我们可以通过在网络检测修复中进行自行检测。或者是检查一下是不是硬件设备的问题。详细解决步骤就来看下系统哥小编是怎么做的吧~win7 64系统无法上网显…

硬件编程:STM32串口发送数据和接收数据方式总结!

串口发送数据1、串口发送数据最直接的方式就是标准调用库函数 。void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);第一个参数是发送的串口号&#xff0c;第二个参数是要发送的数据&#xff0c;但是用过的朋友应该觉得不好用&#xff0c;一次只能发送单个字符&#…

Java编程题修院子,了解java虚拟机—JVM相关参数设置(2)

1. JVM相关参数设置JVM相关配置-XX:PrintGC两次次YoungGC&#xff0c;两次FullGC。-XX:PrintGCDetails打印GC时的内存&#xff0c;并且在程序结束时打印堆内存使用情况-XX:PrintHeapAtGC每次GC时会分别打印回收前与回收后堆信息-XX:PrintGCTimeStamps选择打印GC的方式后&…

此异常最初是在此调用堆栈中引发的:_【8】进大厂必须掌握的面试题Java面试异常和线程...

点击上方“全栈程序员社区”&#xff0c;星标公众号重磅干货&#xff0c;第一时间送达Q1。错误和异常有什么区别&#xff1f;错误是在运行时发生的不可恢复的情况。如OutOfMemory错误。这些JVM错误无法在运行时修复。尽管可以在catch块中捕获错误&#xff0c;但是应用程序的执行…

高仿带感魔性病毒源码+成品(最近很火的)

高仿带感魔性病毒源码成品&#xff08;最近很火的&#xff09;娱乐使用。没破坏性 会改壁纸和打乱桌面图标顺序 自己改回来就好 演示地址&#xff1a; 下载地址&#xff1a;链接: http://pan.baidu.com/s/1dF2ZlU5 密码: m95p转载于:https://www.cnblogs.com/blogwy/p/5804711.…

数据库设计:数据库设计的基本步骤介绍

数据库设计主要包括用户需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施阶段、数据库运行和维护阶段等六个阶段。1、用户需求分析 数据库设计人员采用相应的辅助工具对应用对象的功能、性能、限制等要求进行科学实际的分析。2、概念结构设计 概念结构设计主要…