Blade Template


Blade Template

Introduction

Blade is a simple yet powerful template engine provided by Laravel. Unlike other popular PHP template engines, Blade does not restrict you from using native PHP code in your views. All Blade view files will be compiled into native PHP code and cached, and will not be recompiled unless it is modified, which means that Blade will basically not add any burden to your application. Blade view files use .blade.php as the file extension and are stored in the resources/views directory.

Template inheritance

Define layout

The two main advantages of Blade are template inheritance and blocks. To get started, let's start with a simple example. First, let's look at a "main" page layout. Since most web applications use the same layout across different pages, it's easy to define a single Blade layout view:

<!-- 保存在  resources/views/layouts/app.blade.php 文件中 -->
<html>   
 <head>      
   <title>App Name - @yield('title')</title>    
 </head>   
 <body>
    @section('sidebar')
     This is the master sidebar.
     @show       
     <div class="container">
     @yield('content')       
      </div>   
  </body>
</html>

As you can see, this file contains typical HTML syntax. However, please note the @section and @yield directives. The @section directive defines a part of the view, and the @yield directive is used to display the content of the specified part.

Now that we have defined the layout of this application, we define a subpage that inherits this layout.

##Extended layout

When defining a subview, use Blade's

@extends Directive specifies the view that the subview should "inherit" from. Views that extend Blade layout can inject content into layout sections using the @section directive. As shown in the previous example, the content of these fragments will be displayed in the layout controlled by the @yield directive:

<!-- 保存在 resources/views/child.blade.php 中 -->
@extends('layouts.app')
@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

In this example,

sidebar Fragments use the @parent directive to append (rather than overwrite) content to the layout's sidebar. When the view is rendered, the @parent directives will be replaced by the content in the layout.

{tip} Contrary to the previous example, here the

sidebar fragment ends with @endsection instead of @show. The @endsection directive only defines one section, while @show yields this section immediately while defining it.

Blade view can use the global

view assistant to return from routing:

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

Components & Slots

Components and slots provide similar benefits to fragments and layouts; however, the mental model of components and slots is easier to understand. Let's first look at a reusable "alert" component that we want to reuse in our application:

<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">   
 {{ $slot }}
</div>

{{ $slot }} The variable will contain the value we want to inject into The content of the component. Now, we build this component using Blade's @component directive:

@component('alert') 
<strong>Whoops!</strong> Something went wrong!
@endcomponent

Sometimes it is useful to define multiple slots for a component. Modify the alert component to allow it to inject "title". Named slots can be displayed via their matching "echo" variable:

<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">  
  <div class="alert-title">{{ $title }}</div>    
  {{ $slot }}
 </div>

We can now inject content into named slots using the

@slot directive. Content not within the @slot directive will be passed to the $slot variable in the component:

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

Passing additional data to the component

Sometimes you may need to pass additional data to the component. In this case, the containing data can be organized into an array as the second parameter of the @component directive. All data will be provided to the component template as changes:

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

Alias ​​the components

If the components are stored in a subdirectory, you may wish to give them an alias for easy access. For example, if a Blade component is stored in resources/views/components/alert.blade.php, you can use the component method to components.alert## The alias for # is named alert. . Normally, this process would be done in the boot method of AppServiceProvider:

use Illuminate\Support\Facades\Blade;
Blade::component('components.alert', 'alert');

Once the component has an alias, it can be rendered using a single directive:

@alert(['type' => 'danger'])
    You are not allowed to access this resource!@endalert

If there are no additional slots, you can also omit the component parameter:

@alert
    You are not allowed to access this resource!@endalert

##Display data

The data passed to the Blade view can be displayed through variables wrapped in double curly braces. For example, given the following route:

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

, you can use the

name

variable to display its content:

Hello, {{ $name }}.

{tip} Blade
{{ }}

Statements are automatically passed through PHP's htmlspecialchars function to prevent XSS attacks.

Not limited to displaying the contents of variables passed to the view, you can also display the results of any PHP function. In fact, you can put any PHP code you want in Blade's echo statement:
The current UNIX timestamp is {{ time() }}.

Display unescaped characters

By default, Blade The

{{ }}

statement is automatically passed through PHP's htmlspecialchars function to prevent XSS attacks. If you do not want the data to be escaped, you can use the following syntax:

Hello, {!! $name !!}.

{note} Use caution when echoing user-supplied content from your application. When displaying user-supplied data, it is necessary to always use double curly brace syntax escaping to protect against XSS attacks.

Rendering JSON

Sometimes, in order to initialize a JavaScript variable, you may pass a data to the view and render it into JSON:

<script>  
  var app = <?php echo json_encode($array); ?>;
</script>

However, you can use the

@json

Blade directive instead of manually calling the json_encode function:

<script> 
   var app = @json($array);
</script>

HTML Entity Encoding

By default, Blade (and Laravel's

e

helpers) will double-encode HTML entities. If you want to disable double encoding, you can call the Blade::withoutDoubleEncoding method in boot of AppServiceProvider:

