WooCommerce小工具“按属性筛选产品”显示不可用的产品。

8
我正在使用WooCommerce中包含的小部件之一,名为按属性筛选产品。我在我的Storefront-child-theme functions.php中的类别页面上创建了一个小部件区域(请参见下面的代码)。
但是,当我按属性尺寸M进行筛选时,它会列出尺寸M已售罄的产品...
有任何想法如何解决这个问题吗? 示例:按尺寸M进行筛选会显示此产品,但该产品不可用:

enter image description here

/* FILTER BY SIZE WIDGET */
// Adding the widget area.
if (function_exists('register_sidebar')) {
    register_sidebar(array(
    'name' => 'Below category title',
    'id' => 'extra-widget-area',
    'description' => 'Below category title',
    'before_widget' => '<div class="widget below-cat-title-widget">',
    'after_widget' => '</div>',
    'before_title' => '<h6 class="below-cat-title-widget-title">',
    'after_title' => '</h6>'
    ));
}
// placing the widget
add_action( 'woocommerce_archive_description', 'add_my_widget_area', 31 );
function add_my_widget_area() {
  if (function_exists('dynamic_sidebar')) {
    dynamic_sidebar('Below category title');
  }
}

add_action( 'woocommerce_archive_description', 'filter_button_function', 21 );
function filter_button_function() {
    // if ( is_product_category() ) {
        // global $wp_query;
        // $cat_id = $wp_query->get_queried_object_id();
        // $cat_desc = term_description( $cat_id, 'product_cat' );
        if (get_locale() == 'fr_FR') {
            $filter_html = '<div class="filter_by_size" class="subtitle">'.'FILTRE PAR TAILLE'.'&nbsp;&nbsp;<span class="filter-icon"></span>'.'</div>';
        } else {
            $filter_html = '<div class="filter_by_size" class="subtitle">'.'FILTER BY SIZE'.'&nbsp;&nbsp;<span class="filter-icon"></span>'.'</div>';
        }

        echo $filter_html;
    // }
}
2个回答

7
我会直接说明:默认情况下,您无法这样做。这与特定主题或插件无关,而是与Woocommerce本身有关。这是Woocommerce存在已久的问题之一。在Woocommerce中,默认情况下无法处理可变产品库存可见性(库存状态),因为这是Woocommerce1所必需和需要的。
一种解决方法是添加此操作函数:
add_action('woocommerce_before_shop_loop_item', 'out_of_stock_variations_loop');
function out_of_stock_variations_loop()
{
    global $product;
    $filter = 'size';
    if ($product->product_type === 'variable') {
        $available = $product->get_available_variations();
        if ($available) {
            foreach ($available as $instockvar) {
                if (isset($instockvar[ 'attributes' ][ 'attribute_pa_' . $filter ])) {
                    if ($_GET[ 'filter_' . $filter ]) {
                        if ( !in_array( $instockvar[ 'attributes' ][ 'attribute_pa_' . $filter ], explode(',', $_GET[ 'filter_' . $filter ]) , true ) || ($instockvar[ 'max_qty' ] <= 0) ) {
                            echo "<style>.post-" . $product->get_id() . " {display: none}</style>";
                        } else {
                            echo "<style>.post-" . $product->get_id() . " {display: list-item !important}</style>";
                        }
                    }
                }
            }
        }
    }
}
?>

这将仅显示库存中的产品列表。问题在于,使用此查询删除不在库存中的产品会留下空白空间,而仅使用css可能难以解决此问题,因为在每一行上,第一个和最后一个产品都有firstlast类来确定它们在CSS中的布局。为了克服这个问题,请将此jQuery添加到您的子主题js脚本中:

