Larravel view rendering: Blade template engine


Blade Introduction

Blade is a very simple but powerful template engine provided by Laravel. Unlike other popular PHP template engines, Blade does not restrict you to use PHP native code in the view. All blade views will eventually be compiled into native PHP code and cached until they are modified, which means that the blade is basically zero overhead for application performance. Blade View File Usage .blade.php Files are expanded and stored in resources/views Directory.

Template inheritance

Define Layout

The two greatest advantages of using Blade are template inheritance and fragment combination. Let's look at an example before starting. First, we test the "main" page layout. Since most Web applications use the same layout in different pages, it is convenient to define this layout as a separate Blade page:

 <!--  Stored in resources/views/layouts/app. blade. php --> <html> <head> <title>Application name - @ yield ('title ')</title> </head> <body> @section('sidebar') This is the sidebar @show <div class="container"> @yield('content') </div> </body> </html>

As you can see, this file contains typical HTML tags, but note that @section and @yield Instruction, the former defines a content fragment as its name implies, and the latter is used to display the content of a given fragment.

Now that we have defined a layout for the application, let's define a sub page that inherits the layout.

Inherit Layout

When defining subpages, you can use the Blade's @extends Command to specify the layout inherited by the subpage. The view inheriting a Blade layout can be used @section Instruction injects content into the content fragments defined by the layout. Remember, as shown in the above example, the content of these fragments will be displayed in the layout for use @yield Where:

 <!--  Stored in resources/views/child. blade. php --> @extends('layouts.app') @Section ('title ','Laravel College') @section('sidebar') @parent <p>Laravel College is committed to providing high-quality Chinese learning resources for Laravel</p> @endsection @section('content') <p>Here is the main content, improving</ p> @endsection

In this example, sidebar Fragment Usage @parent Command to append (rather than overwrite) content to the sidebar of the inherited layout, @parent The command will be replaced by the content in the layout when the view is rendered.

Of course, like the native PHP view, the Blade view can be accessed through view Method returns directly from the route:

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

This way, you can access http://blog.dev/blade , you can see that the page displays as follows:

Now the page is still very rough, without any style. You can come back to improve it after learning the front-end components.

Components&Slots

Components and slots bring convenience to the content section and layout. However, some people may find that the model of components and slots is easier to understand. First, let's assume that there is a reusable "alert" component that we want to reuse throughout the application:

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

{{ $slot }} The variable contains the content of the component we want to inject. Now, to build this component, we can use the Blade command @component

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

Sometimes it is useful to define multiple slots for a component. Now let's edit the alert component so that "Title" can be injected. The named slots can be displayed through the variable "echo" matching their names:

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

Now, we can use the command @slot Inject content into the named slot. Any absent @slot The contents of the instruction will be transferred to the component's $slot In variables:

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

When we view the content of this component in the browser, the corresponding output is as follows:

This code means to use the component name alert Find the corresponding view file, load it into the current view, and then use the component @slot The defined slot content is used to render the corresponding slot bit in the slot view. If the component does not define a corresponding slot content segment for a slot bit, the other slots in the component are not @slot The content in the clip will be used to render the slot bit. If there is no other superfluous content, the corresponding slot bit will be empty.

Transfer additional data to components

Sometimes you may need to pass additional data to components. For this reason, you can pass array data as the second parameter to @component Command, all data will take effect in variable mode in the component template:

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

data display

Two curly braces can be used to wrap variables to display the data passed to the view. For example, if the following route is given:

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

Then it can be displayed as follows name Contents of variables:

 Hello, {{$name}}.

Of course, you can output the results of any PHP function without limiting the variable content displayed in the view. In fact, you can put any PHP code into the Blade template statement:

 The current UNIX timestamp is {{ time() }}.
Note: Blade's {{}} The statement has passed PHP's htmlentities Function processing to avoid XSS attacks.

Output existing data

Sometimes you want to output a variable, but you are not sure whether the variable is set. We can use the following PHP code:

 {{ isset($name) ? $name : 'Default' }}

In addition to using ternary operators, Blade also provides a simpler way:

 {{ $name or 'Default' }}

In this example, if $name Variable exists, its value will be displayed, otherwise it will be displayed Default

Display native data

By default, the {{ }} The statement has passed PHP's htmlentities Function processing to avoid XSS attacks. If you do not want data to be processed, such as outputting rich text with HTML elements, you can use the following syntax:

 Hello,  {!! $name !!}.
Note: Be careful when outputting the content provided by users, and always wrap the content provided by users with double curly braces to avoid direct output of HTML code.

Render JSON content

Sometimes you may transfer the data to the view in the form of an array and then convert it to JSON format to initialize a JavaScript variable, for example:

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

This is troublesome. There is a simpler way to implement this function, that is, the @json Directives:

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

Blade&JavaScript framework

Since many JavaScript frameworks also use curly braces to indicate expressions to be displayed in the browser, such as Vue, we can use @ Symbol to tell the Blade rendering engine that the expression should remain unchanged in its native format. For example:

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

In this example, @ The symbol will be removed by the Blade at the compilation stage, but, {{ name }} The expression will remain unchanged so that it can be rendered normally by the JavaScript framework.

@verbatim instructions

If you display JavaScript variables in a large part of the template, you can encapsulate this part of HTML in @verbatim Directive, so that you do not need to add @ Prefix:

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

Process control

In addition to template inheritance and data display, Blade also provides convenient operations for commonly used PHP process control, such as conditional statements and loops. These shortcut operations provide a clean and simple way to handle PHP process control, while maintaining the similarity with PHP corresponding statements.

If statement

have access to @if , @elseif , @else and @endif To construct if Statement. These instructions have the same function as 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

For convenience, the Blade also provides @unless Instruction, indicating that unless:

 @unless (Auth::check()) You are not signed in. @endunless