<?php
   namespace App\Providers;
   use Illuminate\Support\Facades\Blade;
   use Illuminate\Support\ServiceProvider;
   class AppServiceProvider extends ServiceProvider{   
    /**
     * 引导任意应用服务。
     *
     * @return void
     */  
   public function boot()   
    {       
     Blade::withoutDoubleEncoding();   
     }
  }

Blade & JavaScript Framework

Since many JavaScript frameworks also use curly braces to indicate that a given expression will be displayed in the browser, you can use the @ symbol to notify the Blade rendering engine of a certain The expression should remain unchanged. An example is as follows:

<h1>Laravel</h1>Hello, @{{ name }}.

In this example, the @ symbol will be deleted by Blade; in the Blade engine, the {{ name }} expression will remain unchanged, Instead, the JavaScript engine will render the expression.

@verbatim Commands

If you want to use JavaScript variables in a large template, you can wrap the HTML in @verbatim directive, so there is no need to add the @ symbol to each Blade echo statement:

@verbatim   
 <div class="container">
        Hello, {{ name }}.  
  </div>@endverbatim

Control Structure

In addition to template inheritance and data display, Blade also provides convenient shortcuts for PHP control structures such as branching and looping. These shortcuts provide a clean, simple way to work with PHP control structures while maintaining similarity to their counterparts in PHP.

##If statement

can use

@if, @elseif## The #, @else, and @endif directives construct if statements. These directives function identically to the corresponding PHP directives:

@if (count($records) === 1)  
  I have one record!
@elseif (count($records) > 1)   
   I have multiple records!
@else  
    I don't have any records!
 @endif
For convenience, Blade also provides the

@unless

directive:

@unless (Auth::check())
    You are not signed in.@endunless
In addition to the conditional directives already discussed, The

@isset

and @empty directives can be used as shortcuts to their corresponding PHP functions:

@isset($records) 
   // $records 被定义且不是 null...
@endisset

@empty($records)   
 // $records 为空...
@endempty

Authentication directives
## The

#@auth

and

@guest directives can be used to quickly determine whether the current user is authenticated or a guest:

@auth    // 此用户身份已验证...@endauth
@guest    // 此用户身份未验证...@endguest
can be used if needed@auth

and

@guest directives specify the identity that should be verified:

@auth('admin')    // 此用户身份已验证...@endauth
@guest('admin')    // 此用户身份未验证...@endguest

Fragment directives
can be used

@hasSection

The command checks whether the section has content:

@hasSection('navigation')
   <div class="pull-right">
 @yield('navigation')   
    </div>  
    <div class="clearfix">
    </div>
 @endif

##Switch command

can be used
@switch

,

@case

, @break, @default and @endswitch instructions construct switch statements:

@switch($i)
    @case(1)
        First case...
        @break
    @case(2)
        Second case...
        @break
    @default   
        Default case...@endswitch

Loops

In addition to branch statements, Blade also provides simplified instructions that are the same as PHP's loop structure. The functions of these instructions are also the same as the corresponding PHP instructions:

@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

{tip} You can use loop variables in the loop to obtain the evaluable information of the loop, such as it is currently in the loop In the first iteration or the last iteration:

In a loop, you can also terminate the loop or pass through this iteration:

@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif    
     <li>{{ $user->name }}</li>
    @if ($user->number == 5)
        @break
    @endif@endforeach

You can also declare a conditional in one line Instruction:

@foreach ($users as $user)
    @continue($user->type == 1)   
     <li>{{ $user->name }}</li>
    @break($user->number == 5)
  @endforeach

Loop variable

During the loop, there is an available $ in the loop body loop variable. This variable provides access to a small amount of useful information such as the index of the current loop and whether it is the first or last 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

In nested loops, you can use parent Properties access the parent loop's $loop variable:

@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 The variable also contains several other useful properties:

The index of the current iteration (counting from 0). Current loop iteration (counted from 1). The number of remaining iterations in the loop. The total number of array elements being iterated. is the first iteration of the loop. is the last iteration of the loop. The nesting depth level of the current iteration. In nested loops, the loop variable of the parent loop

Annotations

Blade also allows annotations to be defined in views. However, unlike HTML comments, Blade comments are not included in the HTML returned to the application:

{{-- This comment will not be present in the rendered HTML --}}

PHP

In some cases, it is useful to embed PHP code in the view. You can use the @php directive in a template to execute native PHP code blocks:

@php    //@endphp

{tip} Although Blade provides this feature, frequent use means that it is embedded in the template. Too much logic.

##Form

##CSRF field

As long as an HTML form is defined in the application, the hidden CSRF token field must be included in the form so that the CSRF protection middleware can verify the request. You can use Blade's

@csrf

command to generate the token field:

<form method="POST" action="/profile">
    @csrf   
    ...
</form>

##Method field
HTML forms cannot issue

PUT

,

PATCH and DELETE requests and need to add hidden _method fields to imitate these HTTP verbs. Blade's @method command can help you create this domain:

<form action="/foo/bar" method="POST">
    @method('PUT')    
    ...
</form>

Introduce subviews
Blade's

@include

directive allows you to import Blade views from other views. All variables available in the parent view will be available in the introduced view:

