Woocommerce không còn nghi ngờ là một wordpress plugin tạo website thương mại điện tử vô cùng sức mạnh, nó hỗ trợ api gần như bạn làm được mọi thứ. Trong bài hôm nay tôi sẽ chỉ cho bạn làm sao thêm trường mới vào mọi loại sản phẩm của woocommerce.
Kết quả sau khi đọc xong bài viết này bạn có thể làm được như hình dưới đây:
Như bạn nhìn thấy trên hình, chúng ta sẽ thấy các fields mới được thêm vào trang chỉnh sửa sản phẩm. Và để làm điều này chúng ta sử dụng woocommerce API chèn vào functions.php trong folder theme của bạn.
Để bắt đầu bài tập đơn giản, mình sẽ thêm custom fields vào tab đầu tiên general tab, về sau các bạn sẽ tìm hiểu cách thêm fields vào tab khác có sẵn khác hoặc thêm tab mới.
WooCommerce Hooks
Cách xử lý cũng giống như bạn làm việc với custom fields trong wordpress với User, chúng ta sử dụng 2 hooks.
Thêm action cho hook woocommerce_product_options_general_product_data
, hàm liên kết với hook này sẽ hiển thị trường mới. Hook thứ hai, dùng để lưu giá trị của trường woocommerce_process_product_meta
.
// Thêm trường tùy chỉnh vào trang sản phẩm trong WooCommerce add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' ); // Lưu giá trị các trường tùy chỉnh khi sản phẩm được lưu add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
Thêm trường mới
Đoạn code trên, là 2 actions callback cho 2 hook có tác dụng tạo mới và hiển thị fields, cuối cùng lưu giá trị fields sử lý bởi hàm hook woocommerce_process_product_meta
. Đầu tiên, là hàm tạo fields có nội dung như sau.
function woo_add_custom_general_fields() { // Lấy đối tượng toàn cục của WooCommerce và bài viết hiện tại global $woocommerce, $post; // Tạo một div với lớp 'options_group' để chứa các trường tùy chỉnh echo '<div class="options_group">'; // Các trường tùy chỉnh sẽ được thêm vào ở đây... // Đóng div echo '</div>'; }
Để tạo các fields, chúng ta sử dụng tính năng xây dựng form fields có sẵn cung cấp bởi woocommerce api. Tất cả những api này bạn có thể tìm thấy trong file “WooCommerce/Admin/WritePanels/writepanels-init.php”
- woocommerce_wp_text_input()
- woocommerce_wp_textarea_input()
- woocommerce_wp_select()
- woocommerce_wp_checkbox()
- woocommerce_wp_hidden_input()
Một số dạng Field mẫu:
Text Field Type
Phổ biến nhất là text field, thêm code sau nếu bạn tạo field nhập văn bản như họ tên, SĐT..
// Tạo trường nhập văn bản cho sản phẩm woocommerce_wp_text_input( array( 'id' => '_text_field', // ID của trường 'label' => __( 'My Text Field', 'woocommerce' ), // Nhãn hiển thị cho trường 'placeholder' => 'http://', // Giá trị mặc định hiển thị trong trường 'desc_tip' => 'true', // Hiển thị mô tả trợ giúp (tooltip) 'description' => __( 'Enter the custom value here.', 'woocommerce' ) // Mô tả giúp người dùng hiểu ý nghĩa của trường ) );
Ví dụ: thêm text field vào nội dung tab general.
function woo_add_custom_general_fields() { global $woocommerce, $post; // Mở div chứa các trường tùy chỉnh echo '<div class="options_group">'; // Trường nhập văn bản woocommerce_wp_text_input( array( 'id' => '_text_field', // ID của trường 'label' => __( 'My Text Field', 'woocommerce' ), // Nhãn của trường 'placeholder' => 'http://', // Giá trị mặc định trong trường 'desc_tip' => 'true', // Bật mô tả trợ giúp 'description' => __( 'Enter the custom value here.', 'woocommerce' ) // Mô tả trường ) ); // Đóng div echo '</div>'; }
Lưu ý: tham số 'desc_tip'=>'true'
dùng hiển thị tooltip thay vì hiển thị mô tả ra ngoài bên dưới field, sẽ có biểu tượng hướng dẫn cách dùng cho field đó thông qua tooltip.
description
là nội dung của tooltip, nếu desc_tip=true hoặc mặc định desc_tip=false là mô tả field thông thường. Tính năng tooltip có thể áp dụng cho mọi kiểu field.
Number Field Type
Để tạo Number Field, bạn sẽ dùng đến code này:
// Số trường nhập liệu woocommerce_wp_text_input( array( 'id' => '_number_field', // ID của trường 'label' => __( 'My Number Field', 'woocommerce' ), // Nhãn của trường 'placeholder' => '', // Giá trị mặc định trong trường 'description' => __( 'Enter the custom value here.', 'woocommerce' ), // Mô tả trường 'type' => 'number', // Loại trường là số 'custom_attributes' => array( 'step' => 'any', // Cho phép nhập số thập phân 'min' => '0' // Giá trị tối thiểu là 0 ) ) );
Number Field và Input text sử dụng chung thẻ < input
, nên thiết kế chọn vào hàm woocommerce_wp_text_input
chỉ khác tham số ‘type’, với kiểu input muốn tạo. Loại field dạng nhập số thì thiết lập type=>’number’. Bạn có thể thiết lập các thuộc tính khác cho kiểu field này ví dụ bước nhảy số (step), giá trị min, giá trị max.
Ở code trên, mặc định step=1 và thiết lập số nhỏ nhất bắt đầu từ 0. Lưu ý: min, max là số tự nhiên.
Textarea Field Type
Tạo Textarea bằng code dưới đây:
// Trường Textarea woocommerce_wp_textarea_input( array( 'id' => '_textarea', // ID của trường 'label' => __( 'My Textarea', 'woocommerce' ), // Nhãn của trường 'placeholder' => '', // Giá trị mặc định trong trường 'description' => __( 'Enter the custom value here.', 'woocommerce' ) // Mô tả trường ) );
Cũng đơn giản như input text với hàm woocommerce_wp_text_input.
Bạn có thể tùy biến hiển thị form field, bằng cách thêm thành phần HTML hoặc sửa thuộc tính class..nếu không muốn dùng hàm woocommerce_wp_textarea_input bạn sẽ cần định nghĩa hàm tạo textarea mới. Ví dụ:
function _woocommerce_wp_textarea_input( $field ) { global $thepostid, $post; // Xác định post ID nếu chưa có if ( ! $thepostid ) { $thepostid = $post->ID; } // Thiết lập giá trị mặc định nếu chưa có if ( ! isset( $field['placeholder'] ) ) { $field['placeholder'] = ''; } if ( ! isset( $field['class'] ) ) { $field['class'] = 'short'; } if ( ! isset( $field['value'] ) ) { $field['value'] = get_post_meta( $thepostid, $field['id'], true ); } // Hiển thị trường textarea echo '<p class="form-field ' . $field['id'] . '_field">'; echo '<label style="display:block;" for="' . $field['id'] . '">' . $field['label'] . '</label>'; echo '<textarea class="' . $field['class'] . '" name="' . $field['id'] . '" id="' . $field['id'] . '" placeholder="' . $field['placeholder'] . '" rows="2" cols="20"'; // Thêm style nếu có if ( isset( $field['style'] ) ) { echo ' style="' . $field['style'] . '"'; } // Giá trị cho textarea echo '>' . esc_textarea( $field['value'] ) . '</textarea>'; // Hiển thị mô tả nếu có if ( isset( $field['description'] ) && $field['description'] ) { echo '<span class="description">' . $field['description'] . '</span>'; } echo '</p>'; }
Dropdown Select Field Type
Dropdown field thì phức tạp hơn xíu, bạn phải nhập dữ liệu options.
// Select Field woocommerce_wp_select( array( 'id' => '_select', // ID của trường 'label' => __( 'My Select Field', 'woocommerce' ), // Nhãn của trường 'options' => array( // Các lựa chọn trong trường select 'one' => __( 'Option 1', 'woocommerce' ), 'two' => __( 'Option 2', 'woocommerce' ), 'three' => __( 'Option 3', 'woocommerce' ), ), ) );
Nhập danh sách lựa chọn bởi mảng dữ liệu vào tham số ‘options’.
Checkbox Field Type
Code sau đây sử dụng tạo field checkbox.
// Checkbox Field woocommerce_wp_checkbox( array( 'id' => '_checkbox', // ID của trường checkbox 'wrapper_class' => 'show_if_simple', // Lớp CSS cho wrapper (để hiển thị checkbox khi sản phẩm là đơn giản) 'label' => __( 'My Checkbox Field', 'woocommerce' ), // Nhãn cho checkbox 'description' => __( 'Check me!', 'woocommerce' ), // Mô tả cho checkbox ) );
Hidden Field Type
Với hidden field thì khá đơn giản chỉ cần id và value.
// Hidden Field woocommerce_wp_hidden_input( array( 'id' => '_hidden_field', // ID của trường hidden 'value' => 'hidden_value' // Giá trị mặc định cho trường hidden ) );
Products Select Field Type
Ngoài, những field thông dụng của form, bạn có thể tạo các fields đặc trưng riêng cho woocommerce. Đoạn code sau đây sẽ tạo trường lựa chọn sản phẩm.
// Product Select ?> <p class="form-field product_field_type"> <label for="product_field_type"> <?php _e( 'Product Select', 'woocommerce' ); ?> </label> <select id="product_field_type" name="product_field_type[]" class="ajax_chosen_select_products" multiple="multiple" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>"> <?php // Lấy các giá trị của trường meta 'product_field_type_ids' từ bài viết $product_field_type_ids = get_post_meta( $post->ID, '_product_field_type_ids', true ); // Nếu có các giá trị, biến đổi thành một mảng các ID sản phẩm $product_ids = ! empty( $product_field_type_ids ) ? array_map( 'absint', $product_field_type_ids ) : null; // Nếu có các ID sản phẩm, lặp qua và hiển thị từng sản phẩm trong danh sách if ( $product_ids ) { foreach ( $product_ids as $product_id ) { // Lấy thông tin sản phẩm $product = get_product( $product_id ); // Lấy tên sản phẩm $product_name = woocommerce_get_formatted_product_name( $product ); // Hiển thị sản phẩm dưới dạng option echo '<option value="' . esc_attr( $product_id ) . '" selected="selected">' . esc_html( $product_name ) . '</option>'; } } ?> </select> <!-- Tooltip giúp hiển thị thông tin trợ giúp --> <img decoding="async" class="help_tip" data-tip='<?php _e( 'Your description here', 'woocommerce' ) ?>' src="<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /> </p> <?php
Custom Field Type
Bên cạnh đó,bạn còn có thể tạo custom field tự định nghĩa riêng, nhờ vào cách lưu đa dạng dữ liệu trong wordpress bởi hàm update_post_meta
. Với post meta wordpress hỗ trợ lưu kiểu chuỗi, số, boolean, thậm trí mảng. Trường hợp lưu giá trị là đối tượng vd mảng wordpress sử dụng hàm php serialize
dùng để mã hóa đối tượng và giải mã ngược lại bởi hàm unserialize
.
Ví dụ sau đây, tôi tạo 2 Number fields lưu giá trị của chúng vào mảng chung với danh nghĩa là một field.
// Custom field Type ?> <p class="form-field custom_field_type"> <label for="custom_field_type"> <?php echo __( 'Custom Field Type', 'woocommerce' ); ?> </label> <span class="wrap"> <?php // Lấy giá trị của trường custom_field_type từ meta dữ liệu của bài viết $custom_field_type = get_post_meta( $post->ID, '_custom_field_type', true ); ?> <!-- Trường nhập số Field One --> <input placeholder="<?php _e( 'Field One', 'woocommerce' ); ?>" type="number" name="_field_one" value="<?php echo $custom_field_type[0]; ?>" step="any" min="0" style="width: 80px;" /> <!-- Trường nhập số Field Two --> <input placeholder="<?php _e( 'Field Two', 'woocommerce' ); ?>" type="number" name="_field_two" value="<?php echo $custom_field_type[1]; ?>" step="any" min="0" style="width: 80px;" /> </span> <!-- Mô tả cho trường --> <span class="description"> <?php _e( 'Place your own description here!', 'woocommerce' ); ?> </span> </p> <?php
Bạn có thể làm mọi thứ trong việc thiết kế custom field, như thêm CSS làm đẹp field.
Lưu giá trị Fields
Chúng ta đã tạo xong fields và hiển thị trong tab general, tiếp đến công đoạn lưu giá trị fields mới này cho sản phẩm hiện tại đang ở cửa sổ chỉnh sửa thông tin sản phẩm. Giá trị của fields sẽ lưu lại khi nhấn vào nút update hoặc Publish. Như trước đó bạn biết, chúng ta sẽ sử dụng hàm woo_add_custom_general_fields_save liên kết vào hook woocommerce_process_product_meta. Nguyên lý rất đơn giản, hàm sẽ kiểm tra sự tồn tại giá trị của field trong dữ liệu form POST, nếu field có giá trị chúng ta sẽ tạo post meta sử dụng update_post_meta()
. Chú ý để lưu dữ liệu an toàn, chúng ta sử dụng thêm esc_attr()
và esc_html()
Đoạn code sau đây là ví dụ cách lưu mỗi kiểu field.
<?php function woo_add_custom_general_fields_save( $post_id ) { // Text Field $woocommerce_text_field = $_POST['_text_field']; if( !empty( $woocommerce_text_field ) ) { update_post_meta( $post_id, '_text_field', esc_attr( $woocommerce_text_field ) ); } // Number Field $woocommerce_number_field = $_POST['_number_field']; if( !empty( $woocommerce_number_field ) ) { update_post_meta( $post_id, '_number_field', esc_attr( $woocommerce_number_field ) ); } // Textarea $woocommerce_textarea = $_POST['_textarea']; if( !empty( $woocommerce_textarea ) ) { update_post_meta( $post_id, '_textarea', esc_html( $woocommerce_textarea ) ); } // Select $woocommerce_select = $_POST['_select']; if( !empty( $woocommerce_select ) ) { update_post_meta( $post_id, '_select', esc_attr( $woocommerce_select ) ); } // Checkbox $woocommerce_checkbox = isset( $_POST['_checkbox'] ) ? 'yes' : 'no'; update_post_meta( $post_id, '_checkbox', $woocommerce_checkbox ); // Custom Field $custom_field_type = array( esc_attr( $_POST['_field_one'] ), esc_attr( $_POST['_field_two'] ) ); update_post_meta( $post_id, '_custom_field_type', $custom_field_type ); // Hidden Field $woocommerce_hidden_field = $_POST['_hidden_field']; if( !empty( $woocommerce_hidden_field ) ) { update_post_meta( $post_id, '_hidden_field', esc_attr( $woocommerce_hidden_field ) ); } // Product Field Type $product_field_type = $_POST['product_field_type']; update_post_meta( $post_id, '_product_field_type_ids', $product_field_type ); } ?>
Kết quả:
Hiển thị dữ liệu custom field cho sản phẩm
Chúng ta vừa hoàn tất tạo fields và lưu giá trị fields cho mỗi sản phẩm. Những dữ liệu này sẽ được hiển thị trên frontend trong woocommerce custom template của bạn.
Để lấy thông tin custom field, chúng ta sử dụng hàm get_post_meta()
. Xác định product ID và tên field cần lấy.
<?php // Hiển thị giá trị trường tùy chỉnh từ post meta echo get_post_meta( $post->ID, 'my-field-slug', true ); // Cách khác để lấy giá trị trường tùy chỉnh bằng get_the_ID() echo get_post_meta( get_the_ID(), 'my-field-slug', true ); ?>
Tham số thứ là giá trị thuộc tính ‘id’ của tham số mảng khởi tạo field bởi các hàm tạo fields trong woocomerce. VD: woocommerce_wp_checkbox, woocommerce_wp_select, woocommerce_wp_text_input..
Bạn có thể override template woocommerce/templates/content-single-product vào theme. Chèn thêm dòng này vào sau đoạn thực thi action do_action( 'woocommerce_single_product_summary' );
echo get_post_meta( get_the_ID(), '_text_field', true );
View trang sản phẩm sẽ thấy ngay kết quả, hiển thị thêm chuỗi là giá trị của field ‘_text_field’.
Tạo tabs mới
Cuối cùng code snippet sau đây giúp bạn tạo thêm tabs sản phẩm:
// Thêm tab tùy chỉnh vào trang chỉnh sửa sản phẩm WooCommerce add_action( 'woocommerce_product_write_panel_tabs', 'woo_add_custom_admin_product_tab' ); // Hàm để thêm tab tùy chỉnh function woo_add_custom_admin_product_tab() { ?> <li class="custom_tab"> <a href="#custom_tab_data"> <?php _e('My Custom Tab', 'woocommerce'); ?> </a> </li> <?php }
Kết quả:
Tab có biểu tượng mặc định như hình trên, tuy nhiên bạn có thể trang trí tab bằng cách thêm CSS, ví dụ thay icon cho tab.
Nếu nếu muốn thêm fields vào trong những tab khác ngoài general tab, bạn chỉ việc sửa lại tên hook của hàm liên kết woo_add_custom_general_fields cho đúng tab bạn cần. Ví dụ: sử dụng hook woocommerce_product_options_shipping để thêm fields vào shipping tab. Mọi thông tin hooks xem tại woocommerce/admin/post-types/writepanels/writepanel-product_data.php
Thêm fields vào custom tab
Hiện tại tab chưa có fields nào, chúng ta sử dụng hook woocommerce_product_write_panels
để hiển thị các fields cho các custom tab mới thêm. Thêm hàm liên kết vào hook woocommerce_product_write_panels
, mọi fields được phân phối vào các custom tabs chúng ta sẽ sử lý tại callback này. Với mỗi tab xác định bởi một ID bao bởi thẻ DIV.
/** * Adds the panel to the Product Data postbox in the product interface */ public function product_write_panel() { global $post; // the product // Kiểm tra phiên bản WooCommerce if ( defined( 'WOOCOMMERCE_VERSION' ) && version_compare( WOOCOMMERCE_VERSION, '2.1', '<' ) ) { ?> <style type="text/css"> #woocommerce-product-data ul.product_data_tabs li.product_tabs_lite_tab a { padding: 5px 5px 5px 28px; background-repeat: no-repeat; background-position: 5px 7px; } </style> <?php } // Lấy dữ liệu tab tùy chỉnh từ cơ sở dữ liệu $tab_data = maybe_unserialize( get_post_meta( $post->ID, 'frs_woo_product_tabs', true ) ); // Nếu không có dữ liệu, khởi tạo giá trị mặc định if ( empty( $tab_data ) ) { $tab_data[] = array( 'title' => '', 'content' => '' ); } // Duyệt qua từng tab và hiển thị thông tin foreach ( $tab_data as $tab ) { echo '<div id="custom_tab_data" class="panel wc-metaboxes-wrapper woocommerce_options_panel">'; // Hiển thị trường nhập tiêu đề tab woocommerce_wp_text_input( array( 'id' => '_wc_custom_product_tabs_lite_tab_title', 'label' => __( 'Tab Title', self::TEXT_DOMAIN ), 'description' => __( 'Required for tab to be visible', self::TEXT_DOMAIN ), 'value' => $tab['title'] ) ); // Hiển thị trường nhập nội dung tab woocommerce_wp_textarea_input( array( 'id' => '_wc_custom_product_tabs_lite_tab_content', 'label' => __( 'Content', self::TEXT_DOMAIN ), 'placeholder' => __( 'HTML and text to display.', self::TEXT_DOMAIN ), 'value' => $tab['content'], 'style' => 'width:70%;height:21.5em;' ) ); echo '</div>'; } }
Lưu giá trị fields trên tab
Nếu bạn tạo nhiều tab, chúng ta nên ghi nhớ tên fields theo tab và có thể lưu toàn bộ dữ liệu của fields phân loại vào các custom tabs vào mảng 2 chiều và update_post_meta cho dễ quản lý.
// Hàm tạo tab ID từ tiêu đề tab public function generate_tabId( $tab_title ) { $tab_id = ''; // Kiểm tra nếu tiêu đề tab không rỗng if ( $tab_title ) { // Kiểm tra xem tiêu đề có chứa ký tự UTF-8 không if ( strlen( $tab_title ) != strlen( utf8_encode( $tab_title ) ) ) { // Nếu chứa ký tự UTF-8, đặt tab_id mặc định $tab_id = "tab-custom"; } else { // Chuyển tiêu đề tab thành ID bằng cách chuyển thành chữ thường $tab_id = strtolower( $tab_title ); // Loại bỏ ký tự không phải chữ cái, số, dấu gạch dưới hoặc dấu cách $tab_id = preg_replace( "/[^a-z0-9_\s]/", '', $tab_id ); // Thay thế tất cả dấu gạch dưới bằng dấu cách $tab_id = preg_replace( "/_+/", ' ', $tab_id ); // Thay thế tất cả dấu cách liên tiếp bằng dấu gạch nối $tab_id = preg_replace( "/\s+/", '-', $tab_id ); // Tiền tố với 'tab-' $tab_id = 'tab-' . $tab_id; } } return $tab_id; } // Hàm lưu dữ liệu tab vào cơ sở dữ liệu public function product_save_data( $post_id, $post ) { // Lấy tiêu đề và nội dung của các tab từ form $tab1_title = stripslashes( $_POST['_wc_custom_product_tabs_1_title'] ); $tab1_content = stripslashes( $_POST['_wc_custom_product_tabs_1_content'] ); $tab2_title = stripslashes( $_POST['_wc_custom_product_tabs_2_title'] ); $tab2_content = stripslashes( $_POST['_wc_custom_product_tabs_2_content'] ); // Lưu dữ liệu các tab vào cơ sở dữ liệu $tab_data['tab1'] = array( 'title' => $tab1_title, 'id' => $this->generate_tabId( $tab1_title ), 'content' => $tab1_content ); $tab_data['tab2'] = array( 'title' => $tab2_title, 'id' => $this->generate_tabId( $tab2_title ), 'content' => $tab2_content ); // Cập nhật dữ liệu vào post meta update_post_meta( $post_id, 'frs_woo_product_tabs', $tab_data ); }
Sửa lại nội dung các tabs sử dụng với nhiều fields khác nhau.
foreach ( $tab_data as $tab_id => $tab ) { // Xử lý hiển thị tab, tránh lặp lại mã $tab_num = substr( $tab_id, -1 ); // Lấy số từ tên tab (tab1 -> 1, tab2 -> 2) // Hiển thị nội dung cho mỗi tab echo '<div id="woocommerce_product_tabs_' . $tab_num . '" class="panel wc-metaboxes-wrapper woocommerce_options_panel">'; // Tiêu đề tab woocommerce_wp_text_input( array( 'id' => '_wc_custom_product_tabs_' . $tab_num . '_title', 'label' => __( 'Tab Title', self::TEXT_DOMAIN ), 'description' => __( 'Required for tab to be visible', self::TEXT_DOMAIN ), 'value' => $tab['title'] )); // Nội dung tab $this->woocommerce_wp_textarea_input( array( 'id' => '_wc_custom_product_tabs_' . $tab_num . '_content', 'label' => __( 'Content', self::TEXT_DOMAIN ), 'placeholder' => __( 'HTML and text to display.', self::TEXT_DOMAIN ), 'value' => $tab['content'], 'style' => 'width:70%;height:21.5em;' )); echo '</div>'; }
Cách xử lý khác là lưu tên tab vào trong mảng chứa dữ liệu field.
// Tạo mảng chứa dữ liệu của các tab $tabs = array( array( 'tab' => 'tab1', 'title' => $tab1_title, 'id' => $this->generate_tabId($tab1_title), 'content' => $tab1_content ), array( 'tab' => 'tab2', 'title' => $tab2_title, 'id' => $this->generate_tabId($tab2_title), 'content' => $tab2_content ) ); // Cập nhật dữ liệu vào post_meta update_post_meta($post_id, 'frs_woo_product_tabs', $tabs);
Lấy fields ra tabs.
foreach ( $tab_data as $tab ) { // Xác định ID và các trường cho mỗi tab $tab_id = $tab['tab']; $tab_title = $tab['title']; $tab_content = $tab['content']; // Hiển thị tab tương ứng echo '<div id="woocommerce_product_tabs_' . esc_attr( substr( $tab_id, -1 ) ) . '" class="panel wc-metaboxes-wrapper woocommerce_options_panel">'; // Hiển thị tiêu đề của tab woocommerce_wp_text_input( array( 'id' => '_wc_custom_product_tabs_' . esc_attr( substr( $tab_id, -1 ) ) . '_title', 'label' => __( 'Tab Title', self::TEXT_DOMAIN ), 'description' => __( 'Required for tab to be visible', self::TEXT_DOMAIN ), 'value' => $tab_title )); // Hiển thị nội dung của tab $this->woocommerce_wp_textarea_input( array( 'id' => '_wc_custom_product_tabs_' . esc_attr( substr( $tab_id, -1 ) ) . '_content', 'label' => __( 'Content', self::TEXT_DOMAIN ), 'placeholder' => __( 'HTML and text to display.', self::TEXT_DOMAIN ), 'value' => $tab_content, 'style' => 'width:70%;height:21.5em;' )); echo '</div>'; }
Thêm custom tab vào single product tabs
Để thêm tab mới vào danh sách tabs của sản phẩm bao gồm Description, Reviews, Related, chúng ta khai báo thêm dữ liệu tabs vào filter woocommerce_product_tabs
. Các Tabs nội dung của sản phẩm sẽ được hiển thị trong trang sản phẩm chi tiết bởi action hook woocommerce_after_single_product_summary
. Mặc định có 2 hàm liên kết với hook này, một hàm giúp hiển thị product tabs và hàm thứ hai hiển thị các sản phẩm liên quan. Lời gọi nội dung Tabs chứa trong file content-single-product.php
<?php /** * woocommerce_after_single_product_summary hook * * @hooked woocommerce_output_product_data_tabs - 10 * @hooked woocommerce_output_related_products - 20 */ do_action( 'woocommerce_after_single_product_summary' ); ?>
Mỗi tab có cấu trúc như sau:
$tabs[ $tab['id'] ] = array( 'title' => __( $tab['title'], self::TEXT_DOMAIN ), 'priority' => 25, 'callback' => array( $this, 'custom_product_tabs_panel_content' ), 'content1' => $tab['content'], // custom field );
Trong đó:
Tiêu đề tab lấy nội dung của thuộc tính “title”, có thể thêm tab vào cuối danh sách tabs hoặc xen giữa ở bất kỳ vị trí nào bởi thuộc tính ‘priority’. Nội dung của tabs thực thi bởi hàm liên kết “callback”.
Thêm đoạn code sau vào file functions.php hoặc tạo plugin mới như dưới đây.
// Frontend code: Add custom product tabs add_filter( 'woocommerce_product_tabs', array( $this, 'add_custom_product_tabs' ) ); /** * Add custom product tabs * * @param array $tabs Array representing the product tabs * @return array Modified array of product tabs * @since 1.2.0 */ public function add_custom_product_tabs( $tabs ) { global $product; // Check if the product has custom tabs if ( $this->product_has_custom_tabs( $product ) ) { // Loop through the custom tab data foreach ( $this->tab_data as $tab ) { // Add the custom tab to the product tabs array $tabs[ $tab['id'] ] = array( 'title' => __( $tab['title'], self::TEXT_DOMAIN ), // Tab title 'priority' => 25, // Tab priority 'callback' => array( $this, 'custom_product_tabs_panel_content' ), // Callback function to display content 'content' => $tab['content'], // Custom content for the tab ); } } // Return the modified tabs array return $tabs; }
Ngoài ra, có thể chứa thêm dữ liệu khác cho nội dung tab vào biến $tabs. Ví dụ trên, dữ liệu content
sẽ được khai thác trong hàm custom_product_tabs_panel_content.
/** * Render the custom product tab panel content for the given $tab * * $tab structure: * Array( * 'title' => (string) Tab title, * 'priority' => (int) Tab priority, * 'callback' => (mixed) callback function, * 'id' => (int) tab post identifier, * 'content' => (string) tab content, * ) * * @param string $key Tab key * @param array $tab Tab data */ public function custom_product_tabs_panel_content( $key, $tab ) { // Allow shortcodes to function in the content $content = apply_filters( 'the_content', $tab['content'] ); // Fix for incorrectly encoded content (HTML entities) $content = str_replace( ']]>', ']]>', $content ); // Display the tab title (wrapped in an <h2>) echo apply_filters( 'woocommerce_custom_product_tabs_lite_heading', '<h2>' . esc_html( $tab['title'] ) . '</h2>', $tab ); // Display the tab content (after applying necessary filters) echo apply_filters( 'woocommerce_custom_product_tabs_lite_content', $content, $tab ); }
Ở đây mình tạo thêm filter woocommerce_custom_product_tabs_lite_content liên kết với hàm do_shortcode, cho phép thực thi shortcode trong nội dung tab.
Thêm dòng này nếu muốn sử dụng shortcode trong custom product tab ở trên.
// Allow the use of shortcodes within the tab content add_filter( 'woocommerce_custom_product_tabs_lite_content', 'do_shortcode' );
Plugin tạo WooCommerce Tabs
Nếu không rành về code, bạn có thể tạo custom tab dễ dàng với plugin WooCommerce Custom Product Tabs Lite.