Laravel Tutorial

Bài 8: Blade Template trong Laravel – Phần 2

Tiếp tục về Blade template trong Laravel. Bài này chúng ta tìm hiểu về layout trong Blade template

# Nhúng view khác vào trong Blade

@include

Blade template cho phép bạn có thể include các view khác vào trong view hiện tại một cách đơn giản bằng việc sử dụng @include directive. Lúc này ở các view được nhúng cũng có thể sử dụng được tất cả các biến có trong view hiện tại

Ví dụ: Giả sử mình có 2 view với path và code như sau:

resources/views/shared/notify.blade.php

<div class="alert">{{ $alertMsg }}</div>

resources/views/home.blade.php

<h1>{{ $title }}</h1>
@include('shared.notify')

routes/web.php

use Illuminate\Support\Facades\Route;
Route::get('home ', function () {
   return view('home', ['title' => 'Blade template layout', 'alertMsg' => 'Thông báo']);
});

Kết quả: Xem dạng view-source cho dễ hình dung

Trong trường hợp bạn muốn đưa thêm data vào trong view được include thì bạn có thể sử dụng cú pháp sau:

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

Trong đó:

  • $variableName là tên biến chưa data bạn muốn truyền vào sub view
  • $data là giá trị của $variableName

resources/views/shared/notify.blade.php

<div class="alert {{ $alertType }">{{ $alertMsg }}</div>

resources/views/home.blade.php

<h1>{{ $title }}</h1>
@include('shared.notify', ['alertType' = > 'alert-warning'])

routes/web.php

use Illuminate\Support\Facades\Route;
Route::get('home ', function () {
   return view('home', ['title' => 'Blade template layout', 'alertMsg' => 'Thông báo']);
});

Kết quả

@includeIf

Trong blade template nếu bạn @include một view không tồn tại thì Laravel sẽ throw ra một error. Nếu bạn muốn bỏ qua exception đó thì bạn có thể dùng @includeIf. Directive này sẽ check nếu như view tồn tại thì mới thực thi việc include view

resources/views/home.blade.php

<h1>{{ $title }}</h1>
@include('shared.notify', ['alertType' => 'alert-warning'])

@includeWhen

Kiểm tra điều kiện trước khi nhúng view, cú pháp

@includeWhen($boolean, 'view.name', $data)

$boolean trả về true thì view sẽ được include và ngược lại false thì view sẽ không được include

resources/views/home.blade.php

<h1>{{ $title }}</h1>
@includeWhen(true, 'shared.notify', ['alertType' => 'alert-warning']) //view được include

@includeUnless

Đây là directive phủ định của @includeWhen. Nghĩa là $boolean trả về true thì view sẽ không được include và ngược lại false thì view sẽ được include

@includeUnless($boolean, 'view.name', $data)

resources/views/home.blade.php

<h1>{{ $title }}</h1>
@includeUnless(false, 'shared.notify', ['alertType' => 'alert-warning']) //view được include

@includeFirst

Cho phép chúng ta truyền vào một list view. Và nó sẽ kiểm tra xem nếu view nào tồn tại đầu tiên trong list thì nó sẽ nhúng view đó. Các view phía sau sẽ không được nhúng nữa

Cú pháp:

@includeFirst(['view.name', 'view.name1', 'view.name2'], $data)

 @each

Nhúng view qua mỗi lần lặp một mảng hay một collection trong Blade template với directive @each với cú pháp

@each('view.name', $list, 'item', 'view.empty');

Trong đó:

  • view.name là view bạn muốn nhúng vào view hiện tại.
  • $array là mảng, collection data bạn muốn lặp.
  • item là giá trị sẽ được assign qua mỗi lần lặp.
  • view.empty là view sẽ được nhúng khi $array trống. Giá trị này có thể bỏ qua

Ví dụ

resources/views/shared/post.blade.php

<div class="post-item">
   <span>{{ $post['name'] }}</span>
</div>

resources/views/home.blade.php

<div class="list-post">
   <h1>List post</h1>
   @each('shared.post', $list_post, 'post') //Mỗi phần tử của list_post lúc này đước gán = post
</div>

routes/web.php

Route::get('home', function () {
   $list_post = [
      ['name' => 'Post 1'],
      ['name' => 'Post 2']
   ];
   return view('home', ['list_post' => $list_post]); //Gán list_post vào view home
})->name('home');

Kết quả

@once

Cho phép chúng ta thực thi hành động bên trong nó một lần duy nhất khi render view. Ví dụ có 2 chỗ cùng nhúng một đoạn code nếu như sử dụng directive @once thì các đoạn code phía sau once đầu tiên được thực sẽ không được thực thi nữa

@once
   @push('scripts')
   <script>
      // Your custom JavaScript...
   </script>
   @endpush
@endonce

# Xây dựng layout sử dụng component trong Blade

