Tổng hợp thủ thuật và hướng dẫn tạo custom post type và custom taxonomy

Cập nhật lần cuối 21/07/2017 by trong WordPress vào 21/07/2017 có 199 Views

Trong bài này sẽ hướng dẫn các tạo thêm 1 custom post type (cpt) giống như Posts và Page mặc định của WordPress và tạo thêm custom taxonomy cho cpt đó. Ngoài ra sẽ hướng dẫn cách thêm link của cpt có slug của taxonomy trong đường dẫn.

Nội dung chính:

  1. Code đăng ký thêm custom post type san_pham
  2. Code đăng ký thêm custom taxonomy danhmuc_sanpham cho post type san_pham
  3. Hướng dẫn rewrite để có dạng san-pham/{danh-muc-san-pham}/{ten-san-pham}
  4. Full code

Kết quả sau khi làm:

  1. Tạo 1 cpt san_pham và có danh mục sản phẩm danhmuc_sanpham
  2. Link archive: http://your-domain.com/san-pham
  3. Link danh mục: http://your-domain.com/san-pham/dien-thoai
  4. Link danh mục con: http://your-domain.com/san-pham/dien-thoai/iphone
  5. Link chi tiết sản phẩm: http://your-domain.com/san-pham/dien-thoai/iphone/iphone-7-64G-trang

Mục đích: Tạo ra 1 cpt có link sản phẩm chưa slug của taxonomy và link danh mục sản phẩm có base giống với base của cpt

Bình thường: /san-pham/iphone-7-64G-trang
Sau bài này: /san-pham/dien-thoai/iphone-7-64G-trang

Code đăng ký thêm custom post type

Để đăng ký thêm custom post type các bạn có thể vào trang https://generatewp.com/post-type/ để tạo. Rất đơn giản và nhanh gọn. Chỉ cần chọn các tùy chọn và sẽ có ngay kết quả.

Dưới đây là code mà mình đã làm từ trang đó. Bạn chỉ cần copy code này vào file functions.php của theme đang sử dụng là được

/* Register Custom Post Type
Author: levantoan.com
*/
function san_pham_func() {
    $labels = array(
        'name'                  => _x( 'Sản phẩm', 'Post Type General Name', 'devvn' ),
        'singular_name'         => _x( 'Sản phẩm', 'Post Type Singular Name', 'devvn' ),
        'menu_name'             => __( 'Sản phẩm', 'devvn' ),
        'name_admin_bar'        => __( 'Sản phẩm', 'devvn' ),
        'archives'              => __( 'Item Archives', 'devvn' ),
        'attributes'            => __( 'Item Attributes', 'devvn' ),
        'parent_item_colon'     => __( 'Parent Item:', 'devvn' ),
        'all_items'             => __( 'All Items', 'devvn' ),
        'add_new_item'          => __( 'Add New Item', 'devvn' ),
        'add_new'               => __( 'Add New', 'devvn' ),
        'new_item'              => __( 'New Item', 'devvn' ),
        'edit_item'             => __( 'Edit Item', 'devvn' ),
        'update_item'           => __( 'Update Item', 'devvn' ),
        'view_item'             => __( 'View Item', 'devvn' ),
        'view_items'            => __( 'View Items', 'devvn' ),
        'search_items'          => __( 'Search Item', 'devvn' ),
        'not_found'             => __( 'Not found', 'devvn' ),
        'not_found_in_trash'    => __( 'Not found in Trash', 'devvn' ),
        'featured_image'        => __( 'Featured Image', 'devvn' ),
        'set_featured_image'    => __( 'Set featured image', 'devvn' ),
        'remove_featured_image' => __( 'Remove featured image', 'devvn' ),
        'use_featured_image'    => __( 'Use as featured image', 'devvn' ),
        'insert_into_item'      => __( 'Insert into item', 'devvn' ),
        'uploaded_to_this_item' => __( 'Uploaded to this item', 'devvn' ),
        'items_list'            => __( 'Items list', 'devvn' ),
        'items_list_navigation' => __( 'Items list navigation', 'devvn' ),
        'filter_items_list'     => __( 'Filter items list', 'devvn' ),
    );
    $rewrite = array(
        'slug'                  => _x('san-pham/%danhmuc_sanpham%','slug', 'devvn'), //Slug của trang chi tiết sản phẩm
        'with_front'            => true,
        'pages'                 => true,
        'feeds'                 => true,
    );
    $args = array(
        'label'                 => __( 'Sản phẩm', 'devvn' ),
        'description'           => __( 'Post Type Description', 'devvn' ),
        'labels'                => $labels,
        'supports'              => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments', ),
        'taxonomies'            => array( 'danhmuc_sanpham' ),
        'hierarchical'          => false,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 5,
        'menu_icon'             => 'dashicons-cart',
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => 'san-pham', //Đường dẫn của archive
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'rewrite'               => $rewrite,
        'capability_type'       => 'page',
    );
    register_post_type( 'san_pham', $args );
}
add_action( 'init', 'san_pham_func', 0 );

