Cấu trúc phân cấp của các mẫu chủ đề (theme templates) trong WordPress chính là yếu tố then chốt tạo nên sức mạnh và tính linh hoạt của nó. Cấu trúc này cho phép các nhà phát triển tạo ra những trang hiển thị độc đáo cho các loại nội dung khác nhau bằng cách sử dụng các quy tắc đặt tên tệp tin nhất định. Điều này cũng đúng với các trang lưu trữ (archive pages), tức là những trang liệt kê các bài viết. Việc hiểu rõ và áp dụng đúng các quy tắc này là rất quan trọ archive-{post_type}.php Quy tắc đặt tên này là yếu tố then chốt để tạo ra các trang danh sách dành riêng cho các loại bài viết tùy chỉnh. Bài viết này sẽ giải thích một cách có hệ thống toàn bộ quy trình, từ nguyên lý đến thực hành, và cuối cùng là cách khắc phục các vấn đề có thể phát sinh trong quá trình triển khai.
Hiểu cơ chế cấp bậc mẫu và trang lưu trữ
Khi người dùng truy cập vào trang danh sách bài viết – chẳng hạn như trang chủ blog của bạn hoặc trang danh mục nào đó – WordPress sẽ khởi động một quá trình được gọi là “truy vấn chính” (main query) để lấy các bài viết tương ứng. Đồng thời, nó sẽ tìm kiếm tệp template PHP phù hợp nhất để hiển thị trang dựa trên ngữ cảnh của truy vấn hiện tại, theo một thứ tự ưu tiên đã được xác định trước. Thứ tự này được gọi là “cấu trúc phân cấp của các template” (template hierarchy).
Đối với trang lưu trữ (archive page), cách tìm đường dẫn có một mô hình cụ thể. Giả sử người dùng truy cập vào trang lưu trữ thuộc loại “bài viết” mặc định, WordPress sẽ tìm theo thứ tự sau:archive-post.php -> archive.php -> index.phpChỉ cần tìm thấy tệp tin đầu tiên tồn tại, chúng ta sẽ sử dụng nó.
Đọc thêm Hướng dẫn thực hành toàn diện về cách tạo và xuất bản các loại bài viết tùy chỉnh trên WordPress。
Trọng tâm của cơ chế này nằm ở… archive-{post_type}.php. Ở đây {post_type} Đây là một biến; bạn cần thay thế nó bằng tên đăng ký của loại bài viết tương ứng. Ví dụ, để tạo trang lưu trữ cho loại bài viết tùy chỉnh có tên “Dự án”, bạn sẽ cần một biến có tên là… archive-project.php Đó là tệp tin cần thiết. Chỉ khi tệp tin này không tồn tại, WordPress mới quay trở lại phiên bản thông thường (phiên bản mặc định). archive.phpĐiều này cho phép chúng ta kiểm soát chính xác cách hiển thị các danh sách chứa nội dung khác nhau.
Tạo mẫu lưu trữ cho loại bài viết tùy chỉnh
Hãy đảm bảo rằng loại bài viết đó hỗ trợ tính năng lưu trữ (archiving).
Điều kiện tiên quyết để tạo tệp mẫu là loại bài viết tùy chỉnh (Custom Post Type – CPT) của bạn phải được chỉ định rõ ràng là hỗ trợ việc lưu trữ các bản sao (archiving). Điều này thường được thực hiện thông qua các cấu hình liên quan trong hệ thống quản trị nội dung (CMS). register_post_type Khi đăng ký hàm cho CPT (Content Provider Type), việc này được thực hiện thông qua việc thiết lập các tham số.
Trong mảng tham số của hàm đăng ký,has_archive Tham số này kiểm soát việc kích hoạt trang lưu trữ (archive page). Hãy thiết lập nó thành… true Đây là một bước không thể thiếu. Nếu được thiết lập như vậy… false Hoặc chưa được thiết lập (mặc định là…) falseNgay cả khi bạn đã tạo đúng tệp mẫu, WordPress vẫn sẽ không tạo ra URL tương ứng để truy cập trang lưu trữ đó.
Một ví dụ tiêu biểu về đăng ký CPT (Common Practice Template) hỗ trợ việc lưu trữ các tệp tin định dạng archiver như sau:
function my_register_custom_post_type() {
$labels = array(
'name' => '产品',
'singular_name' => '产品',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true, // 启用存档功能
'rewrite' => array('slug' => 'products'), // 可选:自定义存档页URL别名
'supports' => array('title', 'editor', 'thumbnail'),
'menu_icon' => 'dashicons-cart',
);
register_post_type('product', $args);
}
add_action('init', 'my_register_custom_post_type'); Cấu trúc và nội dung của tệp tin mẫu (template file)
Sau khi xác nhận rằng CPT hỗ trợ việc lưu trữ các tệp tin, bước tiếp theo là tạo các tệp mẫu tương ứng trong thư mục chứa chủ đề sự kiện của bạn. Tên của các tệp tin phải được đặt một cách chính xác và tuân thủ nghiêm ngặt các quy định nhất định. archive-{post_type}.php The format should be consistent, and... {post_type} Tên phải hoàn toàn trùng khớp với tên đã được sử dụng khi đăng ký (phân biệt chữ hoa và chữ thường).
Bên trong tệp này, bạn có thể sử dụng các thẻ mẫu (template tags) và vòng lặp (loops) của WordPress để xây dựng nội dung, tương tự như cách bạn thường làm với các mẫu trang khác. Đây là một ví dụ cơ bản và hoàn chỉnh về cách thực hiện điều đó. archive-product.php Có thể trông như thế này:
<?php
/**
* 模板名称:产品存档页
* 用于展示“product”自定义文章类型的文章列表
*/
get_header(); ?>
<main id="primary" class="site-main">
<header class="archive-header page-header">
<?php
the_archive_title( '<h1 class="archive-title page-title">', '</h1>' );
the_archive_description( '<div class="archive-description">', '</div>' );
?>
</header>
<?php if ( have_posts() ) : ?>
<div class="product-archive-wrapper">
<?php
while ( have_posts() ) :
the_post();
?>
<article id="post-<?php the_ID(); ?>" no numeric noise key 1012>
<a href="/vi/</?php the_permalink(); ?>" class="product-thumbnail-link">
</a>
<div class="product-content">
<h2 class="product-title">
<a href="/vi/</?php the_permalink(); ?>"><?php the_title(); ?></a>
</h2>
<div class="product-excerpt">
<?php the_excerpt(); ?>
</div>
<a href="/vi/</?php the_permalink(); ?>" class="read-more-link">Xem chi tiết</a>
</div>
</article>
<?php endwhile; ?>
</div>
2,
'prev_text' => __( '上一页', 'textdomain' ),
'next_text' => __( '下一页', 'textdomain' ),
) );
?>
<section class="no-products">
<p>Xin lỗi, hiện tại chúng tôi không tìm thấy bất kỳ sản phẩm nào.</p>
</section>
<?php endif; ?>
</main>
<?php
get_sidebar();
get_footer(); Kỹ thuật kiểm soát nâng cao và tùy chỉnh
Sử dụng các điều kiện để thực hiện phân tích và xử lý dữ liệu trong mẫu lưu trữ chung
Đôi khi, bạn có thể muốn nhiều loại bài viết khác nhau cùng sử dụng cùng một… archive.php Đó là những tệp tin, nhưng bên trong chúng, nội dung được hiển thị khác nhau tùy theo loại tệp. Lúc này, các thẻ điều kiện (Conditional Tags) của WordPress trở nên cực kỳ hữu ích.
Điều kiện có liên quan nhất là… is_post_type_archive() Hàm. Bạn có thể… archive.php Bạn có thể sử dụng nó để tùy chỉnh tiêu đề, mô tả hoặc cấu trúc lặp (loop structure) cho các CPT (Code Points Types) khác nhau.
// 在 archive.php 文件内
if ( is_post_type_archive('product') ) {
echo '<h1>Sản phẩm và giải pháp của chúng tôi</h1>';
get_template_part('template-parts/loop', 'product-grid');
} elseif ( is_post_type_archive('event') ) {
echo '<h1>Sự kiện và Hội thảo Gần đây</h1>';
get_template_part('template-parts/loop', 'event-list');
} else {
// 默认的文章存档(博客)
echo '<h1>Blog và Tin tức</h1>';
get_template_part('template-parts/loop', 'default');
} Sử dụng các “hook” (công cụ hoặc lệnh đặc biệt) để thay đổi cách truy vấn trang lưu trữ.
Việc chỉnh sửa trực tiếp các vòng lặp trong tệp template chỉ có thể thay đổi cách trình bày nội dung được hiển thị. Nếu bạn muốn thay đổi cách trang lưu trữ (archive page) lấy dữ liệu các bài viết (ví dụ: số lượng bài viết trên mỗi trang, phương thức sắp xếp, hoặc việc lọc các bài viết cụ thể), bạn phải sử dụng các công cụ hoặc kỹ thu pre_get_posts Action hooks. Đây là phương pháp được WordPress khuyến nghị, giúp đảm bảo sự tương tác tốt với các tính năng như phân trang.
Ví dụ mã nguồn dưới đây minh họa cách thay đổi truy vấn chính (main query) trên trang lưu trữ sản phẩm, để nó được sắp xếp theo một trường tùy chỉnh, và hiển thị 9 sản phẩm trên mỗi trang:
function customize_product_archive_query($query) {
// 确保只在非管理后台、主查询、且是产品存档页时生效
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive('product') ) {
$query->set('posts_per_page', 9); // 每页9个产品
$query->set('orderby', 'meta_value_num'); // 按数字元字段排序
$query->set('meta_key', 'product_price'); // 指定元字段键
$query->set('order', 'ASC'); // 升序排列
}
}
add_action('pre_get_posts', 'customize_product_archive_query'); Lưu ý quan trọng: Tuyệt đối tránh sử dụng trong các tệp mẫu (template files). query_posts() Việc thay đổi truy vấn chính có thể làm hỏng cấu trúc của đối tượng truy vấn, dẫn đến lỗi trong việc hiển thị dữ liệu theo trang (pagination), cũng như các vấn đề liên quan đến tính tương thích giữa các tiện ích mở rộng (plugins).
Tải các tệp mẫu khác nhau một cách động (dynamically)
Đối với những tình huống phức tạp hơn, bạn có thể sử dụng… template_include Các bộ lọc được sử dụng để quyết định một cách dinh hồng việc tải file mẫu (template) nào. Điều này cho phép bạn thay đổi file mẫu dựa trên bất kỳ điều kiện nào (chẳng hạn như vai trò người dùng, tham số URL, thời gian, v.v.).
Ví dụ, trang lưu trữ thông tin về “sản phẩm” sẽ tải một mẫu khác nhau dưới những điều kiện nhất định:
function load_special_product_archive_template($template) {
if ( is_post_type_archive('product') && some_custom_condition() ) {
$new_template = locate_template('archive-product-special.php');
if ( ! empty($new_template) ) {
return $new_template;
}
}
return $template;
}
add_filter('template_include', 'load_special_product_archive_template'); Khắc phục sự cố và Thực hành tốt nhất
Ngay cả khi đã tuân thủ tất cả các bước hướng dẫn, đôi khi mẫu lưu trữ vẫn không hoạt động như mong đợi. Dưới đây là danh sách kiểm tra hệ thống để tìm ra nguyên nhân:
1. 刷新固定链接:这是最常见且首要的步骤。前往WordPress后台的“设置” -> “固定链接”,直接点击“保存更改”。这个操作会刷新WordPress的重写规则,使新的存档页面URL规则生效。
2. Xác thực việc đăng ký CPT: Hãy đảm bảo rằng mã được sử dụng để đăng ký CPT đang được thực thi (đang được sử dụng để thực hiện các thao tác cần thiết), và… has_archive Các tham số được truyền đi cuối cùng… register_post_type Thời gian quả thực là… trueHãy kiểm tra xem có bất kỳ plugin hay đoạn mã của theme nào khác đang ghi đè (overwrite) các thiết lập CPT (Custom Post Type) của bạn không.
3. Kiểm tra vị trí và tên của tệp tin: Hãy xác nhận chúng. archive-{post_type}.php Tệp tin nằm trong thư mục gốc của chủ đề đúng. Hãy kiểm tra cách đánh vần tên tệp, bao gồm cả chữ hoa và chữ thường, để đảm bảo rằng nó hoàn toàn trùng khớp với tên loại bài viết (post_type) đã được đăng ký.
4. Xử lý tình trạng trùng lặp nội dung trong các chủ đề: Nếu bạn đang sử dụng các chủ đề con (sub-templates), hãy đảm bảo rằng các tệp mẫu (template files) có cùng tên trong chủ đề cha (parent theme) không làm thay đổi cấu trúc của các tệp mẫu trong chủ đề con. Đồng thời, hãy ki template_include Sự can thiệp của bộ lọc (Filter interference).
5. Vấn đề về bộ đệm: Hãy xóa bộ đệm ở tất cả các cấp độ, bao gồm bộ đệm đối tượng WordPress, plugin lưu trữ trang web, cũng như bộ đệm trên máy chủ hoặc CDN.
Về các thực tiễn tốt nhất, khuyến nghị nên luôn sử dụng chúng. pre_get_posts mà không phải query_posts Hãy thực hiện các thay đổi cần thiết đối với truy vấn; sau đó sử dụng những thay đổi đó trong tệp mẫu (template file). post_class() Để tạo ra các lớp CSS động cho bài viết nhằm thuận tiện hơn trong thiết kế giao diện, hãy sử dụng các kỹ thuật như phản ứng của CSS (CSS responses) hoặc các công cụ tạo lớp CSS dựa trên điều kiện (conditional CSS classes). Đồng thời, hãy thêm các ghi chú rõ ràng ở phần đầu của tệp mẫu
Tóm lại
Việc kết nối các mẫu lưu trữ tùy chỉnh cho các loại bài viết khác nhau trên WordPress là một quá trình giúp đảm bảo sự đồng bộ hoàn hảo giữa nội dung và giao diện hiển thị. Trọng tâm của việc này nằm ở việc hiểu rõ và vận dụng đúng cách các nguyên lý thiết kế li archive-{post_type}.php Những quy tắc về cấu trúc của mẫu này bao gồm: đảm bảo rằng tính năng lưu trữ được kích hoạt khi đăng ký CPT (Common Procurement Template); tạo và đặt tên cho các tệp mẫu một cách chính xác; và sau đó sử dụng chúng một cách thích hợp. pre_get_posts Các công cụ như “hook” (móc) đóng vai trò quan trọng trong việc kiểm soát các truy vấn phức tạp; mỗi bước trong quá trình sử dụng chúng đều cực kỳ quan trọng. Sau khi nắm vững những kỹ năng này, bạn sẽ có thể dễ dàng tạo ra các trang danh sách với chức năng hoàn chỉnh và thiết kế độc đáo cho mọi loại nội dung trên trang web, từ đó nâng cao đáng kể mức độ chuyên nghi
FAQ 常见问题
URL của trang lưu trữ tùy chỉnh có dạng như thế nào?
Theo mặc định, WordPress sẽ tạo URL cho trang lưu trữ (archive page) dựa trên tên bạn đã sử dụng khi đăng ký loại bài viết tùy chỉnh. Ví dụ, một loại bài viết có tên là… product Đối với CPT (Claim Preparation Tool), địa chỉ URL của trang lưu trữ thông tin thường là… 你的网站域名/product/Bạn có thể thực hiện điều này bằng cách thiết lập các thông tin cần thiết khi đăng ký. rewrite tham số trong slug Tùy chọn này cho phép bạn tự định nghĩa tên miền (alias) cho địa chỉ URL này.
Tôi có thể hiển thị kết quả tìm kiếm các bài viết thuộc hệ thống phân loại tùy chỉnh trong mẫu tệp lưu trữ không?
Tất nhiên là có thể. Đây là một yêu cầu phổ biến đối với các trang lưu trữ (archive pages). Bạn có thể… archive-{post_type}.php Sử dụng trong mẫu (Use in the template) get_terms() Hàm này lấy tất cả các thuật ngữ thuộc bộ phân loại tùy chỉnh liên quan (chẳng hạn như “Phân loại sản phẩm”), sau đó hiển thị chúng dưới dạng các liên kết để người dùng lọc. Khi người dùng nhấp vào một liên kết phân loại, họ sẽ được đưa đến trang lưu trữ của bộ phân loại đó; lúc này, WordPress sẽ tự động tìm kiếm và tải nội dung liên quan. taxonomy-{taxonomy_name}.php 或 taxonomy-{taxonomy_name}-{term_slug}.php Các mẫu chờ (waiting templates).
Làm thế nào để tạo trang danh sách cho các loại bài viết không có chức năng lưu trữ?
Nếu một loại bài viết nào đó… has_archive Đặt thành falseNếu không, bạn sẽ không thể truy cập vào danh sách đó thông qua địa chỉ URL lưu trữ tiêu chuẩn. Giải pháp thay thế là tạo một trang web bình thường (Page), sau đó sử dụng nó trong mẫu trang đó. WP_Query 或 get_posts() Hãy thực hiện thao tác truy vấn và hiển thị các bài viết thuộc loại cụ thể đó. Bạn có thể phân bổ một mẫu tùy chỉnh cho trang này, và viết mã truy vấn cũng như các vòng lặp (loops) riêng biệt bên trong mẫu đó.
Trang phân trang không hoạt động trên trang lưu trữ tùy chỉnh; làm thế nào để sửa lỗi này?
Lỗi trong việc hiển thị dữ liệu theo trang (paging) hầu như luôn xảy ra do việc sửa đổi trái phép truy vấn chính (Main Query). Vui lòng đảm bảo rằng bạn không đang sử dụng bất kỳ thứ gì có thể làm thay đổi nội dung của truy vấn chính trong các mẫu (templates) của bạn. query_posts()Nếu bạn cần thay đổi các tham số truy vấn (chẳng hạn như số lượng bài viết, phương thức sắp xếp), bạn phải sử dụng công cụ hoặc lệnh tương ứng để thực hiện điều đó. pre_get_posts Hook, như đã đề cập trong bài viết. Đồng thời, đảm bảo khi gọi the_posts_pagination() Khi sử dụng hàm phân trang, nó hoạt động trên toàn bộ hệ thống (toàn cục – global). $wp_query Đối tượng, chứ không phải một thứ được tùy chỉnh (customized). WP_Query Ví dụ.
Bước tiếp theo, chúng ta nên làm gì tiếp theo?
Đọc thêm và kiến thức thực tế
Những nội dung sau đây liên quan đến chủ đề của bài viết này, thích hợp để tiếp tục đọc sâu hơn. Ưu tiên bắt đầu với bài viết gần nhất với vấn đề hiện tại của bạn, rồi dần dần mở rộng sang các chủ đề xung quanh, hiệu quả thường sẽ tốt hơn.
- Hướng dẫn Tối thượng để Xây dựng Website WooCommerce: Tạo Cửa hàng Trực tuyến Riêng của bạn từ Con số 0
- Phân tích sâu về WooCommerce: Xây dựng một trang web thương mại điện tử WordPress mạnh mẽ từ con số không
- Hướng dẫn toàn diện về tối ưu hóa hiệu suất WordPress: Tăng tốc toàn diện từ lõi đến giao diện người dùng
- Làm thế nào để cài đặt và thiết lập chứng chỉ SSL cho trang web WordPress của bạn?
- Hướng dẫn cấu hình tối ưu hóa bộ đệm toàn trang cho WooCommerce: Nâng cao tốc độ và tỷ lệ chuyển đổi cho trang web thương mại điện tử WordPress