Blade Template Engine
trong Laravel
Giới thiệu
Blade là "framework layout" đi kèm với Laravel
*Note: Tất cả code blade được biên dịch về thành code PHP thuần.
Template Inheritance
Kế thừa template
Template Inheritance
1. Định nghĩa "Master Layout"
<!-- Stored in 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>
*Master Layout: Hầu như tất cả các website đều có một "khung layout" dùng chung cho tất cả các trang.
Template Inheritance
2. Kế thừa master layout
<!-- Stored in 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
*Views con extends view cha và định nghĩa các @section ở biên trong. Ở view cha sẽ hiện nó ra ở trong chỗ @yield
Components & Slots
Components & Slots
Components và slots giống @section và layouts, tuy nhiên nhiều người thấy cái này "dễ hiểu" hơn.
* ví dụ về component "alert" có thể tái sử dụng được trong toàn app.
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
Components & Slots
Giờ để sử dụng component này, chúng ta sử dụng "chỉ dẫn" (directive) @component
@component('alert')
<strong>Whoops!</strong> Something went wrong!
@endcomponent
Components & Slots
Load component đầu tiên trong mảng component sử dụng @componentFirst
@componentFirst(['custom.alert', 'alert'])
<strong>Whoops!</strong> Something went wrong!
@endcomponent
Components & Slots
Định nghĩa nhiều slots cho các component và chuẩn bị cho việc inject biến $title vào.
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
<div class="alert-title">{{ $title }}</div>
{{ $slot }}
</div>
Components & Slots
Định nghĩa biến $title trong @slot và nội dung bên ngoài @slot sẽ được nhét vào biến $slot.
@component('alert')
@slot('title')
Forbidden
@endslot
You are not allowed to access this resource!
@endcomponent
Components & Slots
Truyền thêm giá trị vào cho component, sau đó lấy nội dung thông qua biến chính là "key".
@component('alert', ['foo' => 'bar'])
...
@endcomponent
Passing Additional Data To Components
Components & Slots
Đặt tên lại cho component để dễ gọi hơn.
use Illuminate\Support\Facades\Blade;
Blade::component('components.alert', 'alert');
Aliasing Components
@alert(['type' => 'danger'])
You are not allowed to access this resource!
@endalert
@alert
You are not allowed to access this resource!
@endalert
Displaying Data
Hiển thị dữ liệu
Displaying Data
Route::get('greeting', function () {
return view('welcome', ['name' => 'Samantha']);
});
Hello, {{ $name }}.
* Blade {{ }} statements are automatically sent through PHP's htmlspecialchars function to prevent XSS attacks.
The current UNIX timestamp is {{ time() }}.
Displaying Data
Hello, {!! $name !!}.
<script>
var app = <?php echo json_encode($array); ?>;
</script>
<script>
var app = @json($array);
var app = @json($array, JSON_PRETTY_PRINT);
</script>
Displaying Unescaped Data
<example-component :some-prop='@json($array)'></example-component>
* @json cần được đặt trong nháy đơn ''.
Route::get('greeting', function () {
return view('welcome', ['name' => 'Samantha']);
});
Displaying Data
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::withoutDoubleEncoding();
}
}
HTML Entity Encoding
Displaying Data
<h1>Laravel</h1>
Hello, @{{ name }}.
Blade & JavaScript Frameworks
@verbatim
<div class="container">
Hello, {{ name }}.
</div>
@endverbatim
The @verbatim Directive
Control Structures
Control Structures
If Statements
@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
@unless (Auth::check())
You are not signed in.
@endunless
@isset($records)
// $records is defined and is not null...
@endisset
@empty($records)
// $records is "empty"...
@endempty
Control Structures
Authentication Directives
@auth
// The user is authenticated...
@endauth
@guest
// The user is not authenticated...
@endguest
@auth('admin')
// The user is authenticated...
@endauth
@guest('admin')
// The user is not authenticated...
@endguest
Control Structures
Section Directives
@hasSection('navigation')
<div class="pull-right">
@yield('navigation')
</div>
<div class="clearfix"></div>
@endif
Control Structures
Switch Statements
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
Control Structures
Loops
@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
Control Structures
Loops
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
<li>{{ $user->name }}</li>
@if ($user->number == 5)
@break
@endif
@endforeach
* Sử dụng biến $loop để lấy thêm thông tin về vòng lặp, ví dụ như index của lần lặp hiện tại.
Control Structures
Loops
@foreach ($users as $user)
@continue($user->type == 1)
<li>{{ $user->name }}</li>
@break($user->number == 5)
@endforeach
* Có thể viết điều kiện và chỉ dẫn (directive) trong cùng 1 dòng
Control Structures
The Loop Variable
@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
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is first iteration of the parent loop.
@endif
@endforeach
@endforeach
Control Structures
The Loop Variable
* Biến $loop cung cấp thêm rất nhiều thông tin hữu ích.
Property | Description |
---|---|
$loop->index | The index of the current loop iteration (starts at 0). |
$loop->iteration | The current loop iteration (starts at 1). |
$loop->remaining | The iterations remaining in the loop. |
$loop->count | The total number of items in the array being iterated. |
$loop->first | Whether this is the first iteration through the loop. |
$loop->last | Whether this is the last iteration through the loop. |
$loop->even | Whether this is an even iteration through the loop. |
$loop->odd | Whether this is an odd iteration through the loop. |
$loop->depth | The nesting level of the current loop. |
$loop->parent | When in a nested loop, the parent's loop variable. |
Control Structures
Comments
{{-- This comment will not be present in the rendered HTML --}}
Control Structures
PHP
@php
//
@endphp
Thêm code PHP thuần ở trong template
Forms
Forms
CSRF Field
<form method="POST" action="/profile">
@csrf
...
</form>
Forms
Method Field
<form action="/foo/bar" method="POST">
@method('PUT')
...
</form>
Forms
Validation Errors
<!-- /resources/views/post/create.blade.php -->
<label for="title">Post Title</label>
<input id="title" type="text" class="@error('title') is-invalid @enderror">
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
Including Sub-Views
Including Sub-Views
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
@include('view.name', ['some' => 'data'])
@includeIf('view.name', ['some' => 'data'])
@includeWhen($boolean, 'view.name', ['some' => 'data'])
@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
Including Sub-Views
<input type="{{ $type ?? 'text' }}">
use Illuminate\Support\Facades\Blade;
Blade::include('includes.input', 'input');
@input(['type' => 'email'])
Aliasing Includes
* Nếu file blade của mình ở trong thư mục con, mình có thể đặt tên lại để gọi cho "ngắn" hơn. Ví dụ như file .blade để ở resources/views/includes/input.blade.php, mình có thể đặt tên từ includes.input thành input.
Sau đó gọi như là một Blade directive thành @input.
Including Sub-Views
@each('view.name', $jobs, 'job')
@each('view.name', $jobs, 'job', 'view.empty')
Rendering Views For Collections
Vừa lặp vừa include. Tham số là:
1. Tên view
2. Mảng dữ liệu
3. Tên biến đại diện cho mỗi lần lặp
4. View hiển thị nếu mảng dữ liệu rỗng
Stacks
Stacks
@push('scripts')
<script src="/example.js"></script>
@endpush
<head>
<!-- Head Contents -->
@stack('scripts')
</head>
@push('scripts')
This will be second...
@endpush
// Later...
@prepend('scripts')
This will be first...
@endprepend
Service Injection
@inject('metrics', 'App\Services\MetricsService')
<div>
Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>
Extending
Blade
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});
}
}
Custom If Statements
use Illuminate\Support\Facades\Blade;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Blade::if('env', function ($environment) {
return app()->environment($environment);
});
}
Extending
Blade
@env('local')
// The application is in the local environment...
@elseenv('testing')
// The application is in the testing environment...
@else
// The application is not in the local or testing environment...
@endenv
Let's code it !
Blade Template Engine trong Laravel
By dannguyencoder
Blade Template Engine trong Laravel
Những tính năng mà Blade Engine cung cấp cho chúng ta để cắt layout tiện hơn so với PHP thuần.
- 338