Lúc này admin đã có thêm menu Sản phẩm và link post có dạng san-pham/%danhmuc_sanpham%. Đến bước 3 ta bắt đầu xử lý cái này nhé

Code đăng ký thêm custom taxonomy

Code đăng ký thêm custom taxonomy chúng ta cũng có thể tạo bằng cách vào trang này https://generatewp.com/taxonomy/ để tạo. Sau đó copy code vào file functions.php của theme trang sử dụng là được. Và đây là code cho ví dụ

// Register Custom Taxonomy
function danhmuc_sanpham_func() {
    $labels = array(
        'name'                       => _x( 'Danh mục', 'Taxonomy General Name', 'devvn' ),
        'singular_name'              => _x( 'Danh mục', 'Taxonomy Singular Name', 'devvn' ),
        'menu_name'                  => __( 'Danh mục', 'devvn' ),
        'all_items'                  => __( 'All Items', 'devvn' ),
        'parent_item'                => __( 'Parent Item', 'devvn' ),
        'parent_item_colon'          => __( 'Parent Item:', 'devvn' ),
        'new_item_name'              => __( 'New Item Name', 'devvn' ),
        'add_new_item'               => __( 'Add New Item', 'devvn' ),
        'edit_item'                  => __( 'Edit Item', 'devvn' ),
        'update_item'                => __( 'Update Item', 'devvn' ),
        'view_item'                  => __( 'View Item', 'devvn' ),
        'separate_items_with_commas' => __( 'Separate items with commas', 'devvn' ),
        'add_or_remove_items'        => __( 'Add or remove items', 'devvn' ),
        'choose_from_most_used'      => __( 'Choose from the most used', 'devvn' ),
        'popular_items'              => __( 'Popular Items', 'devvn' ),
        'search_items'               => __( 'Search Items', 'devvn' ),
        'not_found'                  => __( 'Not Found', 'devvn' ),
        'no_terms'                   => __( 'No items', 'devvn' ),
        'items_list'                 => __( 'Items list', 'devvn' ),
        'items_list_navigation'      => __( 'Items list navigation', 'devvn' ),
    );
    $rewrite = array(
        'slug'                       => _x('san-pham','slug', 'devvn'),
        'with_front'                 => true,
        'hierarchical'               => true,
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
        'rewrite'                    => $rewrite,
    );
    register_taxonomy( 'danhmuc_sanpham', array( 'san_pham' ), $args );
}
add_action( 'init', 'danhmuc_sanpham_func', 0 );

Sau khi chèn xong code thì trong admin menu Sản phẩm đã có thêm sub menu là Danh mục

Hướng dẫn rewrite custom post type dạng san-pham/%danhmuc_sanpham%

Phần này khá quan trọng. Nếu không có bước này thì đường dẫn của trang chi tiết sản phẩm sẽ có dạng san-pham/%danhmuc_sanpham%. Sau khi rewrite thì đường dẫn sẽ có dạng như sau

  1. Nếu chọn taxonomy: san-pham/{danh-muc}/{ten-san-pham} => san-pham/dien-thoai/iphone-7-64G-trang
  2. Mếu KHÔNG chọn taxonomy: san-pham/khong-phan-loai/{ten-san-pham}

Copy đoạn code sau vào file functions.php của theme đang sử dụng

