Hướng dẫn tạo Custom Post Type trong WordPress

Hướng dẫn tạo Custom Post Type trong WordPress

Custom Post Type (CPT) là một trong những tính năng đặc biệt rất hay của WordPress, nhờ tính năng này mà WordPress có thể trở thành nhiều loại website khác nhau đáp ứng được yêu cầu. Woocommerce là một plugin sử dụng CPT để tạo ra loại post là sản phẩm. Một CPT thường có đầy đủ như danh mục (category), thẻ (tag), trường tùy biến (custom field), ảnh đại diện (featured image),… Bài viết sau đây sẽ hướng dẫn bạn tạo một CPT sản phẩm cơ bản nhất.

Tạo Custom Post Type trong function.php

Custom Post Type (CPT) sử dụng hook init để móc vào. Hàm để đăng ký CPT là register_post_type với 2 tham số là slug-post-type và một mảng các tham số. Code như sau:

function cpt_demo() {
                     $args = array(
                                      //các tham số dành cho custom post type
                                   );
                      register_post_type( 'slug-post-type' , $args );
                     }
add_action( 'init', 'cpt_demo' );
  • Các tham số là rất quan trọng và cần thiết trong CPT và bắt buột phải truyền vào.
  • Slug cũng rất quan trọng không kém, bạn đặt slug bằng cái gì cũng được như yêu cầu là không dấu, không cách, hay có ký tự đặt biệt nhé. nó sẽ được hiển thị trên thanh URL đấy.

Các tham số truyền vào Custom Post Type

Đây là thành phần quan trọng và cũng là phần bạn phải làm việc nhiều nhất trong việc tạo CPT. Các tham số rất nhiều và phức tạp, bạn nên tìm hiểu trước để lựa chọn đưa vào các tham số phù hợp. Bạn có thể xem chi tiết tại đây. Ở dưới đây mình sẽ hướng dẫn tạo ra một loại post sản phẩm đơn giản.

Đầu tiên, trong hàm “cpt_demo” mình sẽ tạo ra một biến mảng $label để lưu trữ tất cả các tên của lable, có rất nhiều tên của label mà bạn cần tham khảo trên trang chủ của WordPress thì mới biết được. Ở dưới mình chỉ liệt kê vài thứ.

$label = array( 'name' => 'Các sản phẩm', 
                          'singular_name' => 'Sản phẩm', 
                          'add_new' => 'Thêm sản phẩm', 
                          'add_new_item' => 'Thêm sản phẩm mới', 
                          'edit_item' => 'Sửa sản phẩm', 
                          'new_item' => 'Sản phẩm mới', 
                          'view_item' => 'Xem sản phẩm', 
                          'view_items'=>'Xem tất cả sản phẩm', 
                          'search_items'=>'Tìm kiếm sản phẩm', 
                          'not_found'=>'Không có sản phẩm', 
                          'not_found_in_trash'=>'Không có sản phẩm nào trong thùng rác', 
                          'parent_item_colon'=>'Danh mục cha', 
                          'all_items'=>'Tất cả sản phẩm', 
                          'archives'=>'Danh mục', 
                          'attributes'=>'Thuộc tính', 
                          'insert_into_item'=>'Thêm phương tiện', 
                          'uploaded_to_this_item'=>'Tải lên phương tiện', 
                          'featured_image'=>'Ảnh sản phẩm', 
                          'set_featured_image'=>'Thêm hình ảnh sản phẩm', 
                          'remove_featured_image'=>'Xóa hình ảnh sản phẩm', 
                          'use_featured_image'=>'Sử dụng hình ảnh sản phẩm', 
                          'menu_name'=>'Sản phẩm custom', 
                          'name_admin_bar'=>'Sản phẩm',);

Lable thì cũng không quan trong lắm. Nhưng mà nó thể hiện được bảng chất cái custom post của bạn là gì. Nếu viết theme thì hãy làm tốt điều này nhé.

Tiếp theo mình sẽ khai báo thêm một biết mảng có tên $support để truyền vào đây các loại mà loại post này hỗ trợ ví dụ như hỗ trợ tiêu đề, chỉnh sửa, mô tả ngắn, hình ảnh đại diện,…. Biến như sau:

