Hướng dẫn WordPress Custom Post Types: Taxonomy, Admin Column, Filter và Archive

Trước khi xem qua bài này, bạn hãy dành ra chút thời gian đọc qua bài viết về Custom Post Types để nắm được những khái niệm cơ bản của Custom Post Types. Trong bài hướng dẫn sau đây, chúng ta sẽ cùng nhau tìm hiểu thêm về tính năng tuyệt vời này trong WordPress.

Qua hướng dẫn này, bạn sẽ biết được cách làm thế nào để tạo custom taxonomy, admin column (cột quản trị), taxonomy filter (bộ lọc) và archive page (trang lưu trữ) cho Custom Post Types của bạn.

Custom Taxonomy cho Custom Post Types

Taxonomy là một cách tuyệt vời để phân loại bài viết, giúp chúng ta thuận tiện hơn trong việc tìm kiếm các bài viết theo mục cụ thể. Trong WordPress, chúng ta thường sử dụng Categories và Tags làm taxonomy. Các bước dưới đây sẽ giải thích cách tạo custom taxonomy cho Custom Post Types của bạn.

Bước 1: Đăng ký Custom Function

Mở file plugin của bạn lên, trong trường hợp này là file Movie-Reviews.php và thêm code dưới đây vào file để đăng ký custom function.

add_action( 'init', 'create_my_taxonomies', 0 );

Bước 2: Thực hiện Custom Function và đăng ký Custom Taxonomy

function create_my_taxonomies()
{
     register_taxonomy(
          'movie_reviews_movie_genre',
          'movie_reviews',
          array(
               'labels' => array(
                    'name' => 'Movie Genre',
                    'add_new_item' => 'Add New Movie Genre',
                     'new_item_name' => "New Movie Type Genre"
               ),
               'show_ui' => true,
               'show_tagcloud' => false,
               'hierarchical' => true
          )
     );
}

Ở đây, function register_taxonomy chăm chỉ làm tất cả các công việc để tạo ra một custom taxonomy (trong trường hợp này là một category) với tên ‘movie_reviews_movie_genre' cho custom post type ‘movie_reviews'. 'labels' định nghĩa các chuỗi khác nhau được sử dụng trong phần admin của taxonomy.

  • 'show_ui' => true được sử dụng để làm taxonomy editor hiển thị trong dashboard.
  • 'show_tagcloud' => false giải mã liệu đám mây từ khóa có nên được hiển thị không. Trong trường hợp này, chúng bị vô hiệu hóa.
  • 'hierarchical' => true giải mã các định dạng của custom taxonomy.

Ghi chú: 'hierarchical' => false chuyển đổi các category thành các tag.

Sau khi lưu file Movie-Reviews.php, mở file custom template của bạn lên, trong trường hợp này là file single-movie_reviews.php và thêm đoạn code được đánh dấu sau để category hiển thị trong các bài viết của bạn.

<?php
 /*Template Name: New Template
 */
get_header(); ?>
<div id="primary">
     <div id="content" role="main">
          <?php
               $mypost = array( 'post_type' => 'movie_reviews', );
               $loop = new WP_Query( $mypost );
          ?>
          <!-- Cycle through all posts -->
          <?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
               <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                    <header class="entry-header">
                         <!-- Display featured image in top-aligned floating div -->
                         <div style="float: top; margin: 10px">
                              <?php the_post_thumbnail( array( 100, 100 ) ); ?>
                         </div>
                         <!-- Display Title and Author Name -->
                         <strong>Title: </strong><?php the_title(); ?><br />
                         <strong>Director: </strong>
                         <?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?>
                         <br />
                         <strong>Genre: </strong>
                         <?php
                              the_terms( $post->ID, 'movie_reviews_movie_genre' ,  ' ' );
                         ?>
                         <br />
                         <!-- Display yellow stars based on rating -->
                         <strong>Rating: </strong>
                         <?php
                              $nb_stars = intval( get_post_meta( get_the_ID(), 'movie_rating', true ) );
                              for ( $star_counter = 1; $star_counter <= 5; $star_counter++ )
                              {
                                   if ( $star_counter <= $nb_stars )
                                   {
                                        echo '<img src="' . plugins_url( 'Movie-Reviews/images/icon.png' ) . '" />';
                                   }
                                   else
                                   {
                                        echo '<img src="' . plugins_url( 'Movie-Reviews/images/grey.png' ). '" />';
                                   }
                              }
                         ?>
                    </header>
                    <!-- Display movie review contents -->
                    <div class="entry-content">
                         <?php the_content(); ?>
                    </div>
                    <hr/>
               </article>
          <?php endwhile;  ?>
     </div>
