Hướng dẫn render html laravel - kết xuất html ấu trùng

Rất vui được gặp lại tất cả các bạn. Như đã nói ở tập trước thì ngày hôm nay, nội dung sẽ nói về "Blade template" trong Laravel. Tập ngày hôm nay chủ yếu chỉ học cú pháp và lợi ích của từng cú pháp đó, tuy dài nhưng không khó. Không luyên thuyên nữa, chúng ta vào bài thôi.

Show

Vì editor của Viblo không hỗ trợ Blade template Laravel nên đôi khi màu sắc code có chỗ khó nhìn, mong các bạn thông cảm.

I. Giới thiệu (Introduction)

Blade là một template engine được cung cấp bởi Laravel. Đây là một engine khá mạnh mẽ, không như những các template engine khác, Blade không hạn chế việc sử dụng mã code PHP thuần túy trong template của bạn ngoài những cú pháp riêng biệt của nó. Thực tế thì Blade template được biên dịch thành các file PHP và được lưu vào cache. Blade template có đuôi mở rộng là

resources/
├── views/
|   ├── components/
|   |   |   ...
1 và được lưu trữ trong thư mục
resources/
├── views/
|   ├── components/
|   |   |   ...
2.

II. Layout template

1. Xác định bố cục (Defining layout)

Có hai lợi ích chính trong việc sử dụng Blade template là layout và section. Để bắt đầu chúng ta sẽ đi vào một ví dụ đơn giản. Như các bạn đã biết, trong một ứng dụng thì đa phần các trang con đều được thừa hưởng một cấu trúc layout chung. Blade template cho phép chúng ta định nghĩa một layout cho ứng dụng với duy nhất một blade view.

<html>
    <head>
        <title>Laravel</title>
    </head>
    <body>
        @section('sidebar')
            <h2>Sidebar</h2>
        @show
        
        @yield('content')
    </body>
</html>

Đây chỉ là nội dung của một đoạn mã HTML bình thường, nhưng có chút đặt biệt là nó có hai cú pháp lạ:

resources/
├── views/
|   ├── components/
|   |   |   ...
3,
resources/
├── views/
|   ├── components/
|   |   |   ...
4. Đây chính là một trong những cú pháp riêng biệt của Blade template dùng cho mục đích kế thừa qua lại giữa parent-child.

  • resources/
    ├── views/
    |   ├── components/
    |   |   |   ...
    
    3: dùng để xác định một phần nội dung
  • resources/
    ├── views/
    |   ├── components/
    |   |   |   ...
    
    4: dùng để hiển thị nội dung của một phần đã được xác định

Hiện tại khó mà để hiểu theo giải thích bằng văn được. Để các bạn có thể hiểu chi tiết công dụng của hai cú pháp này, mình sẽ làm sáng tỏ chúng qua ví dụ.

2. Kế thừa layout (Extending layout)

Như đã nói ở trên, công dụng chung của hai thằng

resources/
├── views/
|   ├── components/
|   |   |   ...
3 và
resources/
├── views/
|   ├── components/
|   |   |   ...
8 là dùng cho mục đích kế thừa. Blade view
resources/
├── views/
|   ├── components/
|   |   |   ...
9 là parent, vì nó là layout cho ứng dụng, vì vậy mình sẽ tạo một blade view
<div class="modal">
    {{ $slot }}
</div>
0 đóng vai trò là child kế thừa parent
resources/
├── views/
|   ├── components/
|   |   |   ...
9.

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection

Mình đã sử dụng cú pháp

<div class="modal">
    {{ $slot }}
</div>
2, điều này giúp blade view
<div class="modal">
    {{ $slot }}
</div>
0 có thể kế thừa
resources/
├── views/
|   ├── components/
|   |   |   ...
9. Tiếp theo mình đã xác định nội dung cho section
<div class="modal">
    {{ $slot }}
</div>
5 thông qua thẻ
resources/
├── views/
|   ├── components/
|   |   |   ...
3. Bây giờ đăng ký route và xem thử nó hoạt động như thế nào.

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

Ở đây chúng ta render view

<div class="modal">
    {{ $slot }}
</div>
0 chứ không phải
resources/
├── views/
|   ├── components/
|   |   |   ...
9 nhé. Kết qua thu được như thế này:

Hướng dẫn render html laravel - kết xuất html ấu trùng

Chữ "My content" xuất hiện thì khá dễ hiểu, vì chúng đã xác định nội dung cho section

<div class="modal">
    {{ $slot }}
</div>
5, nên lệnh
resources/
├── views/
|   ├── components/
|   |   |   ...
4 sẽ thực hiện công việc render. Nhưng sao section
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 vẫn được hiển thị? Mình dùng
resources/
├── views/
|   ├── components/
|   |   |   ...
3 để xác định nội dung
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 như
<div class="modal">
    {{ $slot }}
</div>
5 thôi mà. Hãy quan sát so sánh sau:

Cú pháp

resources/
├── views/
|   ├── components/
|   |   |   ...
3 cho section
<div class="modal">
    {{ $slot }}