<div>
    @include('shared.errors')   
   <form>       
    <!-- Form Contents -->    
  </form>
</div>
The included view will not only inherit all available data from the parent view, but can also pass additional data to the included view in the form of an array. Data:
@include('view.name', ['some' => 'data'])

Laravel will throw an error if passed to

@include

a view that does not exist. To include a view whose existence cannot be determined, use the

@includeIf directive:

@includeIf('view.name', ['some' => 'data'])
To include a view that depends on a given Boolean condition, use @ includeWhen

directive:

@includeWhen($boolean, 'view.name', ['some' => 'data'])
To include the first existing view in a given view array, use the includeFirst

directive:

@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
{note } You should try to avoid using the

__DIR__
and

__FILE__ magic constants in Blade views because they will point to the location of the compiled view in the cache.

Give aliases to included views

If your Blade included views are stored in subdirectories, you may want to give them aliases that are easily accessible. For example, a Blade view content with the following content is stored in the resources/views/includes/input.blade.php file:

<input type="{{ $type ?? 'text' }}">

You can use include The method is includes.input and gives an alias called input. Typically, this is done in the boot method of AppServiceProvider:

use Illuminate\Support\Facades\Blade;
Blade::include('includes.input', 'input');

Once the contained view has an alias, it can be rendered using the alias just like the Blade directive :

@input(['type' => 'email'])

Rendering a view for a collection

You can use Blade's @each command in Combining loops and includes in one line:

@each('view.name', $jobs, 'job')

The first parameter is a view fragment that renders each element of the array or collection. The second parameter is the array or collection you wish to iterate over, and the third parameter is the name of the variable that will be assigned to the current iteration in the view. For example, if you want to iterate over an array of jobs, you would typically access each task using the job variable in the view fragment. The key of the current iteration will be used as the key variable in the view fragment.

You can also pass a fourth parameter to the @each directive. This parameter is the view fragment to render when the given array is empty.

@each('view.name', $jobs, 'job', 'view.empty')

{note} With @each rendered views, variables cannot be inherited from the parent view. If a subview requires these variables, it must use @foreach and @include instead.

Stack

Blade allows you to push views onto the stack. These views can be used in other views or is rendered in the layout. This is useful when specifying required JavaScript libraries in subviews:

@push('scripts')  
  <script src="/example.js">
  </script>
@endpush

You can push onto the stack multiple times if needed. Rendering of the stack content is completed by passing the stack name to the @stack directive:

<head> 
   <!-- 头部内容 -->
    @stack('scripts')
 </head>

If you want to preset the content on the top of the stack, you need to use the @prepend directive :

@push('scripts')
    This will be second...@endpush// 然后...
  @prepend('scripts')
    This will be first...
  @endprepend

Service injection

@inject directive can be used for services from Laravel Get the service from the container. The first parameter passed to @inject is the name of the service variable to be inserted, and the second parameter is the name of the class or interface that is expected to be resolved:

@inject('metrics', 'App\Services\MetricsService')
<div>
    Monthly Revenue: {{ $metrics->monthlyRevenue() }}.</div>

Extending Blade

Blade allows you to customize directives using the directive method. When the Blade compiler encounters a custom directive, this calls the callback provided by the expression contained in the directive.

The following example creates the @datetime($var) directive, an instance that formats the given DateTime$var:

<?php
  namespace App\Providers;
  use Illuminate\Support\Facades\Blade;
  use Illuminate\Support\ServiceProvider;
  class AppServiceProvider extends ServiceProvider{  
     /**
     * 执行注册后引导服务.
     *
     * @return void
     */   
   public function boot()  
     {       
        Blade::directive('datetime', function ($expression) {           
        return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";       
      });    
    }   
    /**
     * 在容器中注册绑定.
     *
     * @return void
     */ 
      public function register()  
        { 
             //    
         }
      }

As you can see, we will chain the format method in any expression passed to this directive. In this example, the directive will generate the following native PHP code:

<?php echo ($var)->format('m/d/Y H:i'); ?>

{note} After updating the logic of the Blade directive, all caches of the Blade view are required. You can use the view:clear Artisan command to delete the Blade view cache.

Custom If Statement

When defining a simple, custom conditional statement, write your own Defining a directive is more complex than the necessary steps. In this case, Blade provides the Blade::if method, which allows you to quickly define conditional instructions using closures. For example, to define a custom instruction to verify the current application environment, you can do this in the boot method of AppServiceProvider:

use Illuminate\Support\Facades\Blade;
/**
 * 执行注册后引导服务
 *
 * @return void
 */
 public function boot(){  
   Blade::if('env', function ($environment) {     
   return app()->environment($environment);   
   });
 }

Once the custom conditional instruction is defined , you can easily use it in the template:

@env('local')    
  // 应用在本地环境中运行...
@elseenv('testing')    
  // 应用在测试环境中运行...
@else    
  // 应用没有在本地和测试环境中运行...
@endenv
This article was first published on the LearnKu.com website.
PropertiesDescription
##$loop->index
$loop->iteration
$loop->remaining
$loop->count
$loop->first
$loop->last
$loop->depth
$loop->parent