#9 – WordPress The Loop và WP_Query – Hiển thị bài viết bằng vòng lặp

0

Ok, qua nhiều bài học, chúng ta đã gần như hoàn thiện bộ khung cho theme. Trong bài học này, chúng ta sẽ hiển thị bài viết bằng vòng lặp – The Loop và WP Query.

Video Hiển thị bài viết bằng vòng lặp – The Loop và WP Query

Hướng dẫn chi tiết

Chuẩn bị bài viết demo

Các bạn cài cho mình plugin Faker Press để tạo cho mình khoảng 15 – 20 bài viết nhé. Nhớ thêm ảnh đại diện, hình ảnh trong bài viết để chúng ta có thể test được nhiều tính năng.

Plugin: Link download

Hình ảnh: Google Drive

Vòng lặp là gì – The Loop?

Vòng lặp là cơ chế mặc định mà WordPress sử dụng để hiển thị các bài viết thông qua một template files (index.php, archive.php, page.php …). Số lượng bài đăng được truy xuất được xác định bởi số lượng bài đăng để hiển thị trên mỗi trang được xác định trong cài đặt Reading.

Link tài liệu về The Loop

WP_Query

Để thao tác truy xuất, hiển thị dữ liệu bên trong vòng lặp, WordPress cung cấp cho chúng ta lớp WP_Query với rất nhiều các phương thức được viết sẵn.

Lưu ý: Chúng ta không nên tác động, thay đổi trực tiếp các thuộc tính bên trong WP_Query, tức là sửa nguồn core WordPress. Thay vào đó, để tùy chỉnh các truy xuất hay thao tác với dữ liệu, chúng ta sẽ dùng các phương thức, thay vào các đối số vào các phương thức đó.

"Người ta tắt AdsBlock không phải vì người ta dại, mà người ta quý mình nên coi quảng cáo"

Hosting WordPress nhanh, rẻ và dễ sử dụng có free SLL hãy chọn Azdigi nhé.
Link đăng ký: https://my.azdigi.com/aff.php?aff=1612
Nếu các bạn mua hosting từ link trên, mình sẽ có một ít tiền để duy trì. Cảm ơn

Mặc định WordPress đã tạo sẵn cho chúng ta một đối tượng WP_Query nằm ở dạng biến toàn cục $wp_query dựa trên những cài đặt của chúng ta, những thiết lập mặc định của WordPress. Các phương thức của WP_Query sẽ tương tác với $wp_query nếu như chúng ta không tùy chỉnh gì.

Link tài liệu WP_Query class

Template tags

Template tag chỉ đơn giản là một đoạn mã yêu cầu WordPress để lấy thứ gì đó từ cơ sở dữ liệu cho chúng ta. Template tag có dạng như một hàm PHP, một số template tag cho phép bạn truyền tham số. Template tag có thể trả về dữ liệu nào đó hoặc trực tiếp in ra kết quả. Ví dụ get_the_title trả về tiêu đề bài viết, the_title sẽ in ra màn hình tiêu đề bài viết – the_title() tương đương với echo get_the_title().

Lưu ý: Một số template tag chỉ hoạt động trong vòng lặp vì nó yêu cầu biến toàn cục $wp_query

Các template tag file được lưu trữ trong thư mục bao gồm wp. Các tệp có hậu tố “-template.php” để phân biệt chúng với các tệp WordPress khác. Các bạn có thể tham khảo danh sách các template tag tại List of template tags WordPress

Thêm image size

Do giao diện html của chúng ta sử dụng một số image size khác so với mặc định của WordPress, do đó chúng ta nên khai báo iamge size để dễ quản lý, cũng như WordPress sẽ crop hình bạn up lên theo chuẩn image size đó, giúp tối ưu tốc độ tải.

Các bạn mở file setup.php và thêm add_image_size vào hàm glw_theme_setup

