Laravel之视图和Blade模板引擎
一.视图
1.视图文件存放在resources/views目录
2.视图载入及传参
return view('greeting', ['name' => 'James']);
还可以通过with 方法添加独立的数据片段到视图
return 还可以通过with 方法添加独立的数据片段到视图
return view('greeting')->with('name', 'john');
也可以使用compact
return view('greeting')->compact('name','age');
3.判断视图是否存在
if (view()->exists('emails.customer')) { }
4.在视图间共享数据
有时候我们需要在所有视图之间共享数据片段,这时候可以使用视图工厂的share 方法,通常,需要在服务提供者的boot 方法中调用share 方法,你可以将其添加到AppServiceProvider 或生成独立的服务提供者来存放它们:
/** * 启动所有应用服务 * * @return void */ public function boot() { view()->share('key', 'value'); }
二.视图Composer
视图 Composers 是当视图被渲染时的回调或类方法。如果你有一些数据要在视图每次渲染时都做绑定,可以使用视图 composer 将逻辑组织到一个单独的地方。
首先要在服务提供者中注册视图 Composer,我们将会使用帮助函数view 来访问Illuminate\Contracts\View\Factory 的底层实现,记住,Laravel 不会包含默认的视图 Composers 目录,我们可以按照自己的喜好组织其位置,例如可以创建一个App\Http\ViewComposers目录,新建一个Viewtest类
<?php namespace App\Http\ViewComposers; use Illuminate\Contracts\View\View; /** * Created by PhpStorm. * User: guo * Date: 2017/5/30 * Time: 16:17 */ class Viewtest { public function compose(View $view) { $view->with('count', '1000'); } }
根目录下的Providers目录新建ComposerServiceProvider类,代码如下
<?php /** * Created by PhpStorm. * User: guo * Date: 2017/5/30 * Time: 16:13 */ namespace App\Providers; use Illuminate\Support\ServiceProvider; class ComposerServiceProvider extends ServiceProvider { /** * 在容器中注册绑定 */ public function boot() { view()->composer(['test.hi'], 'App\Http\ViewComposers\Viewtest'); } /** * Register the service provider. * * @return void */ public function register() { } }
在config下的app.php中的providers中注册该服务
App\Providers\ComposerServiceProvider::class,
这样,在渲染模板test/hi.blade.php时将有一个变量$count
可以修改ComposerServiceProvider中的boot方法,将composer作用到多个视图中
view()->composer( ['test.hi','test.hi2'], 'App\Http\ViewComposers\Viewtest' );
甚至可以使用通配符
view()->composer( '*', 'App\Http\ViewComposers\Viewtest' );
当然你也可以不用新建服务,直接使用AppServiceProvider
public function boot() { view()->composer(['test.hi'], 'Youxin\Http\ViewComposers\Viewtest'); //或者使用一个闭包 view()->composer('*', function($view) { $view->with('user', array('name'=>'john', 'age'=>18)); }); }
四,视图创建器
视图创建器和视图 composer 非常类似,不同之处在于前者在视图实例化之后立即失效而不是等到视图即将渲染。使用create 方法注册一个视图创建器
view()->creator('profile', 'App\Http\ViewCreators\ProfileCreator');
五.模板Blade引擎
1.模板继承 @extends('...') 2.定义一个内容片断 @yield('...') 3.替换内容片断 @section('...') @endsection 4.扩展 @extends('layouts.master') @section('title', 'Page Title') @section('sidebar') @parent <p>This is appended to the master sidebar.</p> @endsection @section('content') <p>This is my body content.</p> @endsection sidebar 片段使用@parent 指令来追加(而非覆盖)内容到布局中 sidebar, @parent 指令在视图渲染时将会被布局中的内容替换 5.和原生 PHP 视图一样,Blade 视图可以通过view 方法直接从路由中返回 Route::get('blade', function () { return view('child'); }); 6.数据显示: Route::get('greeting', function () { return view('welcome', ['name' => 'Samantha']); }); 模板中: Hello, {{ $name }}. 在模板中输出函数 The current UNIX timestamp is {{ time() }}. 注意:Blade 的{{}} 语句已经经过 PHP 的htmlentities 函数处理以避免 XSS 攻击,如果不想数据被htmlentities处理,可以使用 {!! $name !!} 7.避免和javascript框架的混淆 可以使用@符号来告诉 Blade 渲染引擎该表达式应该保持原生格式不作改动 Hello, @{{ name }}. 在本例中, @ 符将会被 Blade 移除,然而, {{ name }} 表达式将会保持不变,避免被laravel框架渲染 8.默认值 {{ $name or 'Default' }} 如果$name 变量存在,其值将会显示,否则将会显示“Default” 9.流程控制 @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 10.循环 @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 11.包含子视图 Blade 的@include 指令允许你很简单的在一个视图中包含另一个 Blade 视图,所有父级视图中变量在被包含的子视图中依然有效 <div> @include('shared.errors') <form> <!-- Form Contents --> </form> </div> 尽管被包含的视图继承所有父视图中的数据,你还可以传递额外参数到被包含的视图 @include('view.name', ['some' => 'data']) 12.注释 Blade 还允许你在视图中定义注释,然而,不同于 HTML 注释,Blade 注释并不会包含到 HTML 中被返回: {{-- This comment will not be present in the rendered HTML --}}
五.服务注入
@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() { // } }