$support = array( 'title',
                  'editor',
                  'excerpt',
                  'author',
                  'thumbnail', 
                  'comments', 
                  'trackbacks',
                  'custom-fields',
                  'revisions',
                  'page-attributes', 
                  'post-formats' );
  • title: Hỗ trợ tiêu đề.
  • editor: Cho phép nội dung.
  • excerpt: cho phép mô tả ngắn.
  • author: cho phép lựa chọn tác giả.
  • thumbnail: cho phép chọn ảnh đại diện.
  • comments: cho phép tùy chọn bình luận hay không.
  • trackbacks: hỗ trợ trackbacks.
  • custom-fields: cho phép các trường tùy chỉnh.
  • revisions: hiển thị các phiên bản tự động lưu.
  • page-attributes: hiên thị số thứ tự, chỉ hiển thị với danh mục.
  • post-formats: hỗ trợ post format.

Bây giờ bạn đã có 2 biến mảng title và support, bây giờ mình sẽ tạo một mảng quan trọng nhất có tên $arr để chứa toàn bộ các biến mảng trên, đồng thời sẽ chứa một số thuộc tính quan trọng nữa. Toàn bộ biến này như sau

$arr = array( 
    'labels' => $label, 
    'description' => 'Mô tả về loại post này',
    'supports' => $support, 
    'taxonomies' => array( 'category', 'post_tag','nav_menu', 'nav_menu_item' ), 
    'hierarchical' => false, 
    'public' => true, 
    'show_ui' => true, 
    'show_in_menu' => true,
    'show_in_nav_menus' => true, 
    'show_in_admin_bar' => true, 
    'menu_position' => 5, 
    'menu_icon' => 'esc_url( get_template_directory_uri() ).'/img/pro.png', 
    'can_export' => true, 
    'has_archive' => true, 
    'exclude_from_search' => false, 
    'publicly_queryable' => true, 
    'capability_type' => 'post',);
  • labels: sẽ được gán biến mảng $lable mình đã tạo trên.
  • description: Mô tả của loại post type này, tuy nhiên mình chả thấy nó hiển thị ở đâu hihi.
  • supports: sẽ được gán biến mảng $support mình đã tạo trên.
  • taxonomies: taxonomies bạn muốn thêm vào ví dụ như trên là thêm danh mục và tag: những taxonomies như ‘category’, ‘post’, ‘post_tag’‘nav_menu’‘nav_menu_item’,…
  • hierarchical: Được gọi là thứ bật, nếu chọn False thì nó được xem như một post, chọn True thì nó như một Page. Tuy nhiên nó không quá ảnh hưởng đến post type.
  • public: post type có được kích hoạt hay không.
  • show_ui: Hiển thị khung quản trị hay không.
  • show_in_menu: Cho phép hiển thị trên menu admin (ở bên trái).
  • show_in_nav_menus: Cho phép hiển thị trong tùy chọn menu hay không (menu trên giao diện).
  • show_in_admin_bar: Cho phép hiển thị trên menu ngang trên cùng hay không.
  • menu_position: vị trí menu ở dải menu bên trái (5 dưới bài viết).
  • menu_icon: đường dẫn đến icon hiển thị ở bên.
  • can_export: cho phép export bằng công cụ export (tools->export).
  • has_archive: cho phép lưu trữ. (ngày/tháng/năm).
  • exclude_from_search: loại bỏ khỏi tìm kiếm hay không? để false để cho phép tìm kiếm.
  • publicly_queryable: Hiển thị các thông số trong truy vấn. Để True nhé.
  • capability_type: loại phân cấp.

Như vậy là mình đã hoàn thiện việc thêm các thông số và mảng $arr. bây giờ mình sẽ sử dụng một hàm có tên register_post_type để đăng ký post type này. Lưu ý là hàm này được viết trong trong hàm cpt_demo() luôn nhé.

register_post_type('san-pham', $arr);

Ngắn gọn vậy thôi. Toàn bộ đoạn code như sau:

