Tạo WordPress Pagination không cần plugin

Rate this post

WordPress Pagination là thanh liên kết nằm bên dưới danh sách bài viết để hiển thị các trang còn lại. Cách làm tính năng này trong giao diện WordPress rất đơn giản theo hướng dẫn của Code Tốt.

WordPress Pagination là gì?

Khi bạn duyệt một chuyên mục, hoặc danh sách bài viết lưu trữ theo tháng, năm, thường ta sẽ thấy hiện ra một mục hiện ra “Trang tiếp theo”, hoặc “Trang 2”. Đấy chính là Pagination – chức năng giúp người dùng dễ dàng duyệt bài hơn. Số bài viết mỗi trang có thể được quy định trong mục Settings > Reading (hoặc Cài đặt > Đọc nếu bạn dùng WordPress tiếng Việt).

Ví dụ về WordPress Pagination
Ví dụ về WordPress Pagination

WordPress Pagination trong các giao diện mặc định

Rõ ràng người dùng không thể xem 50 bài viết mỗi trang, và chúng ta cần phải tách thành các trang chứa danh sách bài viết tiếp theo. Vậy làm thế để nào để xây dựng và tuỳ biến tính năng này trong một giao diện WordPress mới?

Hãy cùng tham khảo qua tài liệu hướng dẫn của WordPress. Ta có thể thấy một số function đã được WordPress cung cấp sẵn dưới đây để hoạt động trong các template có sẵn của WordPress.

WordPress Pagination theo bài viết (trước và sau)

posts_nav_link()

Function này sẽ hiển thị liên kết tới trang tiếp theo và trang trước đó như sau:

« Previous Page — Next Page »

next_posts_link(); 
previous_posts_link();

Hai function này sẽ hiện ra các bài viết trước và sau. Nếu bạn muốn lấy giá trị, sử dụng:

$next_posts = get_next_posts_link(); 
$prev_posts = get_previous_posts_link();

WordPress Pagination theo số trang (Numeric)

Từ các phiên bản WordPress 4.1 trở lên, bạn có thể dùng function này để hiển thị danh sách các liên kết trang bao gồm cả liên kết trang tiếp theo và trang trước.

the_posts_pagination();

Trong các template mặc định của WordPress, ví dụ trong category.php, archive.php, khi bạn sử dụng function trên, nó sẽ lấy giá trị của $wp_query để xác định trang hiện tại.

WordPress Pagination trong bài viết/trang riêng lẻ (Single)

Để Pagination hoạt động trong một bài viết riêng lẻ và các liên kết sẽ trỏ về bài viết tiếp theo hoặc bài viết cũ hơn (tính theo thời gian), ta sử dụng các function sau:

previous_post_link();
next_post_link();

WordPress Pagination giữa các phần của bài viết

Để chia nội dung bài viết ra làm nhiều phần, mỗi phần là một trang, bạn cần:

  • Tách các phần nội dung bằng thẻ <!--nextpage-->
  • Trong vòng lặp, bên dưới the_content() bạn nhập thêm vào wp_link_pages();

Cụ thể ví dụ như sau:

<?php if ( have_posts() ) : ?>
  <!-- Start of the main loop. -->
  <?php while ( have_posts() ) : the_post(); ?>
    <?php the_content(); ?>
    <?php wp_link_pages(); ?> 
  <?php endwhile; ?>
<?php endif; ?>

WordPress Pagination trong các Custom Query và Custom Template

Giờ hãy tiếp tục với các phương án khó hơn. Nếu ta đang dùng một giao diện riêng cho page (chẳng hạn, tôi muốn page templates/blog.php sẽ chứa các bài viết và có Pagination). Ta sẽ thực hiện như thế nào?

[sociallocker]

WP_Query

Nếu trong template của bạn đang chứa WP_Query, ta sẽ thực hiện như sau:

Bước 1: Xác định query_var paged

Đầu tiên, ta cần xác định query_var (tức là thành phần ?page=x hay /page/x) trong query hiện tại. Lưu ý là phần này nằm ngoài while() loop nhé.

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

Đây là một global variable nên bạn yên tâm sử dụng nhé.

Bước 2: Cập nhật $args để nó sử dụng paged

$args = array(
  'post_type' => array('post'), // Có thể dùng post_type khác ở đây
  'posts_per_page' => "5",
  'paged' => $paged
);

