NTM Solutions

Bài đăng nổi bật

🚀 Laravel 12 (2026) — Từ PHP Core đến Full Stack📘

Nếu cập nhật theo Laravel 12 LTS (2026) thì mình sẽ chia thành các phần như sau để người học đi từ PHP Core → Laravel → Triển khai dự án th...

Thứ Sáu, 10 tháng 7, 2026

🚀 Laravel 12 (2026) — Bài 05 — Blade Template Engine: Xây dựng giao diện

Ở bài trước, chúng ta đã học cách sử dụng Controller để xử lý logic của ứng dụng.

Tuy nhiên, nếu Controller vừa xử lý dữ liệu vừa chứa toàn bộ mã HTML thì mã nguồn sẽ rất khó đọc và khó bảo trì.

Laravel giải quyết vấn đề này bằng Blade Template Engine – hệ thống template được tích hợp sẵn trong Laravel.


Blade là gì?

Blade là Template Engine của Laravel, giúp tách phần giao diện khỏi phần xử lý nghiệp vụ.

Mô hình hoạt động:

Request
    ↓
Route
    ↓
Controller
    ↓
Model (nếu có)
    ↓
Blade View
    ↓
HTML

Nhờ Blade, chúng ta có thể:

  • Viết giao diện sạch sẽ.

  • Tái sử dụng các thành phần giao diện.

  • Tránh lặp lại mã HTML.

  • Hiển thị dữ liệu an toàn.


Tạo View đầu tiên

Trong Laravel, giao diện nằm trong:

resources/views/

Tạo:

resources/views/home.blade.php

Nội dung:

<h1>Xin chào Laravel 13</h1>

Controller:

public function index()
{
    return view('home');
}

Laravel sẽ tìm:

resources/views/home.blade.php

Truyền dữ liệu sang Blade

Controller:

public function index()
{
    $title = 'Học Laravel 13';

    return view('home', compact('title'));
}

Blade:

<h1>{{ $title }}</h1>

{{ }} dùng để hiển thị dữ liệu và Blade tự động escape HTML, giúp giảm nguy cơ XSS.


Viết PHP trong Blade

Điều kiện

@if($age >= 18)
    Người lớn
@else
    Trẻ em
@endif

Vòng lặp

@foreach($posts as $post)
    <p>{{ $post->title }}</p>
@endforeach

Vòng lặp for

@for($i = 1; $i <= 5; $i++)
    {{ $i }}
@endfor

Layout trong Blade

Một website thường có:

  • Header

  • Navigation

  • Footer

  • Nội dung

Thay vì lặp lại HTML trên từng trang, Laravel cho phép chúng ta tạo layout dùng chung.

Laravel 13 hỗ trợ hai cách tổ chức layout chính:

  1. Template inheritance với @extends, @section, @yield.

  2. Blade Component Layout với <x-...> và $slot. (Laravel)

Trong project Laravel 13 hiện tại của chúng ta, chúng ta sẽ ưu tiên Blade Component Layout.


Blade Component Layout

Ví dụ tạo layout:

resources/views/components/layout.blade.php

Nội dung:

<!DOCTYPE html>
<html lang="vi">

<head>
    <meta charset="UTF-8">

    <meta name="viewport"
          content="width=device-width, initial-scale=1">

    <title>{{ $title ?? 'Laravel 13' }}</title>
</head>

<body>

    <header>
        <h1>Laravel 13</h1>
    </header>

    <main>
        {{ $slot }}
    </main>

    <footer>
        &copy; {{ date('Y') }}
    </footer>

</body>

</html>

Ở đây:

{{ $slot }}

là vị trí Laravel đưa nội dung của trang con vào layout. Đây là cơ chế slot của Blade Component. (Laravel)

Trang sử dụng layout:

<x-layout>

    <h2>Trang chủ</h2>

    <p>Xin chào Laravel 13.</p>

</x-layout>

Laravel sẽ đưa phần:

<h2>Trang chủ</h2>

<p>Xin chào Laravel 13.</p>

vào:

{{ $slot }}

Layout Component dạng Class

Laravel cũng hỗ trợ class-based Component.

Tạo:

php artisan make:component BlogLayout

Laravel sẽ tạo Component class trong:

app/View/Components/

và view component tương ứng trong:

resources/views/components/

Laravel tự động phát hiện các Component trong các vị trí chuẩn này. (Laravel)

Ví dụ:

app/
└── View/
    └── Components/
        └── BlogLayout.php

resources/
└── views/
    └── components/
        └── blog-layout.blade.php

Class:

<?php

namespace App\View\Components;

use Illuminate\View\Component;
use Illuminate\View\View;

class BlogLayout extends Component
{
    public function render(): View
    {
        return view('components.blog-layout');
    }
}

Sau đó sử dụng:

<x-blog-layout>

    <h1>Blog</h1>

</x-blog-layout>

Ví dụ Blog Layout

Trong project của chúng ta, Blog là khu vực public nên có thể tạo layout riêng:

resources/views/components/blog-layout.blade.php
<!DOCTYPE html>
<html lang="vi">

<head>

    <meta charset="UTF-8">

    <meta name="viewport"
          content="width=device-width, initial-scale=1">

    <title>{{ $title ?? 'Blog' }}</title>

    @vite(['resources/css/app.css', 'resources/js/app.js'])

</head>

