1、简介 blade 是laravel 提供的一个非常简单但很强大的模板引擎,不同于其他流行的php 模板引擎,blade 在视图中并不约束你使用 php 原生代码。所有的 blade 视图都会被编译成原生 php 代码并缓存起来直到被修改,这意味着对应用的性能而言 blade 基本上是零开销。blade 视图文件使用 .blade.php文件扩展并存放在 resources/views目录下。
2、模板继承 定义 布局 使用 blade 的两个最大优点是模板继承和切片,开始之前让我们先看一个例子。首先,我们检测一个“主”页面布局,由于大多数 web 应用在不同页面中使用同一个布局,可以很方便的将这个布局定义为一个单独的 blade 页面:
app name - @yield('title') @section('sidebar') this is the master sidebar. @show @yield('content')
正如你所看到的,该文件包含典型的html 标记,然而,注意 @section和 @yield指令,前者正如其名字所暗示的,定义了一个内容的片段,而后者用于显示给定片段的内容。
现在我们已经为应用定义了一个布局,接下来让我们定义继承该布局的子页面吧。
扩展布局 定义子页面的时候,可以使用 blade 的 @extends指令来指定子页面所继承的布局,继承一个 blade 布局的视图将会使用 @section指令注入内容到布局的片段中,记住,如上面例子所示,这些片段的内容将会显示在布局中使用 @yield的地方:
@extends('layouts.master')@section('title', 'page title')@section('sidebar') @parent this is appended to the master sidebar.
@endsection@section('content') this is my body content.
@endsection
在本例中, sidebar片段使用 @parent指令来追加(而非覆盖)内容到布局中 sidebar, @parent指令在视图渲染时将会被布局中的内容替换。
当然,和原生 php 视图一样,blade 视图可以通过 view方法直接从路由中返回:
route::get('blade', function () { return view('child');});
3、数据显示 可以通过两个花括号包裹变量来显示传递到视图的数据,比如,如果给出如下路由:
route::get('greeting', function () { return view('welcome', ['name' => 'samantha']);});
那么可以通过如下方式显示 name变量的内容:
hello, {{ $name }}.
当然,不限制显示到视图中的变量内容,你还可以输出任何 php 函数,实际上,可以将任何 php 代码放到 blade 模板语句中:
the current unix timestamp is {{ time() }}.
注:blade 的 {{}}语句已经经过 php 的 htmlentities函数处理以避免xss 攻击。
blade & javascript 框架 由于很多 javascript 框架也是用花括号来表示要显示在浏览器中的表达式,可以使用 @符号来告诉 blade 渲染引擎该表达式应该保持原生格式不作改动。比如:
laravelhello, @{{ name }}.
在本例中, @符将会被 blade 移除,然而, {{ name }}表达式将会保持不变,避免被 javascript 框架渲染。
输出存在的数据 有时候你想要输出一个变量,但是不确定该变量是否被设置,我们可以通过如下 php 代码:
{{ isset($name) ? $name : 'default' }}
除了使用三元运算符,blade 还提供了更简单的方式:
{{ $name or 'default' }}
在本例中,如果 $name变量存在,其值将会显示,否则将会显示“default”。
显示原生数据 默认情况下,blade 的 {{ }}语句已经通过 php 的 htmlentities函数处理以避免 xss 攻击,如果你不想要数据被处理,可以使用如下语法:
hello, {!! $name !!}.
注:输出用户提供的内容时要当心,对用户提供的内容总是要使用双花括号包裹以避免直接输出 html 代码。
4、 流程控制 除了模板继承和数据显示之外,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 还提供了简单指令处理 php 支持的循环结构,同样,这些指令函数和 php 的一样:
@for ($i = 0; $i id }}
@endforeach@forelse ($users as $user) {{ $user->name }} @empty no users
@endforelse@while (true) i'm looping forever.
@endwhile
包含子视图 blade 的 @include指令允许你很简单的在一个视图中包含另一个 blade 视图,所有父级视图中变量在被包含的子视图中依然有效:
@include('shared.errors')
尽管被包含的视图继承所有父视图中的数据,你还可以传递额外参数到被包含的视图:
@include('view.name', ['some' => 'data'])
注:不要在 blade 视图中使用 __dir__和 __file__常量,因为它们会指向缓存视图的路径。
为集合渲染视图 你可以使用 blade 的 @each指令通过一行代码循环引入多个局部视图:
@each('view.name', $jobs, 'job')
该指令的第一个参数是数组或集合中每个元素要渲染的局部视图,第二个参数是你希望迭代的数组或集合,第三个参数是要分配给当前视图的变量名。举个例子,如果你要迭代一个 jobs数组,通常你需要在局部视图中访问 $job变量。
你还可以传递第四个参数到 @each指令,该参数用于指定给定数组为空时渲染的视图:
@each('view.name', $jobs, 'job', 'view.empty')
注释 blade 还允许你在视图中定义注释,然而,不同于 html 注释,blade 注释并不会包含到 html 中被返回:
{{-- this comment will not be present in the rendered html --}}
5、服务注入 @inject指令可以用于从服务容器中获取服务,传递给 @inject的第一个参数是服务将要被放置到的变量名,第二个参数是要解析的服务类名或接口名:
@inject('metrics', 'app\services\metricsservice') monthly revenue: {{ $metrics->monthlyrevenue() }}.
6、扩展 blade blade 甚至还允许你自定义指令,可以使用 directive方法来注册一个指令。当 blade 编译器遇到该指令,将会传入参数并调用提供的回调。
下面的例子创建了一个 @datetime($var)指令格式化给定的 $var:
; }); } /** * 在容器中注册绑定. * * @return void */ public function register() { // }}
正如你所看到的,laravel 的辅助函数 with被用在该指令中, with方法简单返回给定的对象/值,允许方法链。最终该指令生成的 php 代码如下:
format('m/d/y h:i'); ?>