</div>
5 thì như sau:

@section('content')
    <h2>My content</h2>
@endsection

Nó có thẻ mở

resources/
├── views/
|   ├── components/
|   |   |   ...
3 và thẻ đóng
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
08. Trong khi đó, lệnh
resources/
├── views/
|   ├── components/
|   |   |   ...
3 cho section
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 thì khác một chút:

@section('sidebar')
    <h2>Sidebar</h2>
@show

Thẻ đóng lúc này là

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
11, chính vì thể cú pháp này không chỉ là xác định nội dung cho
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 mà đồng với với
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
11 nó sẽ render section này luôn. Đó là lý do vì sao mà chữ "Sidebar" lại xuất hiện.

Nhưng tại sao lại không dùng

resources/
├── views/
|   ├── components/
|   |   |   ...
4 luôn cho tiện mà phải dùng
resources/
├── views/
|   ├── components/
|   |   |   ...
3 rồi đóng bằng thẻ
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
11 để render? Cái gì cũng có nguyên nhân của nó cả, vì khi sử dụng
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
17 trong layout thì bạn có thể làm một điều thú vị trong các trang con. Mình sẽ dẫn chứng ngay và luôn, các bạn mở file
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
18 và thêm đoạn code này vào:

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection

Giờ cứ thử xem kết quả trước đã rồi mình sẽ giải thích.

Như các bạn thấy, section

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 không chỉ không mất chữ "Sidebar" mà còn có thêm cái list mình mới vừa tạo. Bây giờ hãy bắt đầu quan sát lại đoạn code vừa thêm ở trên, mình đã có thêm thẻ
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
20. Với thẻ này thì các section được định nghĩa lại trong trang con sẽ append vào section ở blade view cha. Trong trường hợp này blade view
<div class="modal">
    {{ $slot }}
</div>
0 đã extend blade view
resources/
├── views/
|   ├── components/
|   |   |   ...
9 nên chính vì thế khi khai báo lại section
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 thì nó đã append thêm cái list ở dưới chữ "Sidebar".

Vậy thử đoán xem điều gì sẽ xảy ra nếu mình bỏ đi thẻ

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
20? Vâng, lúc này section
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 được khai báo trong blade view
<div class="modal">
    {{ $slot }}
</div>
0 sẽ ghi đè hoàn toàn lên section
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
01 ở blade view
resources/
├── views/
|   ├── components/
|   |   |   ...
9.

Nói một chút về

resources/
├── views/
|   ├── components/
|   |   |   ...
3 thì ngoài cách khai báo xác định nội dung trên thì ta còn có một cú pháp khác để xác định nội dung của một phần nào đó như sau:

@section('title', 'Laravel')

Thông thường với cách này thường áp dụng cho các section chứa nội dung ngắn gọn hoặc không chứa các thẻ HTML.

Ngoài ra,

resources/
├── views/
|   ├── components/
|   |   |   ...
4 còn có thể nhận tham số thứ hai làm giá trị mặc định nếu các trang con extend với nó không xác định nội dung cho phần đã khai báo.

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')

Lưu ý: Kết thúc mỗi thẻ trong cú pháp Blade template không có dấu

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
31. Kết thúc mỗi thẻ trong cú pháp Blade template không có dấu
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
31.

III. Component & Slot

Component và slot cung cấp tính năng khá giống với section và layout, nhưng có vài chỗ thì component và slot dễ hiểu hơn nhiều. Hiểu đơn giản thì component là các thành phần, còn slot là nơi chứa nội dung sẽ thay đổi nhiều lần. Hãy tưởng tượng nếu ứng dụng của bạn có nhiều xử lý cần hiện modal để thông báo, nhưng bạn lại muốn có thể sử dụng lại mà không cần phải khai báo nhiều lần. Lúc này component chính là modal, và nội dung thông báo chính là slot.

Thông thường các component được khai báo trong view, bạn có thể tự tổ chức cấu trúc thư mục để lưu trữ các component, hoặc là có thể tham khảo theo cấu trúc của mình.

resources/
├── views/
|   ├── components/
|   |   |   ...

1. Khởi tạo component & slot (Creating component & slot)

Bây giờ mình sẽ tạo component modal đặt trong file

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
32 với nội dung sau:

<div class="modal">
    {{ $slot }}
</div>

Cú pháp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
33 sẽ chứa nội dung thông báo thay đổi liên tục trong suốt ứng dụng.

Lưu ý::

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
34 không thể thay đổi tên biến khác.:
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
34 không thể thay đổi tên biến khác.

Mọi thiết lập đã hoàn tất, giờ chỉ cần lấy ra sử dụng thôi. Mình sẽ sử dụng lại blade view

<div class="modal">
    {{ $slot }}
</div>
0 hồi nãy để test luôn.

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
0

Chúng ta sử dụng cặp thẻ

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
36 để gọi component
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
37, đồng thời khai báo slot. Tham số trong
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
38 là tên blade view chứa component, nội dung trong cặp thẻ chính là giá trị mà
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
34 nhận được. Nạp lại server và chạy đường dẫn http://localhost:8000 ta sẽ được kết quả như hình:

