[英]Show Out of stock products at the end in Woocommerce
Is it possible to show out of stock products at the end of a category or page in wordpress?是否可以在 wordpress 中的类别或页面末尾显示缺货产品?
So the customer first see the products that are available and after that the products that are out of stock.因此,客户首先看到可用的产品,然后看到缺货的产品。
This is the same as Viktor & Bogdan's answer, but without the extra Class code.这与 Viktor & Bogdan 的答案相同,但没有额外的 Class 代码。
It uses the post_clause
filter to modify the product query.它使用post_clause
过滤器来修改产品查询。 We JOIN
the wp_postmeta table to the query and prepend an orderby _stock_status
clause to the existing query.我们JOIN
的wp_postmeta表来查询和前面加上一个orderby _stock_status
子句现有查询。 This way any other orderby
clauses remain in the query as well.这样,任何其他orderby
子句也会保留在查询中。
add_filter('posts_clauses', 'order_by_stock_status');
function order_by_stock_status($posts_clauses) {
global $wpdb;
// only change query on WooCommerce loops
if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag() || is_product_taxonomy())) {
$posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
$posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
$posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
}
return $posts_clauses;
}
You could change istockstatus.meta_value ASC
to istockstatus.meta_value DESC
if you for some reason wanted the Out Of Stock items first.如果您出于某种原因首先想要缺货商品,您可以将istockstatus.meta_value ASC
更改为istockstatus.meta_value DESC
。
Tested on WP: 4.8;在 WP 上测试:4.8; WC 3.0.8厕所 3.0.8
Here is a snippet for rearranging products (in stock come first):这是重新排列产品的片段(有货在先):
<?php
/**
* Order product collections by stock status, instock products first.
*/
class iWC_Orderby_Stock_Status
{
public function __construct()
{
// Check if WooCommerce is active
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000);
}
}
public function order_by_stock_status($posts_clauses)
{
global $wpdb;
// only change query on WooCommerce loops
if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
$posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
$posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
$posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
}
return $posts_clauses;
}
}
new iWC_Orderby_Stock_Status;
?>
https://www.snip2code.com/Snippet/114858/WooCommerce-Products-Order-by-Stock-Stat https://www.snip2code.com/Snippet/114858/WooCommerce-Products-Order-by-Stock-Stat
Access the global configuration options for inventory management in WooCommerce, look to the left of your WordPress admin and click on WooCommerce, then on Settings, then click on the Inventory tab.在 WooCommerce 中访问库存管理的全局配置选项,查看 WordPress 管理员的左侧并单击 WooCommerce,然后单击设置,然后单击库存选项卡。
You will find this "Out of Stock Visibility"你会发现这个“缺货可见性”
Out of Stock Visibility - This checkbox will allow you to determine if you want to hide out of inventory items within the WooCommerce catalog.缺货可见性 - 此复选框将允许您确定是否要隐藏 WooCommerce 目录中的库存项目。
http://www.inmotionhosting.com/support/website/woocommerce/managing-inventory-in-woocommerce http://www.inmotionhosting.com/support/website/woocommerce/managing-inventory-in-woocommerce
For making them appear at the end of the category you could use pre_get_posts to order based on the stock, but then you'll lose your other sorting.为了使它们出现在类别的末尾,您可以使用 pre_get_posts 根据库存进行排序,但随后您将丢失其他排序。
Try this code (put in functions.php of your theme):试试这个代码(放在你的主题的functions.php中):
class iWC_Orderby_Stock_Status {
public function __construct() {
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000);
}
}
public function order_by_stock_status($posts_clauses) {
global $wpdb;
if (is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
$posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
$posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
$posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
}
return $posts_clauses;
}
}
new iWC_Orderby_Stock_Status;
For the last versions of WooCommerce see answer below: https://stackoverflow.com/a/44597448/3925099对于 WooCommerce 的最新版本,请参阅以下答案: https ://stackoverflow.com/a/44597448/3925099
This code work for me:这段代码对我有用:
add_action( 'pre_get_posts', function( $query ) {
if ( $query->is_main_query() && is_woocommerce() && ( is_shop() || is_product_category() || is_product_tag() ) ) {
if( $query->get( 'orderby' ) == 'menu_order title' ) { // only change default sorting
$query->set( 'orderby', 'meta_value' );
$query->set( 'order', 'ASC' );
$query->set( 'meta_key', '_stock_status' );
}
}
});
This is the best solution:这是最好的解决方案:
add_action( 'pre_get_posts', function ( $q ) {
if ( !is_admin() // Target only front end
&& $q->is_main_query() // Only target the main query
&& $q->is_post_type_archive() // Change to suite your needs
) {
$q->set( 'meta_key', '_stock_status' );
$q->set( 'orderby', 'meta_value' );
$q->set( 'order', 'ASC' );
}
}, PHP_INT_MAX );
Edited one answer above:编辑了上面的一个答案:
/**
* @snippet Order product collections by stock status, instock products first.
* @author Rkoms
*/
class iWC_Orderby_Stock_Status {
public function __construct() {
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
add_filter('posts_clauses', array($this, 'order_by_stock_status'), 2000, 2);
}
}
public function order_by_stock_status($posts_clauses, $query) {
global $wpdb;
if ( $query->is_main_query() && is_woocommerce() && (is_shop() || is_product_category() || is_product_tag())) {
$posts_clauses['join'] .= " INNER JOIN $wpdb->postmeta istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
$posts_clauses['orderby'] = " istockstatus.meta_value ASC, " . $posts_clauses['orderby'];
$posts_clauses['where'] = " AND istockstatus.meta_key = '_stock_status' AND istockstatus.meta_value <> '' " . $posts_clauses['where'];
}
return $posts_clauses;
}
}
new iWC_Orderby_Stock_Status;
I tried all the solutions above, they worked but resulted in other issues on the site (probably due to theme conflict), Im sure they are all good in different situations / themes.我尝试了上述所有解决方案,它们有效但导致网站上出现其他问题(可能是由于主题冲突),我确定它们在不同情况/主题下都很好。 The below code finally worked great for me (source mentioned)下面的代码终于对我很有用(提到了来源)
source: https://www.businessbloomer.com/woocommerce-show-in-stock-products-first-shop/来源: https : //www.businessbloomer.com/woocommerce-show-in-stock-products-first-shop/
/**
* @snippet Sort Products By Stock Status - WooCommerce Shop
* @how-to Get CustomizeWoo.com FREE
* @author Rodolfo Melogli
* @compatible WooCommerce 3.9
* @donate $9 https://businessbloomer.com/bloomer-armada/
*/
add_filter( 'woocommerce_get_catalog_ordering_args', 'bbloomer_first_sort_by_stock_amount', 9999 );
function bbloomer_first_sort_by_stock_amount( $args ) {
$args['orderby'] = 'meta_value';
$args['order'] = 'ASC';
$args['meta_key'] = '_stock_status';
return $args;
}
@dacrosby answer really should be the best answer here. @dacrosby 的答案真的应该是这里的最佳答案。 I've had a few issues with compatibility with some plugins but in most use cases it seems to work with no issues at all.我在与某些插件的兼容性方面遇到了一些问题,但在大多数用例中,它似乎完全没有问题。
That being said here are a few caveats话虽如此,这里有一些警告
This version built on top of the same implementation should provide wider compatibility without sacrificing the desired result.这个建立在相同实现之上的版本应该提供更广泛的兼容性,而不会牺牲所需的结果。
/**
* Sorts the Woocommerce Archive product query to push out of stock products to the end
*/
function _nok_order_by_stock_status( $posts_clauses, $query ) {
// only change query on WooCommerce loops
if ( $query->is_main_query() && ( is_product_category() || is_product_tag() || is_product_taxonomy() || is_shop() ) ) {
global $wpdb;
$posts_clauses['join'] .=
" LEFT JOIN (
SELECT post_id, meta_id, meta_value FROM $wpdb->postmeta
WHERE meta_key = '_stock_status' AND meta_value <> ''
) istockstatus ON ($wpdb->posts.ID = istockstatus.post_id) ";
$posts_clauses['orderby'] =
" CASE istockstatus.meta_value WHEN
'outofstock' THEN 1
ELSE 0
END ASC, " . $posts_clauses['orderby'];
}
return $posts_clauses;
}
add_filter( 'posts_clauses', '_nok_order_by_stock_status', 2000, 2 );
作为另一种简单的解决方案,如果您的产品列表在 flexbox 中,您也可以使用 CSS 使用以下规则:
ul.products li.product.outofstock {order:1}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.