Trong bài này chúng ta sẽ tìm hiểu về cách liên kết một blade view với một view khác thong qua @include. Chúng ta cùng tìm hiểu ngay sau đây nhé.
Liên kết sub-view (Including sub-view)
@include trong Blade template cho phép bạn có thể liên kết một blade view với một view khác. Tất cả các biến dữ liệu ở parent view đều được truyền đến view include.
Chẳng hạn chúng ta có cấu trúc thư mục như sau:
resources/ ├── views/ | ├── includes/ | | | room.blade.php | | home.blade.php
Ở blade view home ta code:
@php $name = 'Pham Nhan'; @endphp
@include('includes.room')
Như các bạn thấy, mình đã sử dụng cú pháp @include với tham số là tên view liên kết cần đưa vào blade view home này. Ngoài ra mình có khai báo biến $name để thử xem là blade view includes.room có nhận được hay không.
Tại blade view includes.room mình code như sau:
resources/views/includes/room.blade.php
{{ $name }}
Kết quả này chứng minh cho rằng chúng ta có thể lấy tất cả các dữ liệu tại view liên kết từ parent view. Ngoài ra bạn cũng có thể truyền một dữ liệu bất kì cho view liên kết thông qua tham số thứ hai của thẻ @include.
@include('view.name', ['some' => 'data'])
Một số cú pháp khác hỗ trợ cho include (Some other syntax support for including)
Trong trường hợp nếu bạn @include một view không tồn tại thì framework sẽ báo lỗi. Chính vì vậy khi include một view không chắc chắn sẽ tồn tại thì ta sử dụng thẻ @includeIf thay cho @include.
@includeIf('view.name', ['some' => 'data'])
Bạn cũng có thể include một view khi kiểm tra một điều kiện nào đó trả về boolean true.
@includeWhen($boolean, 'view.name', ['some' => 'data'])
Laravel còn cung cấp thẻ @includeFirst, thẻ này cho phép ta include view đầu tiên trong mảng view khai báo. Nhiều bạn sẽ hiểu ngay công dụng của thẻ này nếu theo dõi các tập trước của mình.
@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])
Như dòng code này, nếu view custom.admin tồn tại thì nó sẽ include view này và bỏ qua view admin. Còn nếu view custom.admin không tồn tại thì nó sẽ bỏ qua và tiếp tục kiểm tra view admin.
Lưu ý: Bạn nên tránh sử dụng __DIR__ và __FILE__ trong blade view vì chúng chỉ trả kết quả đường dẫn của các file cache hay compile view, không cung cấp thông tin cần thiết.
Aliasing include
Nếu blade view include một view nằm trong sub-directory, mà phải tham chiếu một tên rất dài. Chúng ta có thể alias cú pháp include một view nào đó giống như là component. Ta cũng sẽ làm việc này tại AppServiceProvider, ngay tại method boot.
app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Blade;
public function boot()
{
Blade::include('includes.room', 'room');
}
Rồi bây giờ ta chỉ cần include view includes.room theo cú pháp đã đăng ký:
@room(['name' => 'Pham Nhan'])
Rendering views for collections
Chúng ta có thể sử dụng @each để truyền từng dữ liệu của 1 mảng vào một view thay vì @foreach và @include.
Ví dụ có cấu trúc thư mục như sau:
resources/ ├── views/ | ├── includes/ | | | item.blade.php | | list.blade.php
Đầu tiên mình sẽ thử sử dụng cách thông thường đó là dùng @foreach và @include. Tại blade view list.blade.php mình sẽ code nội dung như sau:
resources/views/list.blade.php
@php $list = ['Item #1', 'Item #2', 'Item #3']; @endphp
- @foreach ($list as $item) @include('includes.item') @endforeach
Và blade view includes.item:
resources/views/includes/item.blade.php
- {{ $item }}
Sau đó chúng ta đăng ký route và chạy thử:
routes/web.php
Route::get('/', function () {
return view('list');
});
Bây giờ chúng ta sẽ dùng @each để thay thế cách trên. Ta chỉ cần thay đổi đoạn vòng lặp trong blade view list.
resources/views/list.blade.php
- @each('includes.item', $list, 'item')
@each này sẽ nhận tham số sau
- Tham số đầu tiên là tên view include
- Tham số thứ hai là biến chứa mảng dữ liệu
- Tham số thứ ba là tên biến nhận giá trị trong view include.
Ngoài ra trong trường hợp nếu mảng dữ liệu rỗng thì ta có thể include view hiện thông báo gì đó bằng cách khai báo thêm tham số thứ tư ở @each với giá trị là tên view chứa nội dung thông báo của bạn
@each('view.name', $list, 'item', 'view.empty')
Lưu ý: Các view được render thông qua @each không thể nhận các biến dữ liệu được truyền đến parent view. Nên bạn cần cần nhắc sử dụng @foreach và @include để thay thế nếu các view include cần những biến dữ liệu này.