Bạn có thể gọi một component nhiều lần như thế này:

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
1

2. The first available component

Bạn cũng có thể tùy chỉnh các giao diện của component nào đó với

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
40, về tính năng thì nó cũng tương tự như
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
41.

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
2

3. Truyền dữ liệu cho component (Passing data to component)

Đôi khi với một

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
34 thì bị hạn chế cho việc tùy chỉnh nội dung một component, chính vì thế Laravel cho phép truyền slot khác ngoài
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
34 mặc định để ứng dụng của bạn linh hoạt hơn.

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
3

Sử dụng

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
44 với tham số là tên biến nhận dữ liệu trong blade view component để khai báo một giá trị khác mà component có thể nhận.

Tại component

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
45, bạn chỉnh sửa nội dung như sau:

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
4

Laravel sẽ hiểu phần nội dung bạn khai báo ở

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
44 sẽ truyền vào
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
47, còn phần chỉ nằm trong cặp thẻ
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
48 thì sẽ truyền vào
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
34 mặc định. Mình xin tản mạn một chút, cú pháp
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
50 là dùng để hiển thị dữ liệu của biến.

Và đây là kết quả sau khi tải lại trang:

Ngoài ra bạn có thể thay thế cách truyền dữ liệu cho component trên bằng cách:

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
5

Tham số thứ hai trong

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
38 sẽ nhận một mảng chứa dữ liệu và lấy tên key làm tên biến trong component. Với cách này thông thường dùng để truyền các dữ liệu ngắn, không chứa thẻ HTML.

4. Aliasing component

Bạn có nghĩ mình sẽ có thể tự đặt cú pháp cho component để trông code dễ hiểu, dễ hình dung hơn không, chẳng hạn:

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
6

Laravel hiểu mong muốn của bạn, vì thế đã định nghĩa method

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
52 trong
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
53 facade để ta có thể dễ dàng alias cú pháp cho bất kì component nào. Laravel khuyên nên thực hiện việc này tại
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
54, cụ thể làm method
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
55:

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
7

Ở đây bắt buộc chúng ta phải

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
56 Blade facade để có thể gọi method
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
52 ra. Method này sẽ nhận hai tham số:

  • Tham số thứ nhất là tên component
  • Tham số thứ hai là tên cú pháp thay thế

Bây giờ bạn có thể khai báo component

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
45 theo cú pháp sau:

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
8

Bạn có thể test để so sánh kết quả, đảm bảo vẫn không thay đổi gì.

IV. Hiển thị dữ liệu (Displaying data)

Bạn có thể hiện thị dữ liệu được truyền đến blade view bằng cách đặt biến đó giữa cặp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
59, ví dụ mình đăng ký một route:

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
9

Tiếp đó các bạn tạo blade view

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
60 và code nó như sau:

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

Đây là kết quả chúng ta thu được:

Như bạn thấy cú pháp này vô cùng ngắn gọn để hiển thị

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
61 thay vì phải code dài như thế này:

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

Lưu ý: Bạn chỉ có thể sử dụng các cú pháp của Blade template khi đuôi mở rộng có dạng

resources/
├── views/
|   ├── components/
|   |   |   ...
1. Bạn chỉ có thể sử dụng các cú pháp của Blade template khi đuôi mở rộng có dạng
resources/
├── views/
|   ├── components/
|   |   |   ...
1.

1. Displaying unescaped data

Giờ các bạn thử chèn cặp thẻ

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
63 cho giá trị
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
61 như thế này:

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

Đoán xem chữ "Lê Chí Huy" có được bôi đen không? Đáp án là "Không". Vì cú pháp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
59 trước khi hiển thị dữ liệu thì nó đã đưa qua hàm
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
66, việc này sẽ tránh các cuộc tất công XSS. Nói một cách đơn giản thì kiểu tấn công này lợi dụng việc có thể hiển thị các thẻ HTML thông qua chức năng viết bài, comment... để chèn mã script độc, tấn công hệ thống.

Vậy nếu giờ bạn muốn chèn HTML vào dữ liệu của mình thì sao? Laravel không tuyệt đường bất kỳ mong muốn nào của coder cả, họ cung cấp cho chúng ta cú pháp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
67 để có thể hiển thị cả mã HTML

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

Một kết quả đầy mong đợi:

Lưu ý: Để tránh bị tân công XSS, bạn nên dùng cú pháp này show các dữ liệu do bạn xác định, admin cpanel xác định chứ không nên show các dữ liệu do người dùng nhập như viết bài, comment... để tránh chèn mã độc. Để tránh bị tân công XSS, bạn nên dùng cú pháp này show các dữ liệu do bạn xác định, admin cpanel xác định chứ không nên show các dữ liệu do người dùng nhập như viết bài, comment... để tránh chèn mã độc.

Cú pháp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
59 không giới hạn việc hiển thị dữ liệu của biến truyền vào blade view. Bạn có thể
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
69 kết quả bất kì hàm PHP nào, chẳng hạn như:

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

