
Chào các bạn, tôi là Creyt đây! Hôm nay chúng ta sẽ cùng mổ xẻ một trong những viên ngọc quý của Laravel Blade: @extends. Thử nghĩ xem, có bao giờ bạn thấy một trang web mà phần đầu trang (header) và chân trang (footer) cứ lặp đi lặp lại trên mọi trang con chưa? Chắc chắn rồi! Và nếu không có @extends, bạn sẽ phải copy-paste hàng tá code HTML đó vào từng file view một. Nghe thôi đã thấy đau đầu rồi phải không? @extends chính là vị cứu tinh của chúng ta!
Blade Extends là gì? Để làm gì?
Nói nôm na, @extends là cơ chế cho phép bạn định nghĩa một 'bố cục chính' (master layout) và sau đó, các 'bố cục con' (child views) có thể kế thừa toàn bộ cấu trúc của bố cục chính, chỉ việc 'điền vào chỗ trống' mà thôi.
Nó giống như việc bạn có một bản thiết kế nhà mẫu. Bản thiết kế này có sẵn móng, cột, mái, và các vị trí cửa sổ, cửa ra vào đã được định trước. Các căn nhà con chỉ cần dựa vào đó mà xây, chỉ tùy chỉnh nội thất, màu sơn bên trong mà không cần phải xây lại từ đầu cái móng hay cái mái. Cái khung sườn chính là layout của bạn, còn các 'phòng ốc' bạn điền vào là các section.
Mục tiêu tối thượng? DRY (Don't Repeat Yourself) – Đừng lặp lại chính mình! Giúp code sạch sẽ, dễ bảo trì, và khi cần thay đổi header, bạn chỉ cần sửa một chỗ trong layout chính là toàn bộ các trang con đều được cập nhật theo. Quá tiện lợi phải không?
Cách hoạt động của Blade Extends và @section
Để sử dụng @extends, chúng ta cần hai thành phần chính:
-
Bố cục chính (Master Layout): Đây là file Blade chứa cấu trúc HTML chung của trang web (ví dụ:
<html>,<head>,<body>, header, footer). Trong layout này, bạn sẽ định nghĩa các 'điểm neo' (placeholder) bằng directive@yield('tên_section'). Các điểm neo này sẽ là nơi mà các trang con sẽ 'điền' nội dung của chúng vào. -
Bố cục con (Child View): Đây là các file Blade cụ thể cho từng trang (ví dụ: trang chủ, trang giới thiệu). Các trang này sẽ sử dụng directive
@extends('tên_layout')để khai báo rằng chúng muốn kế thừa từ bố cục chính nào. Sau đó, chúng sẽ sử dụng@section('tên_section') ... @endsectionđể điền nội dung vào các 'điểm neo' đã được định nghĩa trong layout chính.

Code Ví Dụ Minh Hoạ Rõ Ràng
Chúng ta hãy xây dựng một ví dụ đơn giản với một bố cục chính và hai bố cục con.
Bước 1: Tạo bố cục chính (Master Layout)
Lưu file này tại resources/views/layouts/app.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', 'Ứng dụng Laravel của Creyt')</title>
<link rel="stylesheet" href="/css/app.css">
@yield('styles')
</head>
<body>
<header>
<nav>
<a href="/">Trang Chủ</a>
<a href="/about">Giới Thiệu</a>
<a href="/contact">Liên Hệ</a>
</nav>
</header>
<main>
@yield('content')
</main>
<footer>
<p>© {{ date('Y') }} Ứng dụng của Creyt. All rights reserved.</p>
</footer>
<script src="/js/app.js"></script>
@yield('scripts')
</body>
</html>
Giải thích:
@yield('title', 'Ứng dụng Laravel của Creyt'): Đây là một điểm neo cho tiêu đề trang. Nếu trang con không định nghĩatitle, nó sẽ dùng giá trị mặc định là 'Ứng dụng Laravel của Creyt'.@yield('styles')và@yield('scripts'): Các điểm neo để các trang con có thể chèn thêm CSS hoặc JavaScript riêng.@yield('content'): Đây là điểm neo quan trọng nhất, nơi nội dung chính của từng trang con sẽ được hiển thị.
Bước 2: Tạo bố cục con (Child Views)
File: resources/views/home.blade.php (Trang Chủ)
@extends('layouts.app')
@section('title', 'Trang Chủ - Chào mừng!')
@section('content')
<h1>Chào mừng đến với trang chủ của tôi!</h1>
<p>Đây là nội dung độc đáo của trang chủ. Bạn đang thấy sức mạnh của Blade Extends đó!</p>
<button onclick="alert('Bạn vừa nhấn nút trên trang chủ!')">Nhấn vào đây</button>
@endsection
@section('scripts')
<script>
console.log('Script riêng của trang chủ đã chạy!');
</script>
@endsection
File: resources/views/about.blade.php (Trang Giới Thiệu)
@extends('layouts.app')
@section('title', 'Giới Thiệu - Về Creyt')
@section('content')
<h1>Về chúng tôi</h1>
<p>Đây là trang giới thiệu về ứng dụng. Chúng tôi đam mê công nghệ và lập trình!</p>
<ul>
<li>Sứ mệnh: Đem kiến thức đến mọi người.</li>
<li>Tầm nhìn: Trở thành nguồn tài nguyên lập trình hàng đầu.</li>
</ul>
@endsection
@section('styles')
<style>
h1 { color: #28a745; }
ul { list-style-type: square; }
</style>
@endsection
Bước 3: Định tuyến (Routes)
Trong routes/web.php, bạn sẽ định nghĩa các route để hiển thị các view này:
use Illuminate
Support
Facades
Route;
Route::get('/', function () {
return view('home');
});
Route::get('/about', function () {
return view('about');
});
Khi bạn truy cập / hoặc /about, Laravel sẽ render các trang con tương ứng, kết hợp chúng với bố cục layouts.app để tạo ra một trang HTML hoàn chỉnh với header và footer thống nhất.
Mẹo (Best Practices) để ghi nhớ và dùng thực tế
Để trở thành một "kiến trúc sư" Blade lão luyện, hãy bỏ túi vài mẹo sau:
-
Chia nhỏ Layout, đừng tham lam!
- Đừng cố nhét tất cả các loại layout vào một file
app.blade.phpduy nhất! Nếu bạn có phần giao diện quản trị (admin dashboard) khác biệt hoàn toàn với giao diện người dùng (user interface), hãy tạo các layout chuyên biệt nhưlayouts/admin.blade.php,layouts/auth.blade.php. Điều này giúp quản lý dễ dàng hơn, tránh tình trạng 'một nồi lẩu thập cẩm' khó nuốt.
- Đừng cố nhét tất cả các loại layout vào một file
-
Sử dụng
@parentđể thêm, không phải ghi đè!- Đôi khi bạn muốn thêm nội dung vào một section đã được định nghĩa ở layout cha mà không muốn ghi đè hoàn toàn. Lúc đó,
@parentchính là 'người bạn' đắc lực! Nó sẽ giữ lại nội dung gốc của section trong layout cha và thêm nội dung mới của bạn vào. Rất hữu ích khi bạn muốn thêm JS/CSS vào một sectionscriptshoặcstyleschung.
@section('scripts') @parent {{-- Giữ lại scripts từ layout cha --}} <script> // Scripts riêng của trang con console.log('Tôi là script bổ sung!'); </script> @endsection - Đôi khi bạn muốn thêm nội dung vào một section đã được định nghĩa ở layout cha mà không muốn ghi đè hoàn toàn. Lúc đó,
-
Kế thừa lồng nhau (Nested Extends):
- Đừng ngại kế thừa nhiều lớp! Ví dụ, bạn có
layouts/app.blade.phplà layout chung nhất. Rồilayouts/admin.blade.phpextendslayouts/app.blade.phpvà thêm sidebar quản trị. Cuối cùng,admin/dashboard.blade.phpextendslayouts/admin.blade.php. Càng phân cấp, càng rõ ràng, dễ quản lý hơn với các khu vực giao diện phức tạp.
- Đừng ngại kế thừa nhiều lớp! Ví dụ, bạn có
-
Tên Section rõ ràng, tường minh:
- Đặt tên cho
yieldvàsectionthật tường minh:content,title,scripts,styles,sidebar,breadcrumbs... Tránh các tên chung chung, khó hiểu. Một cái tên tốt sẽ giúp bạn và đồng đội dễ dàng hiểu được mục đích của section đó.
- Đặt tên cho
Ví dụ thực tế các ứng dụng/website đã ứng dụng
Hầu hết các trang web lớn mà bạn thấy hàng ngày đều áp dụng cơ chế này (dù có thể không phải Laravel, nhưng ý tưởng là tương tự). Hãy nghĩ đến:
- Facebook, Twitter: Phần đầu trang với logo, thanh tìm kiếm, menu navigation; phần chân trang với thông tin bản quyền... chúng đều xuất hiện nhất quán trên mọi trang. Chỉ có phần 'nội dung chính' ở giữa là thay đổi theo từng trang sản phẩm, bài viết, hoặc trang cá nhân.
- Các trang thương mại điện tử (Tiki, Shopee, Amazon): Bạn vào trang chủ, trang danh mục sản phẩm, trang chi tiết sản phẩm... tất cả đều có chung header (giỏ hàng, tìm kiếm, tài khoản), chung footer. Chỉ phần giữa là thay đổi để hiển thị sản phẩm, mô tả, đánh giá.
- Blog/Tin tức (VnExpress, Medium): Các bài viết khác nhau nhưng đều dùng chung một layout cho header (logo, menu), footer (thông tin liên hệ), và sidebar (bài viết liên quan, quảng cáo).
Đó chính là sức mạnh của việc 'kế thừa' bố cục! Nó giúp các công ty lớn duy trì sự nhất quán về giao diện và tiết kiệm hàng ngàn giờ công phát triển và bảo trì.
Vậy là chúng ta đã cùng nhau khám phá sức mạnh của @extends trong Laravel Blade. Nó không chỉ là một cú pháp, mà là một triết lý thiết kế giúp chúng ta xây dựng ứng dụng web hiệu quả hơn, dễ bảo trì hơn. Hãy áp dụng ngay vào dự án của mình nhé, các 'kiến trúc sư' tương lai!
Thuộc Series: Lavarel
Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!