Bước 3: Chạy WP_Query()

Thực hiện WP_Query để ra được danh sách bài viết. Lý do ta không dùng get_posts() để thay thế là vì với WP_Query thì có sẵn biến $list->max_num_pages để tra cứu và hiển thị pagination chỉ khi số bài viết vượt quá trên 1 trang.

// the query
$list = new WP_Query( $args );
if ( $list->have_posts() ) :
  while( $list->have_post() ) : $list->the_post();
    the_title(); // Demo output
  endwhile;
  wp_reset_postdata();
endif;

Bước 4: Viết pagination

Trong custom template (tính tới phiên bản 4.9.1), bạn không thể sử dụng the_posts_pagination() được. Lý do là vì trong core function này sử dụng $wp_query để xem có max_num_pages không thì mới hiển thị.

Bởi vậy, ta cần viết bằng pagination_links() như sau:

global $wp_query;
$big = 999999999; // need an unlikely integer
$translated = __( 'Page', 'mytheme_textdomain' ); // Supply translatable string
echo paginate_links( array(
  'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
  'format' => '?paged=%#%',
  'current' => max( 1, get_query_var('paged') ),
  'total' => $list->max_num_pages,
  'before_page_number' => '<span class="screen-reader-text">'.$translated.' </span>'
) );

Bước 5: Đăng ký rewrite URL để sử dụng ?paged

Trong file functions.php hoặc một trong các file được load vào functions.php tuỳ theo project, bạn đăng ký rewrite URL như sau:

add_action('init', 'rewrite_url');
// Lưu ý thay đường dẫn /blog/ bằng page của bạn
$page_slug = 'blog';
function rewrite_url() {
  add_rewrite_url($page_slug . '/page/([0-9]{1,})/?$', 'index.php?pagename=$matches[1]&paged=$matches[2]', 'top');
}

Bước này sẽ giúp bạn sử dụng get_query_var('paged') ở trên. Nếu không dùng bước này, bạn sẽ lấy giá trị bằng cách $_GET('paged'), nhưng không nên. Lý do là ta cần rewrite url để nó tương thích với pagination_links ở bước 4.

Đừng quên vào Settings > Permalinks để lưu lại và có hiệu lực nữa nhé.

Các cách làm không nên

Viết đè $wp_query

Cách này không nên làm vì $wp_query là giá trị default global scope của WordPress, nếu bạn ghi đè thì có thể các dữ liệu hiển thị không chính xác nếu không nắm vững WP_Query.

Điểm lợi của cách làm này là query gần giống các default query và có thể sử dụng the_posts_pagination().

Ví dụ 1:

Ví dụ 2:

[/sociallocker]

 

Tổng kết

WordPress Pagination là một tính năng mà rất nhiều website cần phải có để đảm bảo hiệu suất và tỷ lệ conversation về content cao. Nếu bạn cần phải phát triển giao diện với các tính năng tương tự, bài viết trên sẽ là gợi ý hay để bạn hoàn thành tốt công việc.

Trong trường hợp bạn cần một plugin nào đó thay thế, WP-Pagenavi là một gợi ý rất xứng đáng.

Nếu bạn có câu hỏi gì chưa rõ, đừng quên bình luận nhé.

Viết một bình luận


Chuyên gia về Web
Bạn muốn làm việc với dịch vụ website do chúng tôi triển khai?
Gọi tư vấn 0982.90.4343
Chuyên gia về Web
Bài viết liên quan

02/01/2024

Fix lỗi npm không thể cài các package devDependencies
Khi cài đặt dự án,  có lúc bạn sẽ cài mãi cũng không đủ các package npm, đặc biệt là...
Gọi file PHP trong WordPress

19/09/2023

Cài đặt và sử dụng WP-CLI trên môi trường Linux
Trên một số môi trường Hosting có thể cung cấp SSH hoặc Terminal access, song không có sẵn WP-CLI để...
Import database MySQL lớn trên môi trường Docker

06/08/2023

Import database MySQL lớn trên môi trường Docker
Mình sử dụng EasyPanel để quản lý các Docker và build môi trường app. Nay gặp tình huống phải import...

28/01/2023

Hướng dẫn cài đặt php extension mongodb trên Mac OS M1
Khi bạn muốn hỗ trợ MongoDB trên dòng Mac M1, phần cài đặt sẽ cần một chút lưu ý. Hướng...