2. Rendering JSON

Nếu bạn truyền một mảng đến blade view và muốn render nó như một JSON để gán giá trị cho biến nào đó trong đoạn mã script. Thông thường với PHP, bạn sẽ:

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

Nhưng đối với Blade template Laravel thì cú pháp sẽ gọn đi rất nhiều. Thay vì gọi thủ công như thế thì ta có thể sử dụng cú pháp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
70, nó sẽ nhận các tham số tương tự như
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
71.

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

Nếu như bạn truyền

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
70 trong một thuộc tính của thẻ thì nên để trong nó trong cặp dấu
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
73.

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

3. Blade & JavaScript Frameworks

Có một số Javascript framework sử dụng cặp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
74 làm cú pháp của mình, chính vì thế đôi khi Blade template sẽ hiểu nhầm là cú pháp của nó và compile, có thể gây lỗi. Để tránh điều đó, bạn chỉ cần thêm ký tự
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
75 trước câu lệnh thì Blade template sẽ hiểu nó không phải là cú pháp cần compile.

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

Đây là kết quả:

Nếu trong trường hợp có nhiều cú pháp Javascript framework có chứa cặp

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
74 mà bạn không muốn phải cất công thêm tiền tố
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
75 trước từng câu lệnh. Laravel cung cấp cho chúng ta một giải pháp đó chính là đưa tất cả các cú pháp Javascript framework ấy vào trong cặp thẻ
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
78 như thế này:

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

V. Cấu trúc điều khiển (Control structure)

Ngoài các tính năng lợi ích trên, Laravel còn cung cấp cho chúng ta các cú pháp ngắn gọn cho các cấu trúc điều khiển của PHP như if, for, foreach... Những cú pháp này rất thuận tiện, nhanh gọn nhưng lại không làm mất đi bản chất vốn có của các cấu trúc điều khiển.

1. Câu lệnh "if" ("if" statement)

Bạn có thể khởi tạo câu lệnh

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
79 bằng các thẻ
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
80,
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
81,
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
82 và
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
83.

@section('content')
    <h2>My content</h2>
@endsection
0

Như bạn thấy, chỉ là cú pháp khác, cách khai báo các điều kiện và hoạt động vẫn không khác gì cấu trúc điều kiện thuần túy.

Blade template cung cấp cho chúng ta thẻ

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
84:

@section('content')
    <h2>My content</h2>
@endsection
1

Phương thức

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
85 là dùng để kiểm tra xem user có đăng nhập hay chưa. Hiện tại chúng ta chưa học tới nên chắn chắc method này sẽ trả về giá trị là
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
86. Nếu các bạn đã học qua chương trình tiếng Anh phổ cập thì sẽ biết
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
87 đồng nghĩa với
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
88.

Ngoài ra còn có

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
89 và
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
90, hai thẻ này đại diện cho hai hàm quen thuộc trong PHP là
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
91 và
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
92.

@section('content')
    <h2>My content</h2>
@endsection
2

a. Authentication

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
93 và
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
94 và hai thẻ dùng để kiểm tra xem user hiện tại có đăng nhập hay chưa.

@section('content')
    <h2>My content</h2>
@endsection
3

Ngoài ra bạn có thể truyền tham số cho hai thẻ này để kiểm tra trạng thái đăng nhập của user với tư cách là ai. Chẳng hạn một tài khoản có vai trò là "user" thì sau khi đăng nhập vẫn không thể truy cập vào admin cpanel được. Tính năng này được gọi là "Authentication Guard", chúng ta sẽ tìm hiểu sau.

@section('content')
    <h2>My content</h2>
@endsection
4

b. Section

Bạn có thể kiểm tra sự tồn tại của một section bằng thẻ

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
95 với tham số truyền vào là tên của section cần kiểm tra.

@section('content')
    <h2>My content</h2>
@endsection
5

2. Câu lệnh "switch" ("switch" statement)

Lệnh switch được khởi tạo bằng các thẻ

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
96,
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
97,
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
98,
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
99 và
Route::get('/', function() {
    return view('child');
});
00.

@section('content')
    <h2>My content</h2>
@endsection
6

3. Vòng lặp (Loop)

Cũng giống như các cấu trúc điều khiển khác, các câu lệnh loop trong Blade template vẫn được giữ nguyên cách thức hoạt động.

@section('content')
    <h2>My content</h2>
@endsection
7

Laravel cung cấp cho chúng ta thẻ

Route::get('/', function() {
    return view('child');
});
01, thẻ này hoạt động giống như là
Route::get('/', function() {
    return view('child');
});
02 nhưng ta có thể kiểm tra nhanh xem object tham chiếu trong loop có rỗng hay không, nếu có thì sẽ thực thi lệnh gì đó thông qua thẻ
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
90.

Bạn có thể test đoạn code này thì sẽ hiểu rõ thẻ

Route::get('/', function() {
    return view('child');
});
01 ngay.

@section('content')
    <h2>My content</h2>
@endsection
8