add_image_size( 'grid_post_thumbnail', 370, 216, true );
add_image_size( 'list_post_thumbnail', 770, 400, true );
add_image_size( 'single_post_thumbnail', 800, 430, true );
add_image_size( 'list_mini_thumbnail', 80, 80, true );
add_image_size( 'author_thumbnail', 82, 82, true );

Hiển thị danh sách bài viết

Cấu trúc cơ bản của một vòng lặp.

  • Kiểm tra xem có bài viết hay không bằng phương thức have_posts của đối tượng $wp_query
  • Duyệt qua từng bài viết bằng phương thức the_post. Phương thức này sẽ đánh dấu bài viết đã được duyệt qua và dẩy sang bài viết kế tiếp. Nếu không có the_post, vòng lặp sẽ vô tận với duy nhất 1 bài viết.
  • Sử dụng các tempalte tag để lấy hoặc hiển thị nội dung.
if(have_posts(  )):
  while(have_posts(  )):
      the_post();
      // hiển thị bài viết
      the_title();
      the_content();
  endwhile;
endif;

File content-excerpt chứa html của bài viết

Các bạn tạo 1 thư mục tên partials nằm trong thư mục chính goclamweb. Sau đó, tạo giúp mình file content-excerpt.php

File content-excerpt.php sẽ chứa code html và các template tag để hiển thị dữ liệu của mỗi bài viết bao gồm ( tiêu đề, đường dẫn, tóm tắt, thumbnail …). Các bài viết đều được hiển thị giống nhau, lặp đi lặp lại nhiều lần nên chúng ta chỉ cần giữ 1 khối là đủ.

<div class="col-xs-12 col-sm-6 mb-30">
    <div class="blog-post">
        <div class="thumb text-center">
            <a href="<?php the_permalink( ); ?>">
            <?php
            the_post_thumbnail( 'grid_post_thumbnail', array(
                'alt'	=> get_post_meta( get_post_thumbnail_id(get_the_ID()),
                '_wp_attachment_image_alt', true)
            ) );
            ?>
            </a>
        </div>
        <div class="blog-content ptb-30 plr-35">
            <div class="date-box clearfix mb-20">
                <h4 class="theme-color pull-left no-margin"><?php echo get_the_time('d'); ?> 
                     <span><?php echo get_the_time('m') ?></span>
                </h4>
                <div class="name-comment pl-15">
                    <h5 class=" mb-5"><span class="theme-color">
                       <?php echo __('By: ', 'glw');?></span> <?php the_author(); ?>
                    </h5>
                    <h5 class="no-margin">
                       <span class="theme-color"><?php echo __('Comments: ', 'glw'); ?></span> 
                       <?php echo get_comments_number( get_the_ID() ); ?>
                    </h5>
                </div>
            </div>
            <a href="<?php the_permalink( ); ?>">
                <h3 class="text-capitalize"><?php glw_post_title(4,get_the_ID(  )); ?></h3>
            </a>
            <p><?php glw_post_excerpt(7, get_the_ID(  )); ?></p>
        </div>
    </div>
</div>
<!-- /.Post End -->

Một số template tag sẽ có 2 dạng là get_the_xxx và the_xxx. Dạng get_the_xxx sẽ lấy dữ liệu và return cho bạn giá trị nào đó, bạn có thể gán giá trị đó cho biến hoặc dùng giá trị đó để làm đối số thêm vào 1 hàm xử lý khác. Dạng the_xxx sẽ không trả về giá trị mà sẽ echo. Ví dụ để lấy tiêu đề bài viết và in ra màn hình, chúng ta có 2 cách sau:

the_title();

hoặc

$title = get_the_title();
echo $title;

Lưu ý:

  • Các template tag này chỉ có thể sử dụng trong vòng lặp, sau phương thức the_post.
  • Chúng ta không cần khởi tạo $wp_query vì WordPress đã khởi tạo sẵn cho chúng ta rồi. Chỉ khi nào cần tùy biến lại vòng lặp, chúng ta mới cần khởi tạo đối tượng và thay các đối số truyền vào. Để kiểm tra, các bạn có thể thử var_dump($wp_query) để xem két quả như thế nào.