</div>
<?php wp_reset_query(); ?>
<?php get_footer(); ?>

Bước 4: Kết quả

Vậy là chúng ta đã thêm một custom taxonomy ‘Movie Genre’ trong phần Movie Reviews của Custom Post Types. Bây giờ, chúng ta có thể thêm các category mới từ bảng quản trị và gán từng category đó vào Custom Post Types.

1

2

3

Hiển thị các cột bổ sung

Trong WordPress admin, trang danh sách Custom Post Types mặc định gồm có 2 cột là DateComments, qua đó chúng ta có thể sắp xếp các mục của Custom Post Types. Để bổ sung thêm và sắp xếp các cột, bạn hãy thực hiện theo các bước sau:

Mở file plugin Movie-Reviews.php và thêm dòng code sau để đăng ký một function được gọi khi trang danh sách Movie Reviews được chuẩn bị.

add_filter( 'manage_edit-movie_reviews_columns', 'my_columns' );

Chúng ta sử dụng biến filter manage_edit-(Custom_Post_Type)_columns để thông qua danh sách cột của Custom Post Types như một đối số cho function.

function my_columns( $columns )
{
     $columns['movie_reviews_director'] = 'Director';
     $columns['movie_reviews_rating'] = 'Rating';
     unset( $columns['comments'] );
     return $columns;
}

Ở đây, chúng ta bổ sung thêm 2 cột là DirectorRating trong bảng quản trị của Custom Post Types và xóa cột Comments từ danh sách.

Bước 3: Điền cột

Đăng ký một function để điền cột

add_action( 'manage_posts_custom_column', 'populate_columns' );

Bước 4: Thực hiện

function populate_columns( $column )
{
     if ( 'movie_reviews_director' == $column )
     {
          $movie_director = esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) );
          echo $movie_director;
     }
     else if ( 'movie_reviews_rating' == $column )
     {
          $movie_rating = get_post_meta( get_the_ID(), 'movie_rating', true );
          echo $movie_rating . ' stars';
     }
}

Ở đây, function được thực hiện khi bất kỳ cột nào đó của Custom Post Types được hiển thị. Function sẽ kiểm tra các cột hiện tại theo yêu cầu trước khi lặp lại chúng. Chúng ta sử dụng function get_the_ID() để lấy chỉ số của hàng hiện tại và sau đó lần lượt sử dụng get_post_meta để lấy dữ liệu trong cột.

Bây giờ, chúng ta đăng ký một function được gọi khi WordPress xác định cột làm sắp xếp trong Custom Post Types.

add_filter( 'manage_edit-movie_reviews_sortable_columns', 'sort_me' );

Bước 6: Thực hiện

function sort_me( $columns )
{
     $columns['movie_reviews_director'] = 'movie_reviews_director';
     $columns['movie_reviews_rating'] = 'movie_reviews_rating';

     return $columns;
}

Function này xác định 2 cột để làm sắp xếp cho chúng và sau đó trả về mảng. Nhưng công việc của chúng ta vẫn chưa kết thúc tại đây.

add_filter( 'request', 'column_ordering' );

add_filter( 'request', 'column_orderby' );

function column_orderby ( $vars )
{
     if ( !is_admin() )
          return $vars;
     if ( isset( $vars['orderby'] ) && 'movie_reviews_director' == $vars['orderby'] )
     {
          $vars = array_merge( $vars, array( 'meta_key' => 'movie_director', 'orderby' => 'meta_value' ) );
     }
     elseif ( isset( $vars['orderby'] ) && 'movie_reviews_rating' == $vars['orderby'] )
     {
          $vars = array_merge( $vars, array( 'meta_key' => 'movie_rating', 'orderby' => 'meta_value_num' ) );
     }
     return $vars;
}

