Joomla Bài học 22: Kỹ thuật tạo Child Template để tùy biến giao diện mà không bị mất code khi cập nhật
Ở Bài học 21, chúng ta đã biết cách thêm file user.css và user.js để tinh chỉnh màu sắc hoặc hành vi nhỏ trên giao diện Cassiopeia. Tuy nhiên, trong các dự án thực tế, khi bạn cần thay đổi cấu trúc HTML trong file index.php, thêm một vị trí Module mới (Module Position), hoặc tạo một phiên bản giao diện hoàn toàn khác cho trang Landing Page mà vẫn muốn tận dụng nền tảng Bootstrap 5 và CSS Grid của Cassiopeia, việc sửa trực tiếp vào thư mục /templates/cassiopeia là điều tối kỵ vì bản cập nhật Joomla Core tiếp theo sẽ ghi đè mất toàn bộ code của bạn.
Trong Joomla Bài học 22, chúng ta sẽ làm chủ tính năng Child Templates (Giao diện con kế thừa) — một kiến trúc chuẩn mực được giới thiệu từ Joomla 4.1+ và hoàn thiện trên Joomla 5, giúp bạn tùy biến sâu ở tầng PHP/HTML mà vẫn nhận được đầy đủ các bản vá bảo mật từ giao diện cha (Parent Template).
1. Bản chất kỹ thuật: Cơ chế Kế thừa và Fallback của Child Template
Khác với tính năng Duplicate Template (Nhân bản toàn bộ giao diện cũ — vốn tạo ra một bản sao độc lập và cắt đứt hoàn toàn liên kết cập nhật với giao diện gốc), Child Template hoạt động theo nguyên lý Kế thừa hướng đối tượng (Inheritance) và Cơ chế tìm kiếm lùi (Fallback Mechanism):
-
Thư mục tối giản: Khi mới tạo, một Child Template chỉ chứa file khai báo
templateDetails.xml(với thẻ<parent>cassiopeia</parent>) và các tài nguyên riêng mà bạn chọn. Nó không sao chép dư thừa toàn bộ các fileindex.php,error.phphay các file CSS/JS gốc. -
Thứ tự ưu tiên đọc file (Resolution Order): Khi Joomla render trang web bằng một Child Template (ví dụ:
cassiopeia_hieu), hệ thống sẽ tìm kiếm các file theo thứ tự sau:-
Bước 1: Tìm trong thư mục của Child Template (
/templates/cassiopeia_hieu/và/media/templates/site/cassiopeia_hieu/). Nếu có file (ví dụindex.phphoặchtml/com_content/...), Joomla sẽ dùng file này. -
Bước 2 (Fallback): Nếu trong Child Template không có file đó, Joomla tự động lùi về lấy file tương ứng từ Parent Template (
/templates/cassiopeia/và/media/templates/site/cassiopeia/).
-
Plaintext
[Request Trang Web dùng Child Template: cassiopeia_hieu]
│
├── Cần nạp index.php?
│ ├─ Có trong /templates/cassiopeia_hieu/index.php? ──► DÙNG FILE CỦA CHILD
│ └─ Không có? ──► Tự động gọi /templates/cassiopeia/index.php (PARENT)
│
└── Cần nạp template.min.css?
└─ Tự động nạp từ /media/templates/site/cassiopeia/css/ (PARENT)
+ Nạp đè /media/templates/site/cassiopeia_hieu/css/user.css (CHILD)
Điều kiện tiên quyết để một Template có thể làm Cha (Parent): Trong file
templateDetails.xmlcủa giao diện gốc phải có khai báo thẻ<inheritable>1</inheritable>và toàn bộ tài nguyên tĩnh (CSS/JS/Images) của nó bắt buộc phải nằm trong thư mục/media/templates/site/<template_name>/.
2. Quy trình khởi tạo Child Template trực tiếp trên Administrator
Joomla 5 tích hợp sẵn công cụ khởi tạo Child Template chỉ với vài cú click chuột:
-
Truy cập System Templates Site Templates.
-
Click vào Cassiopeia Details and Files.
-
Trên thanh công cụ góc trên bên trái, bấm vào nút Create Child Template.
-
Một cửa sổ Popup hiện ra với các thông số:
-
Child Template Name: Nhập tên định danh viết liền không dấu, chỉ dùng chữ thường và dấu gạch dưới (Ví dụ:
hieulab). Hệ thống sẽ tự động ghép tiền tố tên cha thànhcassiopeia_hieulab. -
Additional Template Styles: Cho phép bạn chọn copy cấu hình tham số (Logo, màu sắc, font chữ) từ một Style hiện có của Cassiopeia sang Child Template mới.
-
-
Bấm Create Child Template.
Đặt Child Template làm giao diện mặc định
Sau khi tạo xong, để kích hoạt giao diện con này cho toàn bộ website:
-
Truy cập System Templates Site Template Styles.
-
Tìm dòng
cassiopeia_hieulab - Defaultvà bấm vào biểu tượng Ngôi sao (Default) để chuyển thành ngôi sao màu vàng.
3. Giải phẫu cấu trúc File và XML của Child Template vừa tạo
Nếu mở VS Code kiểm tra mã nguồn trong container Docker của chúng ta, bạn sẽ thấy Joomla vừa sinh ra 2 thư mục cực kỳ gọn nhẹ:
-
Thư mục Logic (
/templates/cassiopeia_hieulab/): Chỉ có duy nhất filetemplateDetails.xml(cùng thư mụchtml/rỗng). Hãy nhìn vào những dòng cốt lõi trongtemplateDetails.xmlcủa Child Template:XML
<?xml version="1.0" encoding="utf-8"?> <extension type="template" client="site"> <name>cassiopeia_hieulab</name> <version>1.0</version> <creationDate>2026-11</creationDate> <author>Hieu Nguyen</author> <!-- DÒNG QUAN TRỌNG NHẤT: Khai báo kế thừa từ cassiopeia --> <parent>cassiopeia</parent> <!-- ... --> </extension> -
Thư mục Tài nguyên tĩnh (
/media/templates/site/cassiopeia_hieulab/): Chứa các thư mục rỗngcss/,js/,images/,scss/sẵn sàng chờ bạn thêm file tùy biến vào.
4. 3 Kịch bản tùy biến thực tế trên Child Template
Kịch bản 1: Tùy biến CSS/JS riêng biệt cho Child Template
Bạn chỉ cần tạo file /media/templates/site/cassiopeia_hieulab/css/user.css.
-
Khi trang web chạy, Web Asset Manager của Joomla sẽ nạp bộ CSS chuẩn của cha (
cassiopeia), sau đó tự động nạp đè fileuser.cssnằm trong thư mụccassiopeia_hieulabcủa con. -
Nhờ vậy, bạn có thể tạo ra nhiều Child Template khác nhau (ví dụ:
cassiopeia_tetcho dịp Tết,cassiopeia_blackfridaycho đợt khuyến mãi), mỗi bản có một fileuser.cssriêng mà không làm ảnh hưởng đến nhau!
Kịch bản 2: Ghi đè và chỉnh sửa cấu trúc index.php (Thêm vị trí Module mới)
Giả sử bạn muốn chỉnh sửa trực tiếp khung HTML chính trong index.php (ví dụ: chèn thêm một thanh thông báo cố định hoặc thêm một vị trí module tên là floating-contact ở góc dưới màn hình):
-
Copy file
index.phptừ Cha sang Con: Chạy lệnh copy trong terminal (hoặc copy trên IDE) từ/templates/cassiopeia/index.phpsang/templates/cassiopeia_hieulab/index.php:Bash
cp src/templates/cassiopeia/index.php src/templates/cassiopeia_hieulab/index.php -
Khai báo thêm Position mới trong
templateDetails.xmlcủa Con: Mở/templates/cassiopeia_hieulab/templateDetails.xml, bổ sung vị trí mới vào khối<positions>:XML
<positions> <!-- Giữ nguyên các vị trí mặc định của Cassiopeia và thêm dòng dưới --> <position>floating-contact</position> </positions> -
Render vị trí mới trong
/templates/cassiopeia_hieulab/index.php: Mở fileindex.phpcủa Child Template, thêm đoạn code sau ngay phía trên thẻ đóng</body>:PHP
<?php if ($this->countModules('floating-contact')) : ?> <div class="floating-contact-widget position-fixed bottom-0 end-0 p-3" style="z-index: 1050;"> <jdoc:include type="modules" name="floating-contact" style="none" /> </div> <?php endif; ?>
Kịch bản 3: Ghi đè giao diện bài viết (Template Overrides) chỉ áp dụng cho Child Template
Khi bạn vào System Site Templates Cassiopeia_hieulab Details and Files Chuyển sang tab Create Overrides và chọn tạo bản ghi đè cho com_content article:
-
File ghi đè sẽ được sinh ra tại
/templates/cassiopeia_hieulab/html/com_content/article/default.php. -
Mọi chỉnh sửa giao diện bài viết tại đây sẽ được bảo toàn vĩnh viễn bên trong Child Template.
5. Tổng kết bài học
-
Hiểu rõ sự khác biệt bản chất giữa Duplicate Template (nhân bản độc lập) và Child Template (kế thừa động qua thẻ
<parent>và cơ chế Fallback). -
Nắm vững quy trình tạo và kích hoạt một Child Template từ Cassiopeia ngay trong trang quản trị Joomla 5.
-
Thành thạo 3 cấp độ tùy biến trên Child Template: Ghi đè CSS/JS (
user.css), ghi đè khung xươngindex.php(chỉ copy khi thật sự cần sửa) và tạo HTML Overrides riêng biệt.
Sau khi đã hiểu cách kế thừa từ một giao diện có sẵn, nếu khách hàng yêu cầu bạn xây dựng một bộ giao diện độc quyền mới hoàn toàn từ bản thiết kế Figma/HTML mà không dựa vào Cassiopeia thì phải làm thế nào? Trong Bài học 23, chúng ta sẽ bắt tay vào: Cấu trúc thư mục chuẩn của một Joomla Template từ con số 0 và chi tiết file templateDetails.xml.
All rights reserved