Như quan sát, mình đã truyền một mảng rỗng vào vòng lặp, lặp tức thì nó sẽ được kiểm tra qua thẻ

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
90. Kết qua ta thu được sẽ là:

Nói về vòng lặp thì không thể thiếu

Route::get('/', function() {
    return view('child');
});
06 và
Route::get('/', function() {
    return view('child');
});
07 được, đương nhiên hai lệnh này vẫn được Blade template chuyển cú pháp thành
Route::get('/', function() {
    return view('child');
});
08 và
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
98.

@section('content')
    <h2>My content</h2>
@endsection
9

Nếu bạn thấy mỗi lần muốn

Route::get('/', function() {
    return view('child');
});
07 hoặc
Route::get('/', function() {
    return view('child');
});
06 phải lồng trong một câu lệnh
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
79 thì hơi dài và khá rối mắc. Chính vì thế Laravel cho phép bạn truyền điều kiện vào hai thẻ
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
98 và
Route::get('/', function() {
    return view('child');
});
08 để rút ngắn thời gian cho bạn.

@section('sidebar')
    <h2>Sidebar</h2>
@show
0

4. Biến vòng lặp (The loop variable)

Khi sử dụng các lệnh vòng lặp

Route::get('/', function() {
    return view('child');
});
15,
Route::get('/', function() {
    return view('child');
});
16 mặc định sẽ có sẵn
Route::get('/', function() {
    return view('child');
});
17 bên trong vòng lặp. Biến này cho phép ta lấy các thông tin hay sử dụng như index hiện tại, index đầu, index cuối vòng lặp...

@section('sidebar')
    <h2>Sidebar</h2>
@show
1

Nếu bạn có các vòng lặp lồng nhau thì có thể tham chiếu

Route::get('/', function() {
    return view('child');
});
17 của vòng lặp cha bằng thuộc tính
Route::get('/', function() {
    return view('child');
});
19 trong vòng lặp con.

@section('sidebar')
    <h2>Sidebar</h2>
@show
2

Dưới đây là toàn bộ các thông tin là

Route::get('/', function() {
    return view('child');
});
17 có thể cung cấp:

Thuộc tínhMô tả
Route::get('/', function() {
    return view('child');
});
21
Lấy index hiện tại (bắt đầu từ 0)
Route::get('/', function() {
    return view('child');
});
22
Lấy số lần đã lặp hiện tại (bắt đầu từ 1)
Route::get('/', function() {
    return view('child');
});
23
Lấy số lần lặp còn lại
Route::get('/', function() {
    return view('child');
});
24
Lấy tổng số vòng lặp sẽ lặp
Route::get('/', function() {
    return view('child');
});
25
Nếu tại vòng lặp đầu tiên thì trả về
Route::get('/', function() {
    return view('child');
});
26
Route::get('/', function() {
    return view('child');
});
25
Nếu tại vòng lặp đầu tiên thì trả về
Route::get('/', function() {
    return view('child');
});
26
Nếu tại vòng lặp cuối cùng thì trả về
Route::get('/', function() {
    return view('child');
});
26
Route::get('/', function() {
    return view('child');
});
29
Nếu index vòng lặp hiện tại chẵn thì trả về
Route::get('/', function() {
    return view('child');
});
26
Route::get('/', function() {
    return view('child');
});
31
Nếu index vòng lặp hiện tại lẻ thì trả về
Route::get('/', function() {
    return view('child');
});
26
Route::get('/', function() {
    return view('child');
});
33
Lấy độ sâu của vòng lặp hiện tại
Route::get('/', function() {
    return view('child');
});
34

Lấy Route::get('/', function() { return view('child'); }); 17 của vòng lặp cha trong vòng lặp con

5. Comment

@section('sidebar')
    <h2>Sidebar</h2>
@show
3

Blade template cũng cho phép chúng ta comment để code dễ hiểu, dễ quản lý hơn với cú pháp:

6. PHP

@section('sidebar')
    <h2>Sidebar</h2>
@show
4

Bạn cũng có thể chèn code PHP vào trong Blade template trong cặp thẻ

Route::get('/', function() {
    return view('child');
});
36. Bạn không nên qua lạm dụng thể này để thực thi một số xử lý logic phức tạp, điều này sẽ làm mất bản chất của view. Với các xử lý logic phức tạp, bạn nên thực thi ở view composer hoặc controller action, sau đó mới truyền đến view đển render.

Lưu ý: Bạn không nên qua lạm dụng thể này để thực thi một số xử lý logic phức tạp, điều này sẽ làm mất bản chất của view. Với các xử lý logic phức tạp, bạn nên thực thi ở view composer hoặc controller action, sau đó mới truyền đến view đển render.

VI. Form

1. Trường CSRF (CSRF field)

Bạn còn nhớ vấn đề ở tập Routing chứ, chúng ta không thể truy cập route với phương thức

Route::get('/', function() {
    return view('child');
});
37, cũng như là
Route::get('/', function() {
    return view('child');
});
38,
Route::get('/', function() {
    return view('child');
});
39... vì thiếu CSRF field này. Vì vậy khi khởi tạo một HTML form thì chúng ta phải khái báo CSRF field thông qua thẻ
Route::get('/', function() {
    return view('child');
});
40.