Function trên được liên kết với bộ lọc theo yêu cầu và thêm phần tử vào mảng truy vấn dựa trên các biến trong URL truy vấn. Trên thực tế, WordPress không biết làm thế nào để sắp xếp theo ‘Movie Director’ hay ‘Movie Rating’, vì vậy chúng ta “dạy” cho WordPress cách để làm điều đó bằng chức năng này.

Chúng ta đã thêm thành công 2 cột sắp xếp trong phần admin.

11

Chúng ta thấy custom taxonomy (trong trường hợp này là category) có thể được sử dụng như một bộ lọc bổ sung trong trang danh sách Custom Post Types ở admin WordPress, vì vậy các quản trị viên có thể hiển thị các phần tử của Custom Post Types theo category cụ thể.

Bước 1: Đăng ký Function

Mở file plugin của bạn và thêm đoạn code sau để đăng ký một function được gọi khi WordPress đang chuẩn bị để hiển thị bộ lọc với drop-down list.

add_action( 'restrict_manage_posts', 'my_filter_list' );

Bước 2: Thực hiện Function

function my_filter_list()
{
     $screen = get_current_screen();
     global $wp_query;
     if ( $screen->post_type == 'movie_reviews' )
     {
          wp_dropdown_categories(
               array(
                    'show_option_all' => 'Show All Movie Genres',
                    'taxonomy' => 'movie_reviews_movie_genre',
                    'name' => 'movie_reviews_movie_genre',
                    'orderby' => 'name',
                    'selected' => ( isset( $wp_query->query['movie_reviews_movie_genre'] ) ? $wp_query->query['movie_reviews_movie_genre'] : '' ),
                    'hierarchical' => false,
                    'depth' => 3,
                    'show_count' => false,
                    'hide_empty' => true,
               )
          );
     }
}

Ở đây, chúng ta sử dụng một biến chung để biết loại bài viết đang được hiển thị và sử dụng một biến truy vấn để kiểm tra đã có bộ lọc hiện tại và phù hợp với thiết lập của bộ lọc chưa. Function wp_dropdown_categories được sử dụng để hiển thị tất cả taxonomy đã đăng ký với Movie Genres. ‘orderby‘, ‘show_count‘, ‘hide_empty‘, ‘depth‘ … là các đối số khác nhau chỉ định sắp xếp, hiển thị mục đếm từng category, ẩn category không liên quan, xác định độ sâu tối đa được hiển thị cho các mục phân cấp tương ứng.

Bước 3: Hiển thị kết quả lọc

Bây giờ, sau khi bộ lọc với drop down list đã được chuẩn bị sẵn sàng, chúng ta sẽ viết code để hiển thị kết quả lọc. Đăng ký một function được gọi khi truy vấn hiển thị bài viết được chuẩn bị.

add_filter( 'parse_query','perform_filtering' );

Bước 4: Thực hiện Function hiển thị

function perform_filtering( $query )
{
     $qv = &$query->query_vars;
     if ( ( $qv['movie_reviews_movie_genre'] ) && is_numeric( $qv['movie_reviews_movie_genre'] ) )
     {
          $term = get_term_by( 'id', $qv['movie_reviews_movie_genre'], 'movie_reviews_movie_genre' );
          $qv['movie_reviews_movie_genre'] = $term->slug;
     }
}

Function perform_filtering nhận đối tượng truy vấn bài viết WordPress hiện tại và trỏ đến các biến truy vấn được lưu trữ bên trong đối tượng truy vấn. Sau đó, nó xác minh Movie Genre là một phần của các biến truy vấn chưa và thực hiện truy vấn.

Bây giờ, bạn đã có thể sử dụng bộ lọc để hiển thị Movies theo Genres.

22

Tạo Archive Page (trang lưu trữ)

Tương tự như việc tạo một custom template cho Custom Post Types, chúng ta cũng có thể tạo một custom archive page ghi đè lên archive template mặc định.

