Woocommerce,基于短代码的产品列表上的排序下拉列表

2024-05-16

在我们的商店里,我们有许多标准的 WP 页面。在这些页面上,我们使用标准 Woocommerce 短代码展示了约 40 种产品。

例如:

[product_category category="boots" per_page="20" columns="4" orderby="price" order="desc"]

产品出现了,但缺少两件事:

  1. 产品列表上方没有出现排序下拉菜单,因此我们的访客无法对产品进行排序。
  2. 我们没有看到任何分页按钮,因此每页上只能看到前 20 个产品。

我们有什么想法可以解决这两件事吗?


关于你的第一个问题,除了破解WC中的短代码之外,我还没有找到任何好的解决方案。不完全建议,因为它会被 WC 的每次升级/补丁覆盖。如果绝对有必要,您可以在每次升级时通过重写 hack 来维护代码。

好的,首先下载一个副本包括\class-wc-shortcodes.php在您的 woocommerce 文件夹中。在编辑之前对原始文件进行备份,我通常使用 -o 重命名文件或将文件类型更改为 .bak。

假设您想要商店页面上 WC 附带的原始排序方式下拉列表。

Step 1删除简码上的 orderby 和 order 参数:

[product_category category="boots" per_page="20" columns="4"]

Step 2编辑产品类别短代码类-wc-shortcodes.php像这样:

/**
 * List products in a category shortcode
 *
 * @access public
 * @param array $atts
 * @return string
 */
public static function product_category( $atts ) {
    global $woocommerce_loop, $wpdb;

    if ( empty( $atts ) ) return '';

    extract( shortcode_atts( array(
        'per_page'      => '12',
        'columns'       => '4',
        'orderby'       => 'title',
        'order'         => 'asc',
        'category'      => '',
        'operator'      => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
        ), $atts ) );

    if ( ! $category ) return '';

    // Default ordering args
    // $ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order ); // COMMENT THIS OUT
    $orderby = 'title';
    $order = 'asc';
    if ( isset( $_GET['orderby'] ) ) {
        $getorderby = $_GET['orderby'];
    }
    if ($getorderby == 'popularity') {
        $orderby = 'meta_value_num';
        $order = 'desc';
        $meta_key = 'total_sales';
    } elseif ($getorderby == 'rating') {

        $fields .= ", AVG( $wpdb->commentmeta.meta_value ) as average_rating ";

        $where .= " AND ( $wpdb->commentmeta.meta_key = 'rating' OR $wpdb->commentmeta.meta_key IS null ) ";

        $join .= "
            LEFT OUTER JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
            LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
        ";

        $orderby = "average_rating DESC, $wpdb->posts.post_date DESC";

        $groupby = "$wpdb->posts.ID";   

    } elseif ($getorderby == 'date') {
        $orderby = 'date';
        $order = 'desc';
    } elseif ($getorderby == 'price') {
        $orderby = 'meta_value_num';
        $order = 'asc';
        $meta_key = '_price';
    } elseif ($getorderby == 'price-desc') {
        $orderby = 'meta_value_num';
        $order = 'desc';
        $meta_key = '_price';
    }
    $args = array(
        'post_type'             => 'product',
        'post_status'           => 'publish',
        'ignore_sticky_posts'   => 1,
        'orderby'               => $orderby, // $ordering_args['orderby'],
        'order'                 => $order, // $ordering_args['order'],
        'meta_key'              => $meta_key,
        'fields'                => $fields,
        'where'                 => $where,
        'join'                  => $join,
        'groupby'               => $groupby,
        'posts_per_page'        => $per_page,
        'meta_query'            => array(
            array(
                'key'           => '_visibility',
                'value'         => array('catalog', 'visible'),
                'compare'       => 'IN'
            )
        ),
        'tax_query'             => array(
            array(
                'taxonomy'      => 'product_cat',
                'terms'         => array( esc_attr( $category ) ),
                'field'         => 'slug',
                'operator'      => $operator
            )
        )
    );

    if ( isset( $ordering_args['meta_key'] ) ) {
        $args['meta_key'] = $ordering_args['meta_key'];
    }

    ob_start();

    $products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $args, $atts ) );

    $woocommerce_loop['columns'] = $columns;

    if ( $products->have_posts() ) : ?>

    <div style="width:100%;">
        <div style="float:right">
            <form class="woocommerce-ordering" method="get">
                <select name="orderby" class="orderby">
                    <?php
                        $catalog_orderby = apply_filters( 'woocommerce_catalog_orderby', array(
                            'menu_order' => __( 'Default sorting', 'woocommerce' ),
                            'popularity' => __( 'Sort by popularity', 'woocommerce' ),
                            'rating'     => __( 'Sort by average rating', 'woocommerce' ),
                            'date'       => __( 'Sort by newness', 'woocommerce' ),
                            'price'      => __( 'Sort by price: low to high', 'woocommerce' ),
                            'price-desc' => __( 'Sort by price: high to low', 'woocommerce' )
                        ) );

                        if ( get_option( 'woocommerce_enable_review_rating' ) === 'no' )
                            unset( $catalog_orderby['rating'] );

                        foreach ( $catalog_orderby as $id => $name )
                            echo '<option value="' . esc_attr( $id ) . '" ' . selected( $getorderby, $id, false ) . '>' . esc_attr( $name ) . '</option>';
                    ?>
                </select>
                <?php
                    // Keep query string vars intact
                    foreach ( $_GET as $key => $val ) {
                        if ( 'orderby' === $key || 'submit' === $key )
                            continue;

                        if ( is_array( $val ) ) {
                            foreach( $val as $innerVal ) {
                                echo '<input type="hidden" name="' . esc_attr( $key ) . '[]" value="' . esc_attr( $innerVal ) . '" />';
                            }

                        } else {
                            echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $val ) . '" />';
                        }
                    }
                ?>
            </form>
        </div>
    </div>
    <div style="clear:both;"></div>

        <?php woocommerce_product_loop_start(); ?>

            <?php while ( $products->have_posts() ) : $products->the_post(); ?>

                <?php wc_get_template_part( 'content', 'product' ); ?>

            <?php endwhile; // end of the loop. ?>

        <?php woocommerce_product_loop_end(); ?>

    <?php endif;

    woocommerce_reset_loop();
    wp_reset_postdata();

    return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}

将文件上传回包含文件夹即可完成!您的短代码产品页面现在将具有与 WC 商店页面上显示的相同的按下拉列表进行工作的排序。

根据您的喜好编辑排序选项!希望能帮助到你!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Woocommerce,基于短代码的产品列表上的排序下拉列表 的相关文章

随机推荐