在 WooCommerce 中,我們經(jīng)常用到的數(shù)據(jù)列表為產(chǎn)品數(shù)據(jù)列表和訂單列表,在本深入教程中,我們將一起學(xué)習(xí)如何在 WooCommerce 儀表盤中管理訂單或產(chǎn)品列表中的數(shù)據(jù)列,這與在任何 WordPress 儀表盤中文章或頁面數(shù)據(jù)列表非常相似,但是有一些不同。
此外,我們還將看到不同的示例,例如,我們要在產(chǎn)品列表中添加一個「總銷售額」數(shù)據(jù)列,入下圖所示:
我們在 WooCommerce 儀表盤的產(chǎn)品列表中添加了一個可排序的 「總銷售額 」數(shù)據(jù)列。您可以直接跳轉(zhuǎn)到這個示例。
使用哪一個鉤子?
根據(jù)我們要創(chuàng)建自定義數(shù)據(jù)列的 WooCommerce 管理頁面(訂單列表、產(chǎn)品列表等)的不同,創(chuàng)建過程可能會略有不同,我們使用的鉤子也會有所不同?,F(xiàn)在,我們一起來看一下我們可以使用哪些鉤子。你也可以直接跳轉(zhuǎn)到示例。
除了管理數(shù)據(jù)列的鉤子,我們還需要用到一些關(guān)于的鉤子用于向列中填充數(shù)據(jù),現(xiàn)在我們將一步一步地逐一介紹。
添加數(shù)據(jù)列
首先,我們需要在數(shù)據(jù)列表中添加一個空列。下面是鉤子列表,可以幫助你完成這項(xiàng)工作。
| 鉤子 | 管理頁面 |
|---|---|
manage_edit-shop_order_columns | 在 CPT 數(shù)據(jù)類型的訂單中使用 |
manage_woocommerce_page_wc-orders_columns | 在 HPOS 數(shù)據(jù)類型的訂單中使用 |
manage_edit-product_columns | 產(chǎn)品 |
manage_edit-product_cat_columns | 產(chǎn)品類別 |
manage_edit-product_tag_columns | 產(chǎn)品標(biāo)簽 |
manage_users_columns | 用戶 |
我還想強(qiáng)調(diào)一下關(guān)于WooCommerce訂單的問題–很可能你使用的是默認(rèn)啟用了HPOS的最新版WooCommerce,這意味著WooCommerce訂單不再是自定義文章類型(CPT),因此manage_edit-shop_order_columns鉤子對你不起作用。別擔(dān)心,只需使用manage_woocommerce_page_wc-orders_columns來代替,并查看下面的示例,我們在其中為訂單創(chuàng)建了一個 WooCommerce 列,它既適用于基于 HPOS 的訂單,也適用于基于 CPT 的訂單。
現(xiàn)在讓我們來看一個簡單的示例。無論您使用哪種鉤子,代碼看起來都差不多–我們只需在$columns數(shù)組中再添加一項(xiàng),里面包含數(shù)據(jù)列 ID 和名稱,如下所示array( 'column_id' => 'column_title' ).
add_filter( 'manage_woocommerce_page_wc-orders_columns', 'wprs_new_column' );
function wprs_new_column( $columns ){
// 在這里添加新數(shù)據(jù)列
$columns[ 'wprs_new_column' ] = 'My new column';
// return the modified array
return $columns;
}
就這樣,數(shù)據(jù)列已經(jīng)添加好了。當(dāng)我們需要移除某個數(shù)據(jù)列時,這組鉤子也很有用。
為自定義數(shù)據(jù)列添加數(shù)據(jù)
完成了上一部,我們只是為數(shù)據(jù)列表添加了一個表頭,我們需要在其中顯示一些數(shù)據(jù),這樣才能在數(shù)據(jù)表格中顯示我們需要的內(nèi)容。
| 鉤子 | 管理頁面 |
|---|---|
manage_posts_custom_column | 產(chǎn)品和基于 CPT 的訂單 |
manage_woocommerce_page_wc-orders_custom_column | 基于 HPOS 的訂單 |
manage_product_cat_custom_column | 產(chǎn)品分類 |
manage_product_tag_custom_column | 產(chǎn)品標(biāo)簽 |
manage_users_custom_column | 用戶 |
這些鉤子的回調(diào)函數(shù)并不相同,例如,對于產(chǎn)品和訂單,我們會在函數(shù)內(nèi)打印結(jié)果,但對于用戶、標(biāo)簽和類別,則會返回結(jié)果。
用戶、產(chǎn)品分類和產(chǎn)品標(biāo)簽:
// 用于用戶
// add_filter( 'manage_users_custom_column', 'wprs_populate_columns', 10, 3 );
// 用于產(chǎn)品分類
// add_filter( 'manage_product_cat_custom_column', 'wprs_populate_columns', 10, 3 );
// 用于產(chǎn)品標(biāo)簽
add_filter( 'manage_product_tag_custom_column', 'wprs_populate_columns', 10, 3 );
function wprs_populate_columns( $output, $column_name, $object_id ) {
// $object_id is either the user ID or product category/tag ID
if( 'column ID here' === $column_name ) {
// you can use switch()
// do something and write the result into $output
$output .= 'some column data here';
}
return $output;
}
產(chǎn)品和基于 CPT 的訂單:
// products and legacy orders (CPT-based)
add_action( 'manage_posts_custom_column', 'wprs_populate_columns' );
function wprs_populate_columns( $column_name ){
global $post, $the_order;
if( 'column ID here' === $column_name ) {
// do something and print the result
echo 'some column data here';
}
}
基于 HPOS 的訂單:
add_action( 'manage_woocommerce_page_wc-orders_custom_column', 'wprs_populate_orders_column', 25, 2 );
function wprs_populate_orders_column( $column_name, $order ){ // WC_Order object is available as $order variable here
if( 'column ID here' === $column_name ) {
// do something and print the result
echo 'some column data here';
}
}
現(xiàn)在我們已經(jīng)完成了理論部分,如果需要查看示例,你可以直接進(jìn)入示例部分。
如何刪除某個數(shù)據(jù)列?
有時,管理頁面中的數(shù)據(jù)列會比較多,我們可能需要稍微清理一下,刪除一些不需要的數(shù)據(jù)列。當(dāng)然,我們也可以在 “屏幕選項(xiàng) “中隱藏它們–別忘了這一點(diǎn)。
下面是具體步驟:
- 決定要在哪個管理頁面移除列,然后轉(zhuǎn)到本教程的這一章,選擇一個合適的鉤子。
- 找出列 ID,為此可以在瀏覽器中 “檢查 “該列。
- 最后是代碼:
// replace 'manage_edit-product_columns' hook with the hook you need
add_filter( 'manage_edit-product_columns', 'wprs_remove_woo_columns' );
function wprs_remove_woo_columns( $columns ) {
unset( $columns[ 'column ID here' ] );
// for example unset( $columns[ 'product_cat' ] );
return $columns;
}
當(dāng)然,如果需要,我們也可以同時刪除多個列。
如何創(chuàng)建自定義數(shù)據(jù)列(示例)
例 1.在訂單列表中添加數(shù)據(jù)列
如果我們使用的是最新版本的 WooCommerce,或者在設(shè)置中打開了HPOS,那么manage_edit-shop_order_columns訂單數(shù)據(jù)列的鉤子就不再起作用了,我們通過下來的例子來學(xué)習(xí)一下怎么解決。
假如,我們需要在訂單狀態(tài)后面顯示已該訂單中包含的商品列表。

