programing

woocommerce 위젯 "속성별로 제품 필터링"에 사용할 수 없는 제품이 표시됨

fastcode 2023. 3. 1. 13:46
반응형

woocommerce 위젯 "속성별로 제품 필터링"에 사용할 수 없는 제품이 표시됨

는 WooCommerce에 포함된 속성별 필터 제품이라는 위젯을 사용하고 있습니다.Storefront-Child-Theme 카테고리 페이지에 위젯화된 영역을 만들었습니다.functions.php( ( ( ( ( ( ( )

, size M예를 들어, M 사이즈가 품절된 제품이 나열됩니다.

이걸 어떻게 고칠지 알아?

예: 크기 M으로 필터링하면 이 제품이 표시되지만 이 제품은 사용할 수 없습니다.

여기에 이미지 설명 입력

/* 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;
    // }
}

직접: 기본적으로는 할 수 없습니다.특정 테마나 플러그인이 아니라 Woocommerce 자체와 관련이 있습니다.이것은 오랫동안 woocommerce에 존재하는 문제입니다.Woocommerce에서는 기본적으로 Woocommerce가1 필요로 하고 필요로 하는 것이므로 변동 가시성에 따라 변동 제품 재고 가시성(재고 상태)을 처리할 수 없습니다.

이 방법으로는 다음 액션 기능을 추가하는 방법이 있습니다.

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>";
                        }
                    }
                }
            }
        }
    }
}
?>

이치는 이가 없는 입니다. 첫 것, last last last last last last last, have have have have have have have have have have have have가 있기 때문에 css만으로 이 문제를 회피하기는 어려울 수 또한 각 행에 첫 번째와 마지막 제품이 있기 때문에 css만으로 이 문제를 회피하기는 어려울 수 있습니다.first ★★★★★★★★★★★★★★★★★」lastCSS를 사용하다이를 해결하려면 다음 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 Woocommerce의 WOF Products Filter 플러그인 및 재고 부족 변동 문제

관련:

- 속성별 필터링변동상품 품절품목 숨김

- 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/

좋은 답이 아니야

@Islam Elshobokshy가 말했듯이 재고 변동을 없애기 위해 제품 루프 쿼리를 편집하는 것은 조금 복잡합니다.

그러나 CSS를 사용하여 리스트에서 재고 변동을 "숨김"할 수 있습니다.그러나 제품 목록/그리드에는 2페이지(10개 항목/페이지)에 충분한 제품이 있지만, 이 필터에 의해 1페이지에 1개의 제품이 숨겨져 있는 경우, 1페이지에는 9개의 제품만 표시됩니다.우리는 상품 문의를 받고 있습니다.

저는 여기서 영감을 얻은 무언가를 빠르게 테스트하고 썼습니다.

  • 이 방법은sizeattribute(Woocommerce 또는 URL 파라미터 "filter_*"의 모든 Atribute를 처리하도록 조정하거나 사용되는 모든 Atribute에 대해 하드코딩할 수 있습니다).

코드:

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.php로.your-theme/woocommerce/content-product.php
  • 코드를 아래쪽으로 이동시키다method($product)필요한 제품에 대해서만 true/false를 반환하도록 약간 편집합니다.
  • "가시성 확보" 블록에서 다음과 같이 호출합니다.if ( empty( $product ) || ! $product->is_visible() || !$method($product) )
  • 이렇게 하면 제품이 출력되지 않지만 그리드/목록 문제는 해결되지 않습니다.

결국 루프 쿼리를 필요에 맞게 업데이트하는 것은 복잡할 수 있으며 성능에 부정적인 영향을 미칠 수 있습니다.하지만 더 자세히 알아보려면 다음과 같이 시작해야 합니다.

  • GET 필터 파라미터를 검출하여 query_var를 추가합니다(또는 가 필터링하는 필터/속성과 일치하는 wp_query 파라미터를 직접 검출합니다).
  • woocommerce 제품 wp_hooks를 찾아 연결하다
  • 커스텀 query_var를 검출하는 메서드를 후크합니다.
  • 쿼리를 편집하지만 raw SQL의 경우 문제가 발생할 수 있습니다.

언급URL : https://stackoverflow.com/questions/64167951/woocommerce-widget-filter-products-by-attribute-displays-unavailable-products

반응형