Joomla Bài học 26: Kỹ thuật Template Overrides: Ghi đè giao diện của Component và Module theo thiết kế riêng
Trong các bài học trước, chúng ta đã học cách cấu hình bố cục tổng thể qua index.php và quản lý tài nguyên tĩnh qua joomla.asset.json. Tuy nhiên, khi bạn cần thay đổi cách hiển thị chi tiết bên trong một Component (ví dụ: đổi thứ tự hiển thị tiêu đề, ngày tháng, ảnh đại diện của trang chi tiết bài viết com_content) hoặc một Module (ví dụ: biến danh sách bài viết mới thành một Slider trượt ngang), việc sửa trực tiếp vào mã nguồn gốc của Joomla là điều cấm kỵ.
Trong Joomla Bài học 26, chúng ta sẽ làm chủ vũ khí lợi hại nhất của lập trình viên giao diện Joomla: Template Overrides (Kỹ thuật ghi đè giao diện). Kỹ thuật này cho phép bạn tùy biến cấu trúc HTML của bất kỳ thành phần nào theo ý muốn mà vẫn giữ nguyên vẹn tính an toàn khi nâng cấp hệ thống Core.
1. Bản chất kỹ thuật của Template Overrides
Khi Joomla xử lý một yêu cầu hiển thị (ví dụ: hiển thị chi tiết bài viết thuộc com_content), bộ định tuyến MVC sẽ đi tìm file giao diện theo thứ tự ưu tiên (Fallback Mechanism):
-
Kiểm tra đầu tiên tại Template đang hoạt động: Joomla quét thư mục
/templates/<ten_template>/html/<component_name>/<view_name>/(Ví dụ:/templates/joomlalab/html/com_content/article/default.php). Nếu tìm thấy file này, nó sẽ ngay lập tức sử dụng file của bạn và bỏ qua bản gốc. -
Kiểm tra tại thư mục gốc của Component (Fallback): Nếu không tìm thấy file ghi đè trong thư mục Template, Joomla mới lùi về lấy file mặc định nằm trong thư mục cốt lõi
/components/<component_name>/tmpl/article/default.php.
Nhờ cơ chế này, bạn có thể copy file giao diện gốc ra thư mục html/ của template và thoải mái mổ xẻ, viết thêm code PHP/HTML mà không lo bị mất code khi cập nhật Joomla Core!
2. Quy trình tạo Template Overrides trực quan trên Administrator
Joomla 5 cung cấp công cụ tự động copy file cực kỳ tiện lợi:
-
Truy cập System Site Templates Click chọn
joomlalab Details and Files. -
Chuyển sang tab Create Overrides.
-
Giao diện sẽ hiển thị danh sách toàn bộ các thành phần có thể ghi đè được chia theo nhóm:
-
com_content(Component bài viết): Ghi đè trang chi tiết (article), danh sách chuyên mục (category), trang blog (category_blog). -
mod_articles_latest(Module bài viết mới nhất). -
com_users,com_contact,com_finder, v.v.
-
-
Bấm vào mục bạn muốn ghi đè (Ví dụ: click vào
com_contentchọnarticle). -
Hệ thống sẽ báo thông báo thành công: Override created successfully. Ngay lập tức, file giao diện đã được tự động sao chép vào thư mục
/templates/joomlalab/html/com_content/article/default.php.
3. Cấu trúc thư mục Overrides thực tế trong dự án
Nếu mở thư mục mã nguồn src/ trên IDE của bạn, cấu trúc file ghi đè sẽ có dạng:
Plaintext
src/templates/joomlalab/html/
├── com_content/
│ ├── article/
│ │ └── default.php <-- Ghi đè trang chi tiết bài viết
│ └── category/
│ └── blog.php <-- Ghi đè trang danh sách blog
└── mod_articles_latest/
└── default.php <-- Ghi đè module bài viết mới nhất
4. Thực hành: Tùy biến file Override com_content/article/default.php
Hãy mở file vừa được tạo tại src/templates/joomlalab/html/com_content/article/default.php. Đây là file PHP chứa HTML kết hợp với các biến dữ liệu được truyền từ Model/View của component.
Chúng ta sẽ tùy biến lại cấu trúc: Đưa ảnh đại diện (fullImage) lên trên cùng làm tiêu đề tràn viền, đẩy tên tác giả và ngày tháng xuống dưới, đồng thời bọc các Custom Fields thành một bảng thông số đẹp mắt:
PHP
<?php
\defined('_JEXEC') or die;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
/** @var \Joomla\Component\Content\Site\View\Article\HtmlView $this */
$item = $this->item;
$params = $item->params;
$images = json_decode($item->images);
?>
<article class="item-page custom-article-override">
<!-- 1. TIÊU ĐỀ BÀI VIẾT -->
<?php if ($params->get('show_title')) : ?>
<header class="article-header mb-4">
<h1 class="fw-bold display-5 text-dark"><?php echo $this->escape($item->title); ?></h1>
<!-- THÔNG TIN TÁC GIẢ VÀ NGÀY THÁNG -->
<div class="text-muted small mt-2">
<span class="me-3"><i class="fas fa-calendar-alt"></i> <?php echo HTMLHelper::_('date', $item->publish_up, Text::_('DATE_FORMAT_LC3')); ?></span>
<?php if ($params->get('show_author') && !empty($item->author)) : ?>
<span><i class="fas fa-user"></i> <?php echo $this->escape($item->author); ?></span>
<?php endif; ?>
</div>
</header>
<?php endif; ?>
<!-- 2. ẢNH ĐẠI DIỆN LỚN (FULL IMAGE) -->
<?php if (!empty($images->image_fulltext)) : ?>
<div class="article-image mb-4 overflow-hidden rounded-4 shadow-sm">
<img src="<?php echo htmlspecialchars($images->image_fulltext, ENT_QUOTES, 'UTF-8'); ?>"
alt="<?php echo htmlspecialchars($images->image_fulltext_alt, ENT_QUOTES, 'UTF-8'); ?>"
class="img-fluid w-100 object-fit-cover" style="max-height: 450px;">
<?php if (!empty($images->image_fulltext_caption)) : ?>
<figcaption class="text-center text-muted small mt-2 fst-italic">
<?php echo htmlspecialchars($images->image_fulltext_caption, ENT_QUOTES, 'UTF-8'); ?>
</figcaption>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 3. NỘI DUNG CHÍNH CỦA BÀI VIẾT -->
<section class="article-content fs-5 text-secondary lh-lg mb-5">
<?php echo $item->text; ?>
</section>
<!-- 4. HIỂN THỊ CUSTOM FIELDS (NẾU CÓ) -->
<?php if (!empty($item->jcfields)) : ?>
<div class="card border-0 bg-light rounded-4 p-4 mb-4">
<h4 class="fw-bold mb-3 fs-5 text-dark"><i class="fas fa-info-circle me-2"></i> Thông số kỹ thuật</h4>
<table class="table table-borderless mb-0">
<tbody>
<?php foreach ($item->jcfields as $field) : ?>
<?php if (!empty($field->value)) : ?>
<tr>
<td class="fw-semibold text-dark w-25"><?php echo htmlspecialchars($field->label, ENT_COMPAT, 'UTF-8'); ?>:</td>
<td class="text-secondary"><?php echo $field->value; ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</article>
5. Kỹ thuật tạo Alternative Layouts (Layout thay thế tùy chọn)
Đôi khi bạn không muốn ghi đè toàn bộ trang chi tiết bài viết mặc định (default.php), mà muốn tạo ra một Layout riêng biệt chỉ áp dụng cho một số bài viết đặc biệt (Ví dụ: một bài viết có giao diện dạng Báo cáo toàn màn hình, bài khác dạng Tin tức ngắn).
Cách thực hiện cực kỳ đơn giản:
-
Copy file
/templates/joomlalab/html/com_content/article/default.phpra thành một file mới ngay trong cùng thư mục và đặt tên tùy ý, ví dụlanding.php. -
Mở file
landing.phplên và tùy biến cấu trúc HTML theo ý muốn (ví dụ: ẩn sidebar, dùng màu nền tối). -
Khi bạn quay lại trang quản trị Joomla, vào một bài viết bất kỳ chuyển sang tab Page Display (hoặc Options tùy phiên bản), tại mục Alternative Layout, bạn sẽ thấy xuất hiện lựa chọn
landingtrong danh sách dropdown! -
Khi chọn
landing, Joomla sẽ tự động dùng filelanding.phpcủa template để render riêng cho bài viết đó mà không làm ảnh hưởng đến các bài viết khác dùngdefault.php.
6. Tổng kết bài học
-
Hiểu rõ cơ chế tìm kiếm và ghi đè MVC qua thư mục
/templates/<template>/html/. -
Thành thạo quy trình tạo bản ghi đè cho Component (
com_content) và Module ngay trên giao diện Administrator. -
Biết cách tối ưu hóa file Override bằng cách sử dụng các biến
$this->item,$item->jcfieldsvà tạo Alternative Layouts để linh hoạt thay đổi giao diện theo từng bài viết cụ thể.
Trong Bài học 27, chúng ta sẽ tiếp tục khám phá kỹ thuật tái sử dụng thành phần giao diện dùng chung trong hệ thống: Kỹ thuật Layout Overrides (JLayout): Tái sử dụng các thành phần giao diện dùng chung.
All rights reserved