@section('sidebar')
    <h2>Sidebar</h2>
@show
5

Giờ mình sẽ tạo blade view

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
60 với nội dung sau:

Form này sẽ gửi một request với method

Route::get('/', function() {
    return view('child');
});
37 với URI
Route::get('/', function() {
    return view('child');
});
43 khi submit.

@section('sidebar')
    <h2>Sidebar</h2>
@show
6

Sau đó các bạn đăng ký hai route này trong

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

Với route đầu tiên thì sẽ render view chứa form của chúng ta. Còn route thứ hai mang phương thức

Route::get('/', function() {
    return view('child');
});
37 sẽ được gọi khi chúng ta click vào nút "Send post".

Bây giờ ta hãy thử truy cập đường dẫn http://localhost:8000 và F12 lên để xem source HTML của form vừa tạo.

Route::get('/', function() { return view('child'); }); 40 đã tạo một input hidden với name là Route::get('/', function() { return view('child'); }); 47 và value chứa CSRF token, có field này chắc chắn ta sẽ gửi được request với method Route::get('/', function() { return view('child'); }); 37. Việc cuối cùng là click vào nút "Send post" thôi.

2. Trường phương thức (Method field)

Đối với những phương thức khác như

Route::get('/', function() {
    return view('child');
});
38,
Route::get('/', function() {
    return view('child');
});
39 và
Route::get('/', function() {
    return view('child');
});
51 ta không thể khai báo trong thuộc tính
Route::get('/', function() {
    return view('child');
});
52 của thẻ
Route::get('/', function() {
    return view('child');
});
53 được, chính vì vậy Laravel cung cấp cho ta thẻ
Route::get('/', function() {
    return view('child');
});
54 để khai báo một Unsafe HTTP method khác ngoài
Route::get('/', function() {
    return view('child');
});
37.

@section('sidebar')
    <h2>Sidebar</h2>
@show
7

Các bạn thêm thẻ

Route::get('/', function() {
    return view('child');
});
54 với tham số
Route::get('/', function() {
    return view('child');
});
38 này như sau:

Sau đó thử click nút "Send post" lại xem, chắc chắn xuất hiện lỗi:

@section('sidebar')
    <h2>Sidebar</h2>
@show
8

Vì chúng ta đã thay đổi HTTP request thành Route::get('/', function() { return view('child'); }); 38 nên ở route đăng ký cũng phải thay đổi.

3. Validation error

@section('sidebar')
    <h2>Sidebar</h2>
@show
9

Với cặp thẻ

Route::get('/', function() {
    return view('child');
});
59 ta có thể dễ dàng bắt bất kỳ thông báo nào khi request trả về lỗi. Về "Validation error message" ta sẽ tìm hiểu ở những tập sau nên phần này mình chỉ nó qua về cú pháp để kiểm tra có tồn tại lỗi được trả về tại blade template hay không.

Route::get('/', function() { return view('child'); }); 60 sẽ nhận tham số là tên lỗi mà chúng ta xử lý trước khi trả về cho blade view. Nếu Route::get('/', function() { return view('child'); }); 26 thì nó sẽ thực thị lệnh trong cặp thẻ.

VII. Liên kết sub-view (Including sub-view)

Route::get('/', function() {
    return view('child');
});
62 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.

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
0

Chẳng hạn mình có cấu trúc thư mục như sau:

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
1

Ở blade view

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
60 ta code:

Như các bạn thấy, mình đã sử dụng cú pháp

Route::get('/', function() {
    return view('child');
});
62 với tham số là tên view liên kết cần đưa vào blade view
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
60 này. Ngoài ra mình có khai báo biến
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
61 để thử xem là blade view
Route::get('/', function() {
    return view('child');
});
67 có nhận được hay không.

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
2

Tại blade view

Route::get('/', function() {
    return view('child');
});
67 mình code như sau:

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
3

Cuối cùng là đăng ký route để render blade view

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
60 ra:

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
4

Kết quả này chứng minh cho việc 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ẻ Route::get('/', function() { return view('child'); }); 62.

1. Một số cú pháp khác hỗ trợ cho include (Some other syntax support for including)

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
5

Trong trường hợp nếu bạn

Route::get('/', function() {
    return view('child');
});
62 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ẻ
Route::get('/', function() {
    return view('child');
});
72 thay cho
Route::get('/', function() {
    return view('child');
});
62.

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
6

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

Route::get('/', function() {
    return view('child');
});
26.

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
7

Như dòng code này, nếu view

Route::get('/', function() {
    return view('child');
});
76 tồn tại thì nó sẽ include view này và bỏ qua view
Route::get('/', function() {
    return view('child');
});
77. Còn nếu view
Route::get('/', function() {
    return view('child');
});
76 không tồn tại thì nó sẽ bỏ qua và tiếp tục kiểm tra view
Route::get('/', function() {
    return view('child');
});
77.

Lưu ý: Bạn nên tránh sử dụng