下面的代碼對傳統(tǒng)訂單和基于 HPOS 的訂單都非常有效:
// legacy – for CPT-based orders
add_filter( 'manage_edit-shop_order_columns', 'wprs_order_items_column' );
// for HPOS-based orders
add_filter( 'manage_woocommerce_page_wc-orders_columns', 'wprs_order_items_column' );
function wprs_order_items_column( $columns ) {
// let's add our column before "Total"
$columns = array_slice( $columns, 0, 4, true ) // 4 columns before
+ array( 'order_products' => 'Purchased products' ) // our column is going to be 5th
+ array_slice( $columns, 4, NULL, true );
return $columns;
}
// legacy – for CPT-based orders
add_action( 'manage_shop_order_posts_custom_column', 'wprs_populate_order_items_column', 25, 2 );
// for HPOS-based orders
add_action( 'manage_woocommerce_page_wc-orders_custom_column', 'misha_populate_order_items_column', 25, 2 );
function wprs_populate_order_items_column( $column_name, $order_or_order_id ) {
// legacy CPT-based order compatibility
$order = $order_or_order_id instanceof WC_Order ? $order_or_order_id : wc_get_order( $order_or_order_id );
if( 'order_products' === $column_name ) {
$items = $order->get_items();
if( ! is_wp_error( $items ) ) {
foreach( $items as $item ) {
echo $item[ 'quantity' ] .' × <a href="' . get_edit_post_link( $item[ 'product_id' ] ) . '">'. $item[ 'name' ] .'</a><br />';
// you can also use $order_item->variation_id parameter
// by the way, $item[ 'name' ] will display variation name too
}
}
}
}
請看第24行,我發(fā)現(xiàn)它非常有趣,因?yàn)殂^子manage_shop_order_posts_custom_column和manage_woocommerce_page_wc-orders_custom_column的第二個參數(shù)不同–它要么是訂單 ID,要么是相應(yīng)的訂單對象,我們使用$order_or_order_id instanceof WC_Order條件來檢查這一點(diǎn)。
manage_shop_order_posts_custom_column 就是鉤子名稱,不像有些鉤子一樣,需要把 custom_column 替換為數(shù)據(jù)列ID。例 2.為產(chǎn)品列表添加列
在這個示例中,我們需要為每個產(chǎn)品創(chuàng)建一個自定義字段total_sales,并在其中存儲總銷售額。這樣,我們就可以在pre_get_posts鉤子中使用該值并創(chuàng)建一個可排序的列!
下面就是我們要創(chuàng)建的結(jié)果:
正如您所看到的,”總銷售額 “列的標(biāo)題是可點(diǎn)擊的,這意味著這一列數(shù)據(jù)是可以排序的,下面是實(shí)現(xiàn)這個需求的代碼。
// 添加數(shù)據(jù)列
add_filter( 'manage_edit-product_columns', 'wprs_add_product_list_column' );
function wprs_add_product_list_column( $column_name ) {
// a little different way of adding new columns
return wp_parse_args(
array(
'total_sales' => 'Total Sales'
),
$column_name
);
}
// 顯示列數(shù)據(jù)
add_action( 'manage_posts_custom_column', 'wprs_populate_product_column', 25, 2 );
function wprs_populate_product_column( $column_name, $product_id ) {
if( 'total_sales' === $column_name ) {
echo get_post_meta( $product_id, 'total_sales', true );
}
}
// 使這一列數(shù)據(jù)可排序
add_filter( 'manage_edit-product_sortable_columns', 'wprs_sortable_column' );
function wprs_sortable_column( $sortable_columns ) {
return wp_parse_args(
array(
'total_sales' => 'by_total_sales' // column name => sortable arg
),
$sortable_columns
);
}
// 實(shí)現(xiàn)排序邏輯
add_action( 'pre_get_posts', function( $query ) {
if( ! is_admin() || empty( $_GET[ 'orderby' ] ) || empty( $_GET[ 'order' ] ) ) {
return $query;
}
if( 'by_total_sales' === $_GET[ 'orderby' ] ) {
$query->set( 'meta_key', 'total_sales' );
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'order', $_GET[ 'order' ] );
}
return $query;
} );
還有一個問題是,我們真的可以將產(chǎn)品元數(shù)據(jù)用作普通的文章元數(shù)據(jù)嗎?我的意思是使用get_post_meta()、pre_get_posts鉤子等。因?yàn)槿绻覀冊?jīng)在訂單中使用過這種方法,那么現(xiàn)在對于HPOS 訂單,我們的代碼就不再起作用了。我認(rèn)為–是的,我們現(xiàn)在可以這樣做,因?yàn)樵谖铱磥?,?CPT 用于 WooCommerce 產(chǎn)品正是它的目的所在。毫無疑問,也許有一天我們會面臨 “高性能產(chǎn)品存儲 “的問題,但我完全沒有聽說過。
示例 3.在用戶管理頁面添加包含 WooCommerce 賬單詳細(xì)信息的列
最后,讓我們在 “用戶”>”所有用戶“頁面上再添加一列。在這一欄中,我們將顯示賬單地址。就像這樣

下面是實(shí)現(xiàn)這一功能的代碼:
add_filter( 'manage_users_columns', 'wprs_billing_address_column' );
function wprs_billing_address_column( $columns ) {
return array_slice( $columns, 0, 3, true ) // 3 columns before
+ array( 'billing_address' => 'Billing Address' ) // our column is 4th
+ array_slice( $columns, 3, NULL, true );
}
add_filter( 'manage_users_custom_column', 'wprs_populate_address', 10, 3 );
function wprs_populate_address( $row_output, $column_name, $id ) {
if( 'billing_address' === $column_name ) {
$address = array();
if( $address_1 = get_user_meta( $id, 'billing_address_1', true ) ) {
$address[] = $address_1;
}
if( $address_2 = get_user_meta( $id, 'billing_address_2', true ) ) {
$address[] = $address_2;
}
if( $city = get_user_meta( $id, 'billing_city', true ) ) {
$address[] = $city;
}
if( $postcode = get_user_meta( $id, 'billing_postcode', true ) ) {
$address[] = $postcode;
}
if( $country = get_user_meta( $id, 'billing_country', true ) ) {
$address[] = $country;
}
$row_output = join( ', ', $address );
}
return $row_output;
}