function devvn_cpt_sanpham_post_type_link( $permalink, $post ) {
    // Abort if post is not a san_pham.
    if ( 'san_pham' !== $post->post_type ) {
        return $permalink;
    }
    // Abort early if the placeholder rewrite tag isn't in the generated URL.
    if ( false === strpos( $permalink, '%' ) ) {
        return $permalink;
    }
    // Get the custom taxonomy terms in use by this post.
    $terms = get_the_terms( $post->ID, 'danhmuc_sanpham' );
    if ( ! empty( $terms ) ) {
        if ( function_exists( 'wp_list_sort' ) ) {
            $terms = wp_list_sort( $terms, 'term_id', 'ASC' );
        } else {
            usort( $terms, '_usort_terms_by_ID' );
        }
        $category_object = apply_filters( 'devvn_cpt_sanpham_post_type_link_product_cat', $terms[0], $terms, $post );
        $category_object = get_term( $category_object, 'danhmuc_sanpham' );
        $product_cat     = $category_object->slug;
        if ( $category_object->parent ) {
            $ancestors = get_ancestors( $category_object->term_id, 'danhmuc_sanpham' );
            foreach ( $ancestors as $ancestor ) {
                $ancestor_object = get_term( $ancestor, 'danhmuc_sanpham' );
                $product_cat     = $ancestor_object->slug . '/' . $product_cat;
            }
        }
    } else {
        // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
        $product_cat = _x( 'khong-phan-loai', 'slug', 'devvn' );
    }
    $permalink = str_replace( '%danhmuc_sanpham%', $product_cat, $permalink );
    return $permalink;
}
add_filter( 'post_type_link', 'devvn_cpt_sanpham_post_type_link', 10, 2 );

Như vậy đã chuyển %danhmuc_sanpham% sang slug của taxonomy rồi. Còn tiếp theo là rewrite để base danh mục giống với base của sản phẩm. Cũng copy code sau vào functions.php của theme

/*rewrite danh muc san pham*/
function devvn_cpt_sanpham_category_base_same_shop_base( $flash = false ){
    $terms = get_terms(array(
        'taxonomy' => 'danhmuc_sanpham',
        'hide_empty' => false,
    ));
    if ($terms && !is_wp_error($terms)) {
        $siteurl = esc_url(home_url('/'));
        foreach ($terms as $term) {
            $term_slug = $term->slug;
            $baseterm = str_replace($siteurl, '', get_term_link($term->term_id, 'danhmuc_sanpham'));
            add_rewrite_rule($baseterm . '?$','index.php?danhmuc_sanpham=' . $term_slug,'top');
            add_rewrite_rule($baseterm . 'page/([0-9]{1,})/?$', 'index.php?danhmuc_sanpham=' . $term_slug . '&paged=$matches[1]','top');
            add_rewrite_rule($baseterm . '(?:feed/)?(feed|rdf|rss|rss2|atom)/?$', 'index.php?danhmuc_sanpham=' . $term_slug . '&feed=$matches[1]','top');
        }
    }
    if ($flash == true)
        flush_rewrite_rules(false);
}
add_filter( 'init', 'devvn_cpt_sanpham_category_base_same_shop_base');

/*Sửa lỗi khi tạo mới taxomony bị 404*/
add_action( 'created_term', 'devvn_cpt_sanpham_cat_same_shop_edit_success', 10, 2 );
add_action( 'created_danhmuc_sanpham', 'devvn_cpt_sanpham_cat_same_shop_edit_success', 10, 2 );
function devvn_cpt_sanpham_cat_same_shop_edit_success( $term_id, $taxonomy ) {
    devvn_cpt_sanpham_category_base_same_shop_base(true);
}

Full code

Túm cái kết lại thì ta được đoạn code sau. Bỏ qua các bước trên bạn có thể copy toàn bộ đoạn code này vào functions.php của theme là được