Route::get('/', function() {
    return view('child');
});
80 và
Route::get('/', function() {
    return view('child');
});
81 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.
Bạn nên tránh sử dụng
Route::get('/', function() {
    return view('child');
});
80 và
Route::get('/', function() {
    return view('child');
});
81 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.

2. 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

@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
54, ngay tại method
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
55.

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
8

Rồi bây giờ ta chỉ cần include view

Route::get('/', function() {
    return view('child');
});
67 theo cú pháp đã đăng ký:

@section('sidebar')
    @parent

    <ul>
        <li>Item 1</li>
        <li>Item 1</li>
    </ul>
@endsection
9

3. Rendering views for collections

Nếu bạn có một mảng dữ liệu và muốn truyền từng dữ liệu vào một view nào đó thì bạn có thể sử dụng

Route::get('/', function() {
    return view('child');
});
85 thay vì
Route::get('/', function() {
    return view('child');
});
02 và
Route::get('/', function() {
    return view('child');
});
62.

Chẳng hạn mình có cấu trúc thư mục như sau:

@section('title', 'Laravel')
0

Đầu tiên mình sẽ thử sử dụng cách thông thường đó là dùng

Route::get('/', function() {
    return view('child');
});
02 và
Route::get('/', function() {
    return view('child');
});
62. Tại blade view
Route::get('/', function() {
    return view('child');
});
90 mình sẽ code nội dung như sau:

@section('title', 'Laravel')
1

Và blade view

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

@section('title', 'Laravel')
2

Sau đó chúng ta đăng ký route và chạy thử:

@section('title', 'Laravel')
3

Bây giờ chúng ta sẽ dùng

Route::get('/', function() {
    return view('child');
});
85 để thay thế cách trên. Ta chỉ cần thay đổi đoạn vòng lặp trong blade view
Route::get('/', function() {
    return view('child');
});
93.

@section('title', 'Laravel')
4

Route::get('/', function() {
    return view('child');
});
85 này sẽ nhận:

  • 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ư ở

Route::get('/', function() {
    return view('child');
});
85 với giá trị là tên view chứa nội dung thông báo.

@section('title', 'Laravel')
5

Lưu ý: Các view được render thông qua

Route::get('/', function() {
    return view('child');
});
85 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
Route::get('/', function() {
    return view('child');
});
02 và
Route::get('/', function() {
    return view('child');
});
62 để thay thế nếu các view include cần những biến dữ liệu này.
Các view được render thông qua
Route::get('/', function() {
    return view('child');
});
85 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
Route::get('/', function() {
    return view('child');
});
02 và
Route::get('/', function() {
    return view('child');
});
62 để thay thế nếu các view include cần những biến dữ liệu này.

VIII. Stacks

Nói về thuật ngữ này bằng văn bản thì rất khó hình dung nên mình sẽ đi qua ví dụ để các bạn thấy công dụng, từ đó có thể hiểu được nó. Chẳng hạn trong ứng dụng của bạn có rất nhiều trang con, tất cả các trang con đều được include với một file JS chung. Một số trang con đặc biệt sẽ có file JS riêng để xử lý.

Đây là cấu trúc thư mục cho ví dụ:

@section('title', 'Laravel')
6

Ở blade view

Route::get('/', function() {
    return view('child');
});
99, ta có nội dung sau:

@section('title', 'Laravel')
7

Còn blade view

@section('content')
    <h2>My content</h2>
@endsection
00 thì:

@section('title', 'Laravel')
8

Bây giờ mình muốn include file JS

@section('content')
    <h2>My content</h2>
@endsection
01 thì cách nhanh nhất là bỏ dòng code include JS vào trong section
@section('content')
    <h2>My content</h2>
@endsection
02 ở blade view
@section('content')
    <h2>My content</h2>
@endsection
03 như thế này:

@section('title', 'Laravel')
9

Cách trên thì có thể code vẫn hoạt động bình thường nhưng sẽ cảm thấy một chút gì đó rất khó chịu, có thể gây một số phiền phức sau này như không tốt cho SEO hoặc bất đồng bộ trong code Javascript.

Laravel cung cấp cho ta một giải pháp để giải quyết tình huống trên dựa vào hai thẻ

@section('content')
    <h2>My content</h2>
@endsection
04 và
@section('content')
    <h2>My content</h2>
@endsection
05. Bạn hãy tưởng tưởng
@section('content')
    <h2>My content</h2>
@endsection
04 giống như một kệ sách, còn
@section('content')
    <h2>My content</h2>
@endsection
05 giống như những cuốn sách, dù bạn đặt những cuốn sách ở đâu thì sau quá trình dọn dẹp (biên dịch) thì những cuốn sách sẽ được đưa vào kệ sách.

Tức là bây giờ mình muốn đưa cuốn sách

@section('content')
    <h2>My content</h2>
@endsection
08 vào một kệ sách nào đó trong
@section('content')
    <h2>My content</h2>
@endsection
09 thì mình phải khai báo kệ sách đó trước đã.

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
0