In addition, Blade provides @isset and @empty Directives that correspond to PHP's isset and empty method:

 @isset($records) // $records is defined and is not null... @endisset @empty($records) // $records is "empty"... @endempty

Certification Directive

@auth and @guest The command can be used to quickly determine whether the current user is logged in:

 @auth //User logged in @endauth @guest //User not logged in @endguest

If necessary, you can also use it @auth and @guest Specify the login user type:

 @auth('admin') // The user is authenticated... @endauth @guest('admin') // The user is not authenticated... @endguest

We will discuss user login authentication in depth later when we talk about user authentication.

Switch statement

switch The statement can be @switch @case @break @default and @endswitch Instruction building:

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

And PHP switch The statement structure is completely consistent.

loop

In addition to conditional statements, Blade also provides simple instructions to deal with the loop structure of PHP. Similarly, these instructions have exactly the same functions as PHP:

 @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
Note: It can be used during circulation $loop Variables obtain loop information, such as whether it is the first or last iteration of the loop.

When using a loop, you can also end the loop or jump out of the current 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 use directive declarations to introduce conditions:

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

$loop variable

When cycling, it can be used in the loop body $loop Variable, which provides some useful information, such as the index of the current loop, and whether the current loop is the first or last iteration:

 @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

If you are in a nested loop, you can use the $loop Variable parent Property access 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 Variables also provide some other useful properties:

attribute describe
$loop->index Index of current loop iteration (starting from 0)
$loop->iteration Current loop iteration (starting from 1)
$loop->remaining The remaining iterations of the current loop
$loop->count The total number of iterated array elements
$loop->first Is it the first iteration of the current loop
$loop->last Whether it is the last iteration of the current loop
$loop->depth Nesting level of the current loop
$loop->parent Parent loop variable in nested loop

notes

Blade also allows you to define comments in the view. However, unlike HTML comments, Blade comments are not included in HTML and are returned:

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

PHP

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

 @php // @endphp
Note: Although Blade provides this feature, if you use it too frequently, it means that you have embedded too much business logic in the view template. You should pay attention.

Include Subviews

Blade's @include Directives allow you to easily include another Blade view in one view. Variables in all parent views are still valid in the included child views:

 <div> @include('shared.errors') <form> <!--  Form Contents --> </form> </div>

The above instructions will be displayed in the shared Find in subdirectory errors.blade.php File and bring its contents into the current view.

Although included views can inherit data from all parent views, you can also pass additional parameters to included views:

 @include('view.name', ['some' => 'data'])

Of course, if you try to include a view that does not exist, Larvel will throw an error. If you want to include a view that may not exist, you can use @includeIf Directives:

 @includeIf('view.name', ['some' => 'data'])

If the included view depends on a given Boolean condition, you can use the @includeWhen Directives:

 @includeWhen($boolean, 'view.name', ['some' => 'data'])

To include the first view in a given array, use the @includeFirst Directives:

 @includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
Note: Do not use in Blade view __DIR__ and __FILE__ Constants because they point to the path of the cached view.

Someone once asked me @include and @component What's the difference? They have something in common. They are both used to introduce other content into the current view. I understand the difference is that @include For coarse-grained views, @component For fine-grained component introduction, @component The slot mechanism allows more granular control over the import of view content. If you only import a view content fragment, use @include That is, if you want to adjust and control the introduced view content fragment in the current view, you can consider using @component

Render Assembly View

You can use Blade's @each The instruction circulates through a line of code to introduce multiple detail views:

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

The first parameter of this command is the detail view to be rendered for each element in the array or collection, the second parameter is the array or collection you want to iterate over, and the third parameter is the variable name to be assigned to the current view. For example, if you want to iterate a jobs Array, which you usually need to access in the detail view $job Variable. In detail views, you can use the key Variable to access the key of the current iteration.

You can also pass the fourth parameter to @each Directive, which specifies the rendered view when the given array is empty:

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

stack

Blade allows you to push content to the named stack for rendering in other views or layouts. This is useful when introducing a specified JavaScript library into a subview:

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

Unlimited push times. To render the complete stack content, pass the stack name to @stack Command:

 <head> <!--  Head Contents --> @stack('scripts') </head>

Service injection

@inject The instruction can be used to obtain the service from the service container and pass it to @inject The first parameter of is the variable name corresponding to the service, and the second parameter is the name of the service class or interface to be resolved:

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

Expand Blades

Blade even allows you to customize instructions, which can be used directive Method to register an instruction. When the Blade compiler encounters this instruction, it will pass in parameters and call the provided callback.

The following example creates a @datetime($var) The command formats the given DateTime Instance of $var

 <? php 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); ?> "; }); } /** *Register the binding in the container * * @return void */ public function register() { // } }

As you can see, we can datetime Method is applied to the expression of any incoming instruction:

 @datetime(1508888888)

The PHP code generated by this instruction is as follows:

 <? php echo date('m/d/Y H:i', 1508888888); ?>
Note: After updating the Blade instruction logic, you must delete all Blade cache views. Cached blade views can be accessed via Artisan commands view:clear Remove.

Custom If Statement

When defining some simple and customized conditional statements, the complexity of writing custom instructions is often greater than the necessity. For this reason, Blade provides a Blade::if Method to quickly define user-defined condition instructions by means of closures. For example, we can customize a condition to check the current application environment AppServiceProvider Of boot This logic is defined in the method:

 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); }); }

After defining user-defined conditions, you can use them in the template:

 @env('local') The application is in the local environment... @else The application is not in the local environment... @endenv

give the thumbs-up Cancel Like Collection Cancel Collection

<<Previous: HTTP response, redirection and file download

>>Next: Creation and data transfer of Larave view