<body>

    <header>
        <h1>
            <a href="{{ route('blog.index') }}">
                Blog
            </a>
        </h1>
    </header>

    <main>
        {{ $slot }}
    </main>

    <footer>
        &copy; {{ date('Y') }}
    </footer>

</body>

</html>

Trang Blog:

<x-blog-layout>

    <h1>Danh sách bài viết</h1>

</x-blog-layout>

Như vậy:

<x-blog-layout>
        ↓
BlogLayout Component
        ↓
resources/views/components/blog-layout.blade.php
        ↓
{{ $slot }}

<x-app-layout> trong project Laravel 13

Trong project thực tế của chúng ta, cấu trúc Component cần được kiểm tra theo project, không nên mặc định suy ra rằng:

<x-app-layout>

luôn tương ứng với:

resources/views/components/app-layout.blade.php

Laravel hỗ trợ cả anonymous component và class-based component; class-based component được đặt trong app/View/Components, còn view của component được đặt trong resources/views/components. (Laravel)

Trong project hiện tại, app-layout đang được xử lý thông qua Component class và render layout tương ứng.

Vì vậy khi gặp:

<x-app-layout>

hãy kiểm tra:

app/View/Components/

để xem Component class thực tế.


@extends vẫn dùng được

Blade Component không có nghĩa là Laravel 13 bỏ @extends.

Template inheritance vẫn được hỗ trợ:

Layout:

<!DOCTYPE html>
<html>

<head>
    <title>Laravel 13</title>
</head>

<body>

    @yield('content')

</body>

</html>

Trang con:

@extends('layouts.app')

@section('content')

    <h1>Trang chủ</h1>

@endsection

@section sẽ đưa nội dung vào vị trí @yield.

Laravel 13 vẫn có cơ chế compile cho @extends, @section, @yield và các directive layout này. (Laravel API)

Vì vậy không nên viết trong giáo trình rằng @extends là lỗi thời hoặc không còn dùng.


@include

Những phần giao diện dùng nhiều lần có thể tách riêng:

resources/views/partials/
├── header.blade.php
├── menu.blade.php
└── footer.blade.php

Sử dụng:

@include('partials.header')

@include('partials.menu')

@yield('content')

@include('partials.footer')

@include phù hợp với những đoạn HTML đơn giản được tái sử dụng.


Blade Component

Đối với những thành phần giao diện có tính tái sử dụng như:

  • Button

  • Card

  • Alert

  • Modal

  • Navigation

  • Form Input

có thể tạo Component:

php artisan make:component Alert

Laravel tạo Component class:

app/View/Components/Alert.php

và view:

resources/views/components/alert.blade.php

Sử dụng:

<x-alert>
    Lưu dữ liệu thành công.
</x-alert>

Trong view component, nội dung giữa:

<x-alert>

    Nội dung

</x-alert>

được nhận thông qua:

{{ $slot }}

Đây chính là cơ chế Component Slot của Blade. (Laravel)


Comment trong Blade

Comment Blade:

{{-- Đây là comment Blade --}}

không được gửi ra HTML của trình duyệt.

Khác với:

<!-- HTML Comment -->

HTML comment vẫn xuất hiện trong mã nguồn HTML.


Escape HTML

Blade mặc định escape dữ liệu:

{{ $content }}

Nếu muốn render HTML:

{!! $content !!}

Ví dụ Blog của chúng ta có:

$post->content

và nội dung được lưu dưới dạng HTML, có thể dùng:

{!! $post->content !!}

Chỉ sử dụng {!! !!} với dữ liệu HTML mà bạn tin tưởng hoặc đã được xử lý an toàn.


Cấu trúc thư mục Laravel 13

Với project hiện tại, có thể tổ chức:

resources/
└── views/
    ├── admin/
    ├── auth/
    ├── blog/
    │   ├── index.blade.php
    │   └── show.blade.php
    │
    ├── components/
    │   ├── alert.blade.php
    │   ├── blog-layout.blade.php
    │   └── ...
    │
    ├── layouts/
    │   ├── app.blade.php
    │   └── ...
    │
    └── ...

Trong đó:

blog/
    ↓
Các trang Blog

components/
    ↓
Các Blade Component

layouts/
    ↓
Các layout được Component class sử dụng

admin/
    ↓
Các trang quản trị

auth/
    ↓
Các trang xác thực

Tổng kết

Sau bài học này, bạn đã biết:

  • Blade Template Engine là gì.

  • Tạo View trong Laravel 13.

  • Truyền dữ liệu từ Controller sang View.

  • Hiển thị dữ liệu với {{ }}.

  • Sử dụng @if, @foreach, @for.

  • Tạo layout với @extends, @section, @yield.

  • Tái sử dụng giao diện với @include.

  • Tạo Blade Component.

  • Phân biệt Anonymous Component và Class-based Component.

  • Hiểu $slot trong Blade Component.

  • Tạo layout riêng bằng <x-blog-layout>.

  • Hiểu Component class nằm trong app/View/Components.

  • Hiểu view Component nằm trong resources/views/components.

  • Hiểu cơ chế escape HTML của Blade.

Ở bài tiếp theo, chúng ta sẽ bắt đầu làm việc với cơ sở dữ liệu bằng cách cấu hình Database, kết nối MySQL và thực hiện Migration đầu tiên trong Laravel 13.

Không có nhận xét nào:

Đăng nhận xét

Facebook Youtube RSS