function cpt_demo() {function cpt_demo() {                                                         
    $label = array( 'name' => 'Các sản phẩm', 'singular_name' => 'Sản phẩm', 'add_new' => 'Thêm sản phẩm', 'add_new_item' => 'Thêm sản phẩm mới', 'edit_item' => 'Sửa sản phẩm', 'new_item' => 'Sản phẩm mới', 'view_item' => 'Xem sản phẩm', 'view_items'=>'Xem tất cả sản phẩm', 'search_items'=>'Tìm kiếm sản phẩm', 'not_found'=>'Không có sản phẩm', 'not_found_in_trash'=>'Không có sản phẩm nào trong thùng rác', 'parent_item_colon'=>'Danh mục cha', 'all_items'=>'Tất cả sản phẩm', 'archives'=>'Danh mục', 'attributes'=>'Thuộc tính', 'insert_into_item'=>'Thêm phương tiện', 'uploaded_to_this_item'=>'Tải lên phương tiện', 'featured_image'=>'Ảnh sản phẩm', 'set_featured_image'=>'Thêm hình ảnh sản phẩm', 'remove_featured_image'=>'Xóa hình ảnh sản phẩm', 'use_featured_image'=>'Sử dụng hình ảnh sản phẩm', 'menu_name'=>'Sản phẩm custom', 'name_admin_bar'=>'Sản phẩm',); 
    $support = array( 'title','editor','excerpt','author','thumbnail', 'comments', 'trackbacks','custom-fields','revisions','page-attributes', 'post-formats'  );
    $arr  = array( 'labels' => $label, 'description' => 'Post type đăng sản phẩm',  'supports' => $support, 'taxonomies' => array( 'category', 'post_tag'),  'hierarchical' => true, 'public' => true,  'show_ui' => true, 'show_in_menu' => true,  'show_in_nav_menus' => true, 'show_in_admin_bar' => true,  'menu_position' => 5,  'menu_icon' => esc_url( get_template_directory_uri() ).'/img/pro.png', 'can_export' => true,  'has_archive' => true, 'exclude_from_search' => false, 'publicly_queryable' => true, 'capability_type' => 'post', ); 
    register_post_type('san-pham', $arr);  
}
add_action('init', 'cpt_demo');

Bạn có thể xem một số hình ảnh sau khi mình tạo custom post type như trên.

Menu bên trái xuất hiện tên và icon của custom post type mới

Menu bên trái xuất hiện tên và icon của custom post type mới

Phần post của custom post type mới

Phần post của custom post type mới

Phần biên tập nội dung của custom post type mới (1)

Phần biên tập nội dung của custom post type mới (1)

Phần biên tập nội dung của custom post type mới (2)

Phần biên tập nội dung của custom post type mới (2)

Phần biên tập nội dung của custom post type mới (3)

Phần biên tập nội dung của custom post type mới (3)

Lấy những bài post từ Custom Post Type lên themes

Tương tự cách hiển thị loại post thông thường, custom post type cũng hiển thị trên file single.php, Nhưng nếu bạn muốn nó hiển thị trên một cấu trúc khác bạn có thể tạo một file khác có tên single-{slug-post-type}.php. như trên mình sẽ tạo ra một file tên single-san-pham.php và code hiển thị như bình thường.

Nếu bạn sử dụng truy vấn để lấy những bài post từ custom post type thì bạn chỉ cần truyền thêm thông số post_type là được. ví dụ như:  $new_query = new WP_Query( ‘post_type=san-pham’ );

Tạo Custom Post Type nhanh chóng và không cần code

Bạn có thể sử dụng Plugin Custom Post Type UI để tạo custom post type nhanh chóng ngay trên website của mình. Nếu bạn không bạn có thể sử dụng Custom Post Type Generator để tạo CPT đồng thời có thể download cả source về nữa.

Custom Post type mặc dù rất hay nhưng nó vẫn mang một sự phức tạp lớn. Nếu yêu cầu về loại post của bạn không quá phức tạp và tương tự như post thông thường chỉ muốn hiển thị khác thì bạn có thể sử dụng post format (xem bài: Tạo Post Format cho theme wordpress) để tối ưu đơn giản hơn cho theme của bạn. Nếu bạn muốn thêm nhiều tùy biến hơn cho custom post type bạn có thể sử dụng custom taxonomy (xem bài: Hướng dẫn custom taxonomy kết hợp custom post type trong wordpress).

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