/* Register Custom Post Type
Author: levantoan.com
*/
function san_pham_func() {
    $labels = array(
        'name'                  => _x( 'Sản phẩm', 'Post Type General Name', 'devvn' ),
        'singular_name'         => _x( 'Sản phẩm', 'Post Type Singular Name', 'devvn' ),
        'menu_name'             => __( 'Sản phẩm', 'devvn' ),
        'name_admin_bar'        => __( 'Sản phẩm', 'devvn' ),
        'archives'              => __( 'Item Archives', 'devvn' ),
        'attributes'            => __( 'Item Attributes', 'devvn' ),
        'parent_item_colon'     => __( 'Parent Item:', 'devvn' ),
        'all_items'             => __( 'All Items', 'devvn' ),
        'add_new_item'          => __( 'Add New Item', 'devvn' ),
        'add_new'               => __( 'Add New', 'devvn' ),
        'new_item'              => __( 'New Item', 'devvn' ),
        'edit_item'             => __( 'Edit Item', 'devvn' ),
        'update_item'           => __( 'Update Item', 'devvn' ),
        'view_item'             => __( 'View Item', 'devvn' ),
        'view_items'            => __( 'View Items', 'devvn' ),
        'search_items'          => __( 'Search Item', 'devvn' ),
        'not_found'             => __( 'Not found', 'devvn' ),
        'not_found_in_trash'    => __( 'Not found in Trash', 'devvn' ),
        'featured_image'        => __( 'Featured Image', 'devvn' ),
        'set_featured_image'    => __( 'Set featured image', 'devvn' ),
        'remove_featured_image' => __( 'Remove featured image', 'devvn' ),
        'use_featured_image'    => __( 'Use as featured image', 'devvn' ),
        'insert_into_item'      => __( 'Insert into item', 'devvn' ),
        'uploaded_to_this_item' => __( 'Uploaded to this item', 'devvn' ),
        'items_list'            => __( 'Items list', 'devvn' ),
        'items_list_navigation' => __( 'Items list navigation', 'devvn' ),
        'filter_items_list'     => __( 'Filter items list', 'devvn' ),
    );
    $rewrite = array(
        'slug'                  => _x('san-pham/%danhmuc_sanpham%','slug', 'devvn'), //Slug của trang chi tiết sản phẩm
        'with_front'            => true,
        'pages'                 => true,
        'feeds'                 => true,
    );
    $args = array(
        'label'                 => __( 'Sản phẩm', 'devvn' ),
        'description'           => __( 'Post Type Description', 'devvn' ),
        'labels'                => $labels,
        'supports'              => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments', ),
        'taxonomies'            => array( 'danhmuc_sanpham' ),
        'hierarchical'          => false,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 5,
        'menu_icon'             => 'dashicons-cart',
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => 'san-pham', //Đường dẫn của archive
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'rewrite'               => $rewrite,
        'capability_type'       => 'page',
    );
    register_post_type( 'san_pham', $args );
}
add_action( 'init', 'san_pham_func', 0 );
// Register Custom Taxonomy
function danhmuc_sanpham_func() {
    $labels = array(
        'name'                       => _x( 'Danh mục', 'Taxonomy General Name', 'devvn' ),
        'singular_name'              => _x( 'Danh mục', 'Taxonomy Singular Name', 'devvn' ),
        'menu_name'                  => __( 'Danh mục', 'devvn' ),
        'all_items'                  => __( 'All Items', 'devvn' ),
        'parent_item'                => __( 'Parent Item', 'devvn' ),
        'parent_item_colon'          => __( 'Parent Item:', 'devvn' ),
        'new_item_name'              => __( 'New Item Name', 'devvn' ),
        'add_new_item'               => __( 'Add New Item', 'devvn' ),
        'edit_item'                  => __( 'Edit Item', 'devvn' ),
        'update_item'                => __( 'Update Item', 'devvn' ),
        'view_item'                  => __( 'View Item', 'devvn' ),
        'separate_items_with_commas' => __( 'Separate items with commas', 'devvn' ),
        'add_or_remove_items'        => __( 'Add or remove items', 'devvn' ),
        'choose_from_most_used'      => __( 'Choose from the most used', 'devvn' ),
        'popular_items'              => __( 'Popular Items', 'devvn' ),
        'search_items'               => __( 'Search Items', 'devvn' ),
        'not_found'                  => __( 'Not Found', 'devvn' ),
        'no_terms'                   => __( 'No items', 'devvn' ),
        'items_list'                 => __( 'Items list', 'devvn' ),
        'items_list_navigation'      => __( 'Items list navigation', 'devvn' ),
    );
    $rewrite = array(
        'slug'                       => _x('san-pham','slug', 'devvn'),
        'with_front'                 => true,
        'hierarchical'               => true,
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
        'rewrite'                    => $rewrite,
    );
    register_taxonomy( 'danhmuc_sanpham', array( 'san_pham' ), $args );
}
add_action( 'init', 'danhmuc_sanpham_func', 0 );