Như các bạn thấy mình đã khởi tạo một kệ sách với tên là

@section('content')
    <h2>My content</h2>
@endsection
10 rồi, việc cần làm bây giờ là đưa cuốn sách
@section('content')
    <h2>My content</h2>
@endsection
08 về kệ sách
@section('content')
    <h2>My content</h2>
@endsection
10 thôi.

Tại blade view

@section('content')
    <h2>My content</h2>
@endsection
03, mình chỉnh sửa nội dung lại như sau:

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
1

Giờ chắc các bạn đã hiểu cách hoạt động của

@section('content')
    <h2>My content</h2>
@endsection
04 và
@section('content')
    <h2>My content</h2>
@endsection
05 rồi đúng không nào. Ngoài ra, Laravel còn cung cấp thẻ
@section('content')
    <h2>My content</h2>
@endsection
16, thẻ này giúp ta sẽ thêm cuốn sách "yêu thích" nào đó vào đầu ngăn sách.

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
2

IX. Service injection

Cái này chắc đã quá quen thuộc rồi, Laravel cho phép chúng ta lấy một service bất kỳ có trong service container thông qua

@section('content')
    <h2>My content</h2>
@endsection
17.

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
3

X. Mở rộng Blade (Extending Blade)

Laravel cho phép chúng ta tự định nghĩa các thẻ bằng phương thức

@section('content')
    <h2>My content</h2>
@endsection
18 có trong
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
53 facade. Việc này đương nhiên chúng ta cũng sẽ code trong
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
55 của
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
54.

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
4

Quan sát đoạn code trên, tại method

@section('content')
    <h2>My content</h2>
@endsection
22:

  • Tham số thứ nhất là tên thẻ
  • Tham số thứ hai là một Closure object, nó sẽ chứa biến dữ liệu nhận được qua các tham số của thẻ trong blade view. Trong Closure này, ta sẽ
    @section('content')
        <h2>My content</h2>
    @endsection
    
    23 mã PHP được viết dưới dạng chuỗi.

Sau khi đăng ký xong, ta có thể test thẻ

@section('content')
    <h2>My content</h2>
@endsection
24 như sau:

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
5

Nếu bạn muốn truyền nhiều tham số cho thẻ của mình thì bạn có thể xử lý chuỗi

@section('content')
    <h2>My content</h2>
@endsection
25 để lấy các giá trị tham số.

Để mình test cho các bạn xem, tại Closure object mình sẽ dump

@section('content')
    <h2>My content</h2>
@endsection
25.

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
6

Sau đó mình thử gọi

@section('content')
    <h2>My content</h2>
@endsection
24 và truyền nhiều tham số vào nó:

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
7

Đây là kết quả:

Như các bạn thấy,

@section('content')
    <h2>My content</h2>
@endsection
25 trả về chuỗi với dạng:

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
8

Các bạn có thể tùy biến để có thể lấy các giá trị tham số từ

@section('content')
    <h2>My content</h2>
@endsection
25.

Lưu ý: Trong khi phát triển ứng dụng, nếu có sử dụng thẻ riêng trong blade view thì sau mỗi lần sửa đổi code xử lý trong mỗi thẻ riêng thì phải chạy lệnh Artisan

@section('content')
    <h2>My content</h2>
@endsection
30 để xóa cache và compile lại các view. Trong khi phát triển ứng dụng, nếu có sử dụng thẻ riêng trong blade view thì sau mỗi lần sửa đổi code xử lý trong mỗi thẻ riêng thì phải chạy lệnh Artisan
@section('content')
    <h2>My content</h2>
@endsection
30 để xóa cache và compile lại các view.

Ngoài ra bạn cũng có thể tự tạo cho mình lệnh điều kiện riêng có thể gọi trong blade view bằng method

@section('content')
    <h2>My content</h2>
@endsection
31 được đăng ký tại
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
55 của
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
54.

// Nhận giá trị mặc định là view
@yield('content', View::make('view.name'))

// Nhận giá trị mặc định là một chuỗi
@yield('content', 'default')
9

Với

@section('content')
    <h2>My content</h2>
@endsection
31 thì:

  • Tham số thứ nhất là tên lệnh điều kiện,
  • Tham số thứ hai là Closure nhận biến giá trị truyền vào và trả về boolean

Như đăng ký trên, nó sẽ kiểm tra môi trường hiện tại của ứng dụng, nếu trùng khớp thì sẽ trả về

Route::get('/', function() {
    return view('child');
});
26, còn không thì trả về
@extends('app')

@section('content')
    <h2>My content</h2>
@endsection
86.

Ta có thể sử dụng trong blade view như sau:

resources/
├── views/
|   ├── components/
|   |   |   ...
0

Cảm ơn các bạn đã quan tâm theo dõi. Cùng đồng hành với mình qua những tập tiếp theo tại series "Hành trình chinh phục Laravel Framework" nhé! Chúc may mắn và hẹn gặp lại.

Mình đang xây dựng blog riêng là lechihuy.dev , mong các bạn ghé sang ủng hộ, mình cảm ơn rất nhiều ạ