【问题标题】:Woocommerce, sort dropdown on shortcode based product listsWoocommerce,基于短代码的产品列表的排序下拉列表
【发布时间】:2013-08-07 01:18:45
【问题描述】:

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

例如:

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

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

  1. 产品列表上方没有排序下拉菜单,因此我们的访问者无法对产品进行排序。
  2. 我们看不到任何分页按钮,因此不可能在每个页面上看到超过前 20 个产品。

有什么想法可以解决这两个问题吗?

【问题讨论】:

    标签: wordpress sorting pagination woocommerce


    【解决方案1】:

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

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

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

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

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

    第 2 步 编辑 class-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 商店页面上显示的下拉列表相同的工作排序。

    根据自己的喜好编辑排序选项!希望对您有所帮助!

    【讨论】:

      【解决方案2】:

      您的第二个问题很好:您的简码限制为只能查看 20 种产品。将其更改为 per_page="40",您应该会看到 40 个产品,或者直接删除该行,产品数量不受限制。

      对于您的第一个问题,我没有答案。我也在为自己寻找它:)。

      【讨论】:

        猜你喜欢
        • 2016-09-05
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        • 1970-01-01
        • 2018-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多