function devvn_cpt_sanpham_post_type_link( $permalink, $post ) {
    // Abort if post is not a san_pham.
    if ( 'san_pham' !== $post->post_type ) {
        return $permalink;
    }
    // Abort early if the placeholder rewrite tag isn't in the generated URL.
    if ( false === strpos( $permalink, '%' ) ) {
        return $permalink;
    }
    // Get the custom taxonomy terms in use by this post.
    $terms = get_the_terms( $post->ID, 'danhmuc_sanpham' );
    if ( ! empty( $terms ) ) {
        if ( function_exists( 'wp_list_sort' ) ) {
            $terms = wp_list_sort( $terms, 'term_id', 'ASC' );
        } else {
            usort( $terms, '_usort_terms_by_ID' );
        }
        $category_object = apply_filters( 'devvn_cpt_sanpham_post_type_link_product_cat', $terms[0], $terms, $post );
        $category_object = get_term( $category_object, 'danhmuc_sanpham' );
        $product_cat     = $category_object->slug;
        if ( $category_object->parent ) {
            $ancestors = get_ancestors( $category_object->term_id, 'danhmuc_sanpham' );
            foreach ( $ancestors as $ancestor ) {
                $ancestor_object = get_term( $ancestor, 'danhmuc_sanpham' );
                $product_cat     = $ancestor_object->slug . '/' . $product_cat;
            }
        }
    } else {
        // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
        $product_cat = _x( 'khong-phan-loai', 'slug', 'devvn' );
    }
    $permalink = str_replace( '%danhmuc_sanpham%', $product_cat, $permalink );
    return $permalink;
}
add_filter( 'post_type_link', 'devvn_cpt_sanpham_post_type_link', 10, 2 );

/*rewrite danh muc san pham*/
function devvn_cpt_sanpham_category_base_same_shop_base( $flash = false ){
    $terms = get_terms(array(
        'taxonomy' => 'danhmuc_sanpham',
        'hide_empty' => false,
    ));
    if ($terms && !is_wp_error($terms)) {
        $siteurl = esc_url(home_url('/'));
        foreach ($terms as $term) {
            $term_slug = $term->slug;
            $baseterm = str_replace($siteurl, '', get_term_link($term->term_id, 'danhmuc_sanpham'));
            add_rewrite_rule($baseterm . '?$','index.php?danhmuc_sanpham=' . $term_slug,'top');
            add_rewrite_rule($baseterm . 'page/([0-9]{1,})/?$', 'index.php?danhmuc_sanpham=' . $term_slug . '&paged=$matches[1]','top');
            add_rewrite_rule($baseterm . '(?:feed/)?(feed|rdf|rss|rss2|atom)/?$', 'index.php?danhmuc_sanpham=' . $term_slug . '&feed=$matches[1]','top');
        }
    }
    if ($flash == true)
        flush_rewrite_rules(false);
}
add_filter( 'init', 'devvn_cpt_sanpham_category_base_same_shop_base');

/*Sửa lỗi khi tạo mới taxomony bị 404*/
add_action( 'created_term', 'devvn_cpt_sanpham_cat_same_shop_edit_success', 10, 2 );
add_action( 'created_danhmuc_sanpham', 'devvn_cpt_sanpham_cat_same_shop_edit_success', 10, 2 );
function devvn_cpt_sanpham_cat_same_shop_edit_success( $term_id, $taxonomy ) {
    devvn_cpt_sanpham_category_base_same_shop_base(true);
}

Chúc các bạn thành công^^

Tổng hợp thủ thuật và hướng dẫn tạo custom post type và custom taxonomy
5 (100%) 4 votes
  • Bình luận
Có thể bạn quan tâm
x