Trong file template index.php, chúng ta sẽ gọi giao diện của bài viết riêng bằng hàm get_template_part, trong đó

  • Tham số đầu tiên là đường dẫn cho mẫu chung.
  • Tham số thứ hai là tên riêng cho file

Mình đặt tên cho các file template part sẽ có dạng là content-$ten-rieng.php

Sử dụng hàm get_template_part(‘partials/content’, $ten-rieng). WordPress sẽ tự hiểu rằng vào thư mục partials. Mặc định sẽ lấy file content.php nếu bạn không thêm tham số ‘$ten-rieng‘.

if(have_posts(  )):
	while(have_posts(  )):
		the_post();
		get_template_part( 'partials/content','excerpt' );
	endwhile;
endif;

Thực sự ra không nhất thiết lúc nào cũng là content-xxx.php như mình, đặt sao cũng được miễn là đườgn dẫn trong get_template_part đúng với tên file bạn đã đặt (bỏ chữ php đi nhé).

Vài giây cho quảng cáo Hosting

Các bạn cần hosting PHP - WordPress nhanh, rẻ và dễ sử dụng có thể chọn Azdigi nhé.
Link đăng ký: https://my.azdigi.com/aff.php?aff=1612
Nếu các bạn đăng ký và sử dụng hosting, Góc Làm Web sẽ có một ít tiền để duy trì.

Tùy chỉnh các template tag

Các bạn sẽ thấy trong template part có 2 hàm glw_post_title và glw_post_excerpt. Đó là 2 hàm mình dùng để rút ngắn lại tiêu đề và phần tóm tắt.

Các bạn tạo 1 file custom-post-content.php nằm trong thư mục goclamweb/includes. Hai hàm đó như sau

if(!function_exists('glw_post_excerpt')){
    function glw_post_excerpt($limit, $id_post){
        // string rất dài
        $excerpt = explode(' ', get_the_excerpt(  ), $limit + 1);
        array_pop($excerpt);
        $excerpt = implode(' ',$excerpt )
               .'... <a href="'.get_permalink( $id_post )
               .'">'.__('Read more','glw').'</a>';
        echo $excerpt;
    }
}
if(!function_exists('glw_post_title')){
    function glw_post_title($limit, $id_post){
        // string rất dài
        $title = explode(' ', get_the_excerpt(  ), $limit);
        array_pop($title);
        $title = implode(' ',$title );
        echo $title;
    }
}

Cách làm của chúng ta là lấy tiêu đề bằng get_the_title. Sau đó biến từ chuỗi sang mảng bằng explode và chỉ giữ lại một số phần tử nào đó. Chuyển mảng trở lại chuỗi bằng implode và in ra màn hình hoặc return rồi echo sau cũng được.

Cách thứ 2, các bạn sẽ giới hạn số dòng của tiêu đề và đoạn tóm tắt bằng css. Thêm đoạn css này vào style.css trong assets/css.

.blog-content h3{
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 1;
}
.blog-content p{
	overflow: hidden;
	text-overflow: ellipsis;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	min-height:50px;
}
.blog-content p a{
	color: #111;
}
.blog-content p a:hover {
	color: #169eb7;
}

Trong bài viết, đôi lúc hướng dẫn khó hiểu nên các bạn có thể tại code về và xem lại. Ngoài ra các bạn nên xem hướng dẫn các hàm trên WordPress Dev để hiểu cặn kẽ hơn.

Tài liệu WordPress

Link tài liệu chính chủ WordPress về các hàm đã dùng trong bài học nếu muốn tìm hiểu sâu hơn

Code hoàn thành của bài học: Google Drive

Nếu có thắc mắc, đặt câu hỏi bằng cách comment bên dưới, qua email, hoặc nhắn tin qua Fanpage Góc làm web.

Đừng quên LikeShare nếu thấy bài viết thú vị.

Liên hệ

Để lại một trả lời

Địa chỉ email của bạn sẽ không được công bố.