Bước 1: Thêm một Archive Template dự phòng

Mở file plugin Movie-Reviews.php và thêm đoạn code được đánh dấu vào function include_template_function.

function include_template_function( $template_path )
{
if ( get_post_type() == 'movie_reviews' )
     {
          if ( is_single() )
          {
               // checks if the file exists in the theme first,
               // otherwise serve the file from the plugin
               if ( $theme_file = locate_template( array ( 'single-movie_reviews.php' ) ) )
               {
                    $template_path = $theme_file;
               }
               else
               {
                    $template_path = plugin_dir_path( __FILE__ ) . '/single-movie_reviews.php';
               }
          }
          else if ( is_archive() )
          {
               if ( $theme_file = locate_template( array ( 'archive-movie_reviews.php' ) ) )
               {
                    $template_path = $theme_file;
               }
               else
               {
                    $template_path = plugin_dir_path( __FILE__ ) . '/archive-movie_reviews.php';
               }
          }
     }
     return $template_path;
}

WordPress tìm kiếm thông qua thư mục theme một file archive template trước khi sử dụng làm mặc định. Function này kiểm tra xem người dùng đã cung cấp một archive template trong thư mục theme chưa, nó giống với tìm file trong folder plugin.

Bước 2: Tạo Archive Template

Lưu và đóng file plugin lại, sau đó tạo một file mới có tên là archive-movie_reviews.php và thêm đoạn code sau vào.

<?php get_header(); ?>
<section id="primary">
     <div id="content" role="main" style="width: 70%">
          <?php if ( have_posts() ) : ?>
               <header>
                    <h1>Movie Reviews</h1>
               </header>
              <table>
                   <!-- Display table headers -->
                   <tr>
                        <th style="width: 200px"><strong>Title</strong></th>
                        <th><strong>Director</strong></th>
                   </tr>
                   <!-- Start the Loop -->
                   <?php while ( have_posts() ) : the_post(); ?>
                        <!-- Display review title and author -->
                        <tr>
                             <td><a href="<?php the_permalink(); ?>">
                             <?php the_title(); ?></a></td>
                             <td><?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?></td>
                        </tr>
                   <?php endwhile; ?>

                   <!-- Display page navigation -->
               </table>
               <?php global $wp_query;
                    if ( isset( $wp_query->max_num_pages ) && $wp_query->max_num_pages > 1 ) { ?>
                         <nav id="<?php echo $nav_id; ?>">
                              <div><?php next_posts_link( '<span>&larr;</span> Older reviews'); ?></div>
                              <div><?php previous_posts_link( 'Newer reviews <span class= "meta-nav">&rarr;</span>' ); ?></div>
                         </nav>
               <?php };
          endif; ?>
     </div>
</section>
<br /><br />
<?php get_footer(); ?>

Ở đây, chúng ta sử dụng vòng lặp có chu trình đi qua các mục của bài viết và sau đó hiển thị chúng bằng cách sử dụng table layout. Chúng ta cũng định nghĩa một navigation menu nếu các mục có số lượng nhiều hơn cấu hình tối đa dưới WordPress Settings. Navigation menu được hiển thị bằng cách sử dụng function next_post_linksprevious_post_links.

Chúng ta sử dụng đối tượng chung wp_query chứa dữ liệu về truy vấn đang thực hiện để đưa ra nội dung trang. Function get_post_meta được sử dụng để lấy ra dữ liệu custom field.

Bước 3: Kết quả

Lưu file và kiểm tra archive page cho danh sách lưu trữ của Movie Reviews.

33

Vậy là chúng ta đã đi đến cuối cùng bài hướng dẫn này. Qua bài viết, mình mong là các bạn đã nắm được tầm quan trọng của Custom Post Types. Còn rất nhiều điều về Custom Post Types mà chúng ta chưa khám phá hết, đây mới chỉ là một phần nhỏ mà thôi.

Chúc bạn thành công.

Cám ơn bạn đã đọc bài viết của mình, nếu bạn thấy hay thì hãy chia sẻ nó cho mọi người nhé.


Leave a Reply

Your email address will not be published. Required fields are marked *

×