Hầu hết các ứng dụng web hiện này đều phân chia bố cục theo các layout riêng rồi ghép chúng lại với nhau khi cần sử dụng đến. Làm như thế khiến cho code phần view sẽ dễ đọc hơn, dễ maintenance hơn

Định nghĩa component trong Blade template

Để khai báo một component cơ bản trong Laravel các bạn chỉ cần khai báo chúng ở trong path resources/views/components

Khai báo component resources/views/components/todo.blade.php

<html>
<head>
   <title>Balade template components</title>
</head>
<body>
   <h1>My tasks</h1>
   <hr/>
   {{ $slot }}
</body>
</html>

$slot là nơi sẽ hiện thị nội dung truyền vào component khi chúng được gọi ở view khác

Gọi component trong Blade template

Sau khi đã khai báo được component, giờ nếu bạn muốn gọi chúng ở trong view thì có thể sử dụng cú pháp sau:

<x-componentname>...</x-componentname>
Hoặc
<x-componentname/>

componentname là tên file component bạn muốn gọi

resources/views/home.blade.php

<x-todo>
   @foreach ($tasks as $task)
      <span>{{ $task }}</span>
   @endforeach
</x-todo> 

routes/web.php

Route::get('home', function () {
   $tasks = ['Task 1', 'Task 2'];
   return view('home', ['tasks' => $tasks]);
})->name('home');

Truyền data vào trong components

<x-slot name="VariableName">
   Data
</x-slot>

Trong đó:

  • VariableName là tên biến trong component bạn muốn truyền data vào.
  • Data là dữ liệu bạn muốn truyền vào

Ví dụ: bind deadline vào trongcomponent todo.blade.php ở trên

resources/views/components/todo.blade.php

<html>
<head>
   <title>Balade template components</title>
</head>
<body>
   <h1>My tasks</h1>
   <hr/>
   {{ $slot }}
   {{ $deadline }}

</body>
</html>

resources/views/home.blade.php

<x-todo>
   <x-slot name="deadline">
      Deadline: 30/08/2021
   </x-slot>
   @foreach ($tasks as $task)
      <span>{{ $task }}</span>
   @endforeach
</x-todo> 

routes/web.php

Route::get('home', function () {
   $tasks = ['Task 1', 'Task 2'];
   return view('home', ['tasks' => $tasks]);
})->name('home');

Kết quả

# Xây dựng layout sử dụng kế thừa trong Blade

Có 2 lợi ích của việc sử dụng Blade là template inheritance và sections. Như chúng ta biết hầu hết các ứng dụng web đều có cùng bố cục trên nhiều trang, vì vậy cách tiếp cận tốt hơn là xác định một mẫu chính nơi chúng ta có thể đặt tất cả các code giống nhau trong các trang. Trong Laravel, Blade Template cho phép chúng ta xác định một mẫu chính có thể được mở rộng bởi các trang con khác

Xây dựng layout master

Khai báo một layout trong 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>

@section directive  dùng để định nghĩa một nội dung của section

@yielddirective dùng để chỉ định section có name trong yield sẽ được hiển thị. Ví dụ trên @yield('title') sẽ hiện thị nội dung của @section('title')

Kế thừa layout

Khai báo một view kế thừa layout ở ví dụ trên, file resources/views/home.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

@extends directive để chỉ ra layout của trang con này “inherit” từ đâu

view kế thừa một Blade layout có thể inject nội dung vào trong sections sử dụng @section, nội dung của những section này được hiển thị khi sử dụng @yield

Trong một vài trường hợp bạn muốn xác định giá trị mặc định sẽ hiển thị khi không có data truyền vào trong @yield thì bạn có thể sử dụng cú pháp sau:

@yield('name', 'Default content')

 @parent sẽ lấy nội dung của layout cha

Render view, file routes/web.php

Route::get('home', function () { 
   return view('home');
})->name('home');

Kết quả

# Form trong Blade template

Trong Blade template, Laravel cũng đã cung cấp sẵn cho chúng ta một số directive hộ trợ cho việc tạo ra các method, csrf token.

Để thêm một input field hidden chứa csrf_token trong form các bạn có thể sử dụng directive @csrf

Cú pháp:

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

Kết quả:

 

Ngoài ra bạn có thể sử dụng directive @method để thêm một input hidden chứa method của form. Vì HTML form không thể tạo được method PUTPATCHDELETE

Ví dụ:

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

Kết quả:

# Raw PHP

Trong một số trường hợp bạn muốn sử dụng code PHP chứa logic code trong blade template bạn có thể sử dụng directive @php với cú pháp như sau:

@php(//Code PHP here)
Hoặc
@php
   //Code PHP here
@endphp

Ví dụ: resources/views/home.blade.php

@php
   $message = "Học Laravel";
@endphp
{{ $message }}

Kết quả:

 

Leave a Comment