Blade 是 Laravel 提供的一个既简单又强大的模板引擎。php
和其余流行的 PHP 模板引擎不同,Blade 并不限制你在视图中使用原生 PHP 代码。全部 Blade 视图文件都将被编译成原生的 PHP 代码并缓存起来,除非它被修改,不然不会从新编译,这就意味着 Blade 基本上不会给你的应用增长任何额外负担。css
Blade 视图文件使用 .blade.php 扩展名,通常被存放在 resources/views 目录。html
像以前实验中的 welcome.blade.php 和 home.blade.php 等都是 blade 模板文件,只是咱们以前尚未用到模板的功能,在本次实验咱们将体验强大的 blade 模板功能。java
2、模板继承web
模板继承是最经常使用的一个 blade 模板功能。express
平时访问网站的时候,能够发现,通常一个网站的不一样页面都应该是相似的,好比都有相同的导航栏和底部信息栏,或者都有相同的左侧菜单栏。数组
咱们在写代码的时候不可能每一个页面都要把重复的东西写一遍,这样不只效率低下,还不易维护,因此就有了模板继承。浏览器
下面咱们经过一个很简单的例子来使用模板继承。缓存
首先,建立相关路由: app/Http/routes.php
ruby
<?php
//home page Route::get('/', 'StaticPagesController@home')->name('home'); //about page Route::get('/about', 'StaticPagesController@about')->name('about');
而后,使用 artisan 建立控制器:
cd ~/Code/myweb php artisan make:controller StaticPagesController --plain
打开控制器,建立相应方法:
app/Http/Controllers/StaticPagesController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; class StaticPagesController extends Controller { public function home() { return view('home'); } public function about() { return view('about'); } }
而后,在 resources/views 目录下建立对应的视图文件 home.blade.php
和about.blade.php
打开这两个视图文件,分别输入如下代码:
resources/views/home.blade.php
<!DOCTYPE html> <html> <head> <title>Home</title> </head> <body> <h1>Home</h1> <p>Welcome to My web</p> </body> </html> resources/views/about.blade.php <!DOCTYPE html> <html> <head> <title>About</title> </head> <body> <h1>About</h1> <p>This is my first Laravel web</p> <p>Author: SadCreeper</p> <!-- 能够更改成你本身的信息 --> </body> </html>
而后,打开浏览器,输入 localhost 和 localhost/about 能够看到咱们建立的两个视图。
可是到如今为止,咱们尚未使用 blade 模板继承,能够看到两个视图中有不少的重复代码,下面建立一个基础视图,其余的全部视图都将继承这个基础视图。
在 resources/views 目录下新建一个目录 layouts 而后在 resources/views/layouts 目录下新建一个视图文件 app.blade.php。
打开这个 app.blade.php 加入以下代码:
resources/views/layouts/app.blade.php
<!DOCTYPE html> <html> <head> <title>Myweb</title> </head> <body> @yield('content') </body> </html>
而后修改 home.blade.php 和 about.blade.php:
resources/views/home.blade.php
@extends('layouts.app')
@section('content')
<h1>Home</h1> <p>Welcome to My web</p> @endsection resources/views/about.blade.php @extends('layouts.app') @section('content') <h1>About</h1> <p>This is my first Laravel web</p> <p>Author: SadCreeper</p> <!-- 能够更改成你本身的信息 --> @endsection
其中顶部代码:
@extends('layouts.app')
就是表示当前视图继承自 layouts 文件夹下的 app.blade.php 视图。
而后用下面这种方式就能够把 section(‘content’) 中包含的内容放到被继承的视图 app.blade.php 中的 yield(‘content’) 部分。
@section('content') // @endsection
使用模板继承后,你若是想对网站进行一些基础的公用代码的修改时,就能够修改 app.blade.php。
下面咱们给这个基础视图添加一个很是简单的顶部导航栏和底部信息栏。
resources/views/layouts/app.blade.php
<!DOCTYPE html> <html> <head> <title>Myweb</title> </head> <body style="margin:0;padding:0;"> <!-- header --> <div style="padding:10px 50px 10px 50px;border-bottom: 1px solid #eeeeee;"> <div style="display:inline-block;"> <a href="{{ route('home') }}"><h2>Myweb</h2></a> </div> <div style="display:inline-block;margin-left:20px;"> <a href="{{ route('about') }}">about</a> </div> </div> <div style="text-align:center;"> @yield('content') </div> <!-- footer --> <div style="padding:10px 50px 10px 50px;"> <p>contact me : 1234567</p> </div> </body> </html>
在本教程中,我把样式写到了 style 里,是为了简化流程,一般来讲,样式代码应该尽可能写到 css 文件中,以方便复用和维护。
此时咱们访问localhost 和 localhost/about 均可以看到完整的包含导航栏和底部信息栏的视图。
你可使用 Blade 的 @include 命令来引入一个已存在的视图,全部在父视图的可用变量在被引入的视图中都是可用的。
<div> @include('shared.errors') <form> <!-- Form Contents --> </form> </div>
尽管被引入的视图会继承父视图中的全部数据,你也能够经过传递额外的数组数据至被引入的页面:
@include('view.name', ['some' => 'data'])
下面咱们建立一个子视图,用来显示网站做者信息,你能够在网站上任何想显示做者信息的地方引用这个视图。
在 resources/views 目录下新建一个文件夹 shared 而后在 resources/views/shared 目录下新建一个文件 author.blade.php 打开该文件。
resources/views/shared/author.blade.php
<div style="width:200px;margin:20px auto 20px auto;padding:20px;border:1px solid black;"> <h3>Author</h3> <p>name : SadCreeper</p> <p>age : 22</p> <p>Tel : 150-XXXX-XXXX</p> </div>
而后在 resources/views/about.blade.php 中引用该子视图: resources/views/about.blade.php
@extends('layouts.app') @section('content') <h1>About</h1> <p>This is my first Laravel web</p> @include('shared.author') @endsection
而后访问localhost/about 看下效果:
此时若是你想在任何地方显示这个子视图,只须要在相应位置加入下面一行代码便可~
@include('shared.author')
你可使用 「中括号」 包住变量以显示传递至 Blade 视图的数据。如假设你有下面这样一个路由:
Route::get('greeting', function () { return view('welcome', ['name' => 'Samantha']); });
你在视图文件中能够像这样显示 name 变量的内容:
Hello, {{ $name }}.
你也能够显示 PHP 函数的结果。事实上,你能够在 Blade 中显示任意的 PHP 代码:
The current UNIX timestamp is {{ time() }}.
有时候你可能想要输出一个变量,可是你并不肯定这个变量是否已经被定义,咱们能够这样:
{{ $name or 'Default' }}
在这个例子中,若是 $name 变量存在,它的值将被显示出来。可是,若是它不存在,则会显示 Default 。
在默认状况下,Blade 模板中的 {{ }} 表达式将会自动调用 PHP htmlentities 函数来转义数据以免 XSS 的攻击。若是你不想你的数据被转义,你可使用下面的语法:
Hello, {!! $name !!}.
除了“模板继承” 与 “数据显示”的功能之外,Blade 也给通常的 PHP 结构控制语句提供了方便的缩写,好比条件表达式和循环语句。这些缩写提供了更为清晰简明的方式来使用 PHP 的控制结构,并且还保持与 PHP 语句的类似性。
你能够经过 @if , @elseif , @else 及 @endif 指令构建 if 表达式,这些命令的功能等同于在 PHP 中的语法:
@if (count($records) === 1) 我有一条记录! @elseif (count($records) > 1) 我有多条记录! @else 我没有任何记录! @endif
为了方便,Blade 也提供了一个 @unless 命令:
@unless (Auth::check())
你还没有登陆。
@endunless
@for ($i = 0; $i < 10; $i++) 目前的值为 {{ $i }} @endfor @foreach ($users as $user) <p>此用户为 {{ $user->id }}</p> @endforeach @forelse ($users as $user) <li>{{ $user->name }}</li> @empty <p>没有用户</p> @endforelse @while (true) <p>我永远都在跑循环。</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 来获取循环中有价值的信息,好比当前循环的索引,当前循环是否是首次迭代,又或者当前循环是否是最后一次迭代。
@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属性来获取父循环中的loop变量的parent属性来获取父循环中的loop 变量:
@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 | 当在嵌套的循环内时,能够访问到父循环中的 $loop变量。 |
Blade 也容许在页面中定义注释,然而,跟 HTML 的注释不一样的是,Blade 注释不会被包含在应用程序返回的 HTML 内:
{{-- 此注释将不会出如今渲染后的 HTML --}}
Blade的@include指令容许你很简单的在一个视图中包含另外一个Blade视图,全部父级视图中变量在被包含的子视图中依然有效:
<div> @include('shared.errors') <form> <!-- Form Contents --> </form> </div>
尽管被包含的视图继承全部父视图中的数据,你还能够传递额外参数到被包含的视图:
@include('view.name', ['some' => 'data'])
@inject指令能够用于从服务容器中获取服务,传递给@inject的第一个参数是服务将要被放置到的变量名,第二个参数是要解析的服务类名或接口名:
@inject('metrics', 'App\Services\MetricsService') <div> Monthly Revenue: {{ $metrics->monthlyRevenue() }}. </div>
六、扩展Blade
Blade甚至还容许你自定义指令,可使用directive方法来注册一个指令。当Blade编译器遇到该指令,将会传入参数并调用提供的回调。
下面的例子建立了一个@datetime($var)指令:
<?php namespace App\Providers; use 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 with{$expression}->format('m/d/Y H:i'); ?>"; }); } /** * 在容器中注册绑定. * * @return void */ public function register() { // } }
正如你所看到的,Laravel的帮助函数with被用在该指令中,with方法简单返回给定的对象/值,容许方法链。最终该指令生成的PHP代码以下:
<?php echo with($var)->format('m/d/Y H:i'); ?>
用于封装和继承用的,仍是比较实用的!!!