我們首先先要決定我們的產品列表,及需要改變的頁面,這次舉的範例是我的公司的一些產品列表,而我們先預先設定我們產品的列表:
在一班的顯示頁面下,會先選擇到standard product,進到第二頁則會顯示著兩個single與double這兩項產品,並且還有第二個子目錄,直到點擊進入第二個子目錄,才會把所有商品顯示,而我們的目標是在點入standard product後,以巢狀的方式顯示,並且細載所屬的子項目,來看我們下方的規劃,可以在第二層的目錄就看到更多,而你可能有更複雜的更多的子目錄層層堆疊,我們就不考慮這些使考慮有兩層的使用:
一開始我是朝著回傳的action做開發,但如果你有套主題,你得小心你的archieve-product.php是否有被覆蓋掉,如果沒有的話,我們可以直接朝著對檔案做修改,而如何修改的介紹可以參考這個Template structure & Overriding templates via a theme他的架構時如何組成的,而我們直接改寫woocommerce_locate_template
的hook,讓wooCommerce優先執行我們外掛裡頭的模組,改寫後的順序為以下流程:
plugin/template/woocommerce -> theme/yourtheme/woocommerce.php -> theme/yourtheme/woocommerce/ -> 預設模板
此段程式碼節錄於下方網站程式碼,當時看到的時候還不感覺有什麼特別,直到開始寫外掛後才發現extension是一個多麼好用的延伸,而我們就把設定的模板放在plugin/template/woocommerce
之中,以便於我們做後續的維護。
add_filter( 'woocommerce_locate_template', 'woo_adon_plugin_template', 1, 3 );
function woo_adon_plugin_template( $template, $template_name, $template_path ) {
global $woocommerce;
$_template = $template;
if ( ! $template_path )
$template_path = $woocommerce->template_url;
$plugin_path = untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/template/woocommerce/';
// Look within passed path within the theme - this is priority
$template = locate_template(
array(
$template_path . $template_name,
$template_name
)
);
if( ! $template && file_exists( $plugin_path . $template_name ) )
$template = $plugin_path . $template_name;
if ( ! $template )
$template = $_template;
return $template;
}
content-product_cat.php 顯示子目錄的content的template,大部分在產品之中顯示是否要將所有顯示出來,就會先查到woocommerce_content
,而他是把所有項目藉由你的設定給印出來,但不少主題開發者為了省時間是都使用這個來做,而我們今天要使用的,就是將這個content給取代掉,取而代之做出新的loop,而這一段程式碼,主要都是product-archieve.php中的程式碼,而我們在開始之前,我們得先將category的設定更正,設定成defaults,而在customize->woocommerce之中,設定products shop顯示只有product。
而我們主要從woocommerce_product_loop_start
到woocommerce_product_loop_end
改寫新的程式碼,以便於其他目錄可以顯示,而目前我們是針對網址不是product-category而是shop,在母頁面會有一定的影響,而這些調整則是在明天一並做處理,而在加入找post與conditional的邏輯偵測,則是放在woocommerce_before_shop_loop
之後。
<?php
// woocommerce_content();
if ( is_singular( 'product' ) ) {
while ( have_posts() ) :
the_post();
wc_get_template_part( 'content', 'single-product' );
endwhile;
我們開頭先對於如果是單一產品的品項,做不同的設定,並且直接做輸出,而接下來我們要加入原本的程式碼,而假如我們的subcategory這一些抓取有問題,我們則加入預設的程式碼,而在開頭的前段,我們使用term_id
來取得當下的目錄號碼,而可以看到product_categories中有非常多的訊息可以顯示。
if ( woocommerce_product_loop() ) {
do_action( 'woocommerce_before_shop_loop' );
$term = get_queried_object();
$parent_id = $term->term_id;
$product_categories = get_categories(
array(
'child_of' => $parent_id,
'taxonomy' => 'product_cat',
'orderby' => 'name',
'order' => 'ASC'
);
var_dump($product_categories);
if(empty($product_categories)) {
woocommerce_product_loop_start();
if ( wc_get_loop_prop( 'total' ) ) {
while ( have_posts() ) {
the_post();
/**
* Hook: woocommerce_shop_loop.
*
* @hooked WC_Structured_Data::generate_product_data() - 10
*/
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
}
woocommerce_product_loop_end();
}
而我們下一步,在woocommerce原生之中,wp_query後的have_posts與the_post()來做loop結束的資料,而為何他能夠直接使用have_posts其實我還是不清楚,還沒找到相對的程式碼,而之後我們將開始我們對於product_categories
的輸出。
$product_categories = sort_product($product_categories);
foreach ($product_categories as $product_category) {
echo '<h2>'.$product_category->name.'</h2>'.$product_category->term_id;
woocommerce_product_loop_start();
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $product_category->term_id,
'include_children' => false
)
),
);
$new_cat = new WP_Query( $args );
while ( $new_cat->have_posts() ) : $new_cat->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
wp_reset_postdata();
woocommerce_product_loop_end();
printf('<div class="content-seperator"></div>');
}
而我們最後可以看見會使像我下面的介面依樣的結果,而sort_product
需要自己撰寫,因為不管是get_categories
或是改用wp_get_object_terms
,他並不支援以自己的函式做排序處理,而我們的排序又不單純只是照著名字或者數字排序大小,你在這邊可以編輯好你需要的顯示排序,而之後我們進到loop,對每一個目錄做顯示,為了呼應woocommerce的原生寫法,但如果想要自己做喜歡的卡片來擺放,也是可以自己category後的產品中,一個一個抓product title這些來做設定,WP_Query中的參數可以參考get_terms
中是如取得的。
最後,完成的畫面就會是巢狀的,明日我們將接續著第二個頁面,將這個顯示到正常的顯示,在product-category中,仍然會有顯示只有subcat的問題,而準備將子目錄加上母目錄的顯示,讓顯示更加完整,明天一並將程式碼改好附上,就可以接著做多重roles的設計!
WooCommerce - Nested Category/Subcategory Layout, FIXED: show subcategory content
How to Override WooCommerce Templates in your Plugin
WordPress Plugin Boilerplate
DX Plugin Base
woocommrece content
have_posts