function openLayeredNavFilterIfSelected() {

  if (jQuery('.wc-layered-nav-term').hasClass('woocommerce-widget-layered-nav-list__item--chosen')) {

    /*keep layered nav filter open, if at least an attribute is selected*/
    jQuery('.woocommerce-widget-layered-nav-list__item--chosen').parent().parent().show();
    if (!jQuery('.filter-icon').hasClass('arrow_up')) {
      jQuery('.filter-icon').addClass('arrow_up');
    }

    /*redistribute products rows to avoid missing spaces*/
    jQuery('.site-main ul.products.columns-3 li.product').removeClass('first').removeClass('last');
    jQuery('.site-main ul.products.columns-3 li.product:visible').each(function(i) {
      if (i % 3 == 0) jQuery(this).addClass('first'); //add class first to firsts products of rows
      if (i % 3 == 2) jQuery(this).addClass('last'); //add class last to lasts products of rows
    });
  }
}

openLayeredNavFilterIfSelected();
jQuery(window).resize(openLayeredNavFilterIfSelected);

希望这些对你有所帮助。

1 WOOF产品过滤器插件和WooCommerce中缺货变体问题

相关:

- 按属性筛选产品并隐藏可变产品的缺货物品

- 如何防止“缺货”商品在侧边栏(分层导航小部件)中显示为筛选选项?在WooCommerce中

- https://wordpress.org/support/topic/hide-out-of-stock-variations-when-filtering/#post-7718128

- https://xtemos.com/forums/topic/filter-attributes-dont-show-out-of-stock-variations/ 这里是一个关于如何过滤掉无库存变体的属性的讨论。

- https://wordpress.org/support/topic/exclude-out-of-stock-products-from-filter/ 这里是一个有关如何从筛选器中排除无库存产品的讨论。


1

这里没有一个真正好的答案。

如@Islam Elshobokshy所说,编辑产品循环查询以删除缺货变体有点复杂。

不过,您可以使用CSS来“隐藏”清单中的缺货变体。但是它可能会“破坏”您的产品列表/网格:如果有足够的产品供两个页面使用(每页10个项目),但此筛选器在第1页上隐藏了一个产品,则第1页将仅有9个产品。我们正在寻找产品查询。

我快速测试并从this中得到了一些灵感:

  • 这适用于size属性(它可以被调整为处理来自Woocommerce的所有属性、URL参数“filter_*”或为使用的每个属性硬编码)

代码:

add_action('woocommerce_before_shop_loop_item', 'out_of_stock_variations_loop');
function out_of_stock_variations_loop()
{
    global $product;

    $filter = 'size'; //to edit

    if ($product->product_type === 'variable') {
        $available = $product->get_available_variations();
        if ($available) {
            foreach ($available as $instockvar) {
                if (isset($instockvar[ 'attributes' ][ 'attribute_pa_' . $filter ])) {
                    if (($instockvar[ 'attributes' ][ 'attribute_pa_' . $filter ] === $_GET[ 'filter_' . $filter ]) && ($instockvar[ 'max_qty' ] <= 0)) {
                        //sadly echo some inline CSS :(
                        echo "<style>.post-" . $product->get_id() . " {display: none}</style>";

                        //some tests using is_visible() filters, but we are too late here
                        //add_filter( 'woocommerce_product_is_visible', function($visible, $id) use ($the_id) {return $id === $the_id ? false : $visible;}, 50, 2);
                    }
                }
            }
        }
    }
}

为了不使用内联CSS,您可以:
  • 覆盖 /woocommerce/template/content-product.phpyour-theme/woocommerce/content-product.php
  • 将下面的代码移动到一个 method($product) 中,编辑它以仅针对所需产品返回 true/false
  • 在“确保可见性”块中调用它,如 if ( empty( $product ) || ! $product->is_visible() || !$method($product) )
  • 这将防止输出产品,但不会解决网格/列表问题。
最后,更新循环查询以满足您的需求可能会很复杂,并且会对性能产生负面影响。但是,要探索更多内容,我会从以下步骤开始:
  • 通过检测GET过滤器参数(或直接检测与您知道的过滤器/属性匹配的wp_query参数)添加一个query_var
  • 找到并钩住woocommerce产品wp_query周围
  • 挂钩一个方法来检测您的自定义query_var
  • 编辑查询,但如果涉及原始SQL,则可能会很痛苦..

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接