How to add woocommerce-pagination and woocommerce-ordering dropdown to custom shortcode

二次信任 提交于 2019-12-11 17:50:39

问题


I've created a custom shortcode to display products with a minimum stock amount and would like to add pagination to the results as well as calling the woocommerce-ordering dropdown to be displayed on the page.

Here's the shortcode:

// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );

function minimum_stock_shortcode( $atts ) {

global $woocommerce_loop;

// Attributes 
        $atts = shortcode_atts(
            array(
            'limit'         => '40',
            'columns'       => '5',
            'orderby'       => 'title',
            'order'         => 'asc',
            'category'      => '',
            'cat_operator'  => 'IN',
            'stock' => '',
            ),
            $atts, 'minimum_stock'
        );

        $args = array(
            'post_type'             => 'product',
            'post_status'           => 'publish',
            'ignore_sticky_posts'   => 1,
            'posts_per_page'        => $atts['limit'],
            'orderby'               => $atts['orderby'],
            'order'                 => $atts['order'],
            'meta_query'            => array(
                array(
                    'key'           => '_stock',
                    'value'         => $atts['stock'],
                    'compare'       => '>='
                )
            ),
            'tax_query'             => array(
                array(
                    'taxonomy'      => 'product_cat',
                    'field'         => 'slug',
                    'terms'         => $atts['category'],
                )   
            )
        );


ob_start();

$products = new WP_Query( $args );

$woocommerce_loop['columns'] = $atts['columns'];

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

    <?php woocommerce_product_loop_start(); ?>

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

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

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

    <?php woocommerce_product_loop_end(); ?>

<?php endif;

wp_reset_postdata();

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

Any help would be very much appreciated!

Kind regards, JP


回答1:


Okay, so I've got pagination working and tidied things up a bit (it was throwing some errors in the debug log), the code now looks like this:

// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );

function minimum_stock_shortcode( $atts ) {

global $product, $woocommerce, $woocommerce_loop;

// Attributes 
        $atts = shortcode_atts(
            array(
            'limit'                 => '40',
            'columns'               => '5',
            'orderby'               => 'title',
            'order'                 => 'asc',
            'category'              => '',
            'cat_operator'          => 'IN',
            'stock'                 => '',
            ),
            $atts, 'minimum_stock'
        );

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

        $args = array(
            'post_type'             => 'product',
            'post_status'           => 'publish',
            'ignore_sticky_posts'   => 1,
            'posts_per_page'        => $atts['limit'],
            'orderby'               => $atts['orderby'], 
            'order'                 => $atts['order'], 
            'paged'                 => $paged, 
            'meta_query'            => array(
                array(
                    'key'           => '_stock',
                    'value'         => $atts['stock'],
                    'compare'       => '>='
                )
            ),
            'tax_query'             => array(
                array(
                    'taxonomy'      => 'product_cat',
                    'field'         => 'slug',
                    'terms'         => $atts['category'],
                )   
            )
        );

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


ob_start();

$products = new WP_Query( $args );

$woocommerce_loop['columns'] = $atts['columns'];


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

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

if($products->max_num_pages>1){
?>

<nav class="woocommerce-pagination"> 

<?php echo paginate_links( apply_filters(
        'woocommerce_pagination_args', array( 
            'base'      => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ), 
            'format'    => '', 
            'current'   => max( 1, get_query_var( 'paged' ) ), 
            'total'     => $products->max_num_pages, 
            'prev_text' => '&larr;', 
            'next_text' => '&rarr;', 
            'type'      => 'list', 
            'end_size'  => 3, 
            'mid_size'  => 3 
        )
    )       
);

?>

</nav>

<?php }

woocommerce_reset_loop(); 
wp_reset_postdata();

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

// Remove ordering query arguments 
WC()->query->remove_ordering_args();

return $return; 
}

Does anyone know how I can now call the woocommerce-ordering dropdown?

I've tried adding:

<?php do_action( 'woocommerce_before_shop_loop' ); ?>

But this doesn't seem to work, when I check the page it does have the 'woocommerce-notices-wrapper' but there's no sign of the 'woocommerce_catalog_ordering' that I thought should also be called with 'woocommerce_before_shop_loop'.

Any and all help will be very much appreciated :)

Update:

I found this question Adding 'sort by' drop down on custom page using woocommerce short code which gave me the answer I needed to add the woocommerce-ordering dropdown.

Here's my updated code:

// Minimum Stock Shortcode
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );

function minimum_stock_shortcode( $atts ) {

global $woocommerce_loop;

// Attributes 
        $atts = shortcode_atts(
            array(
            'limit'                 => '40',
            'columns'               => '5',
            'orderby'               => 'date',
            'order'                 => 'desc',
            'category'              => '',
            'cat_operator'          => 'IN',
            'stock'                 => '',
            ), $atts );

    if ( ! $atts['category'] ) {
        return '';
    }

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

// Default ordering args
$ordering_args = WC()->query->get_catalog_ordering_args( $atts['orderby'],    
$atts['order'] );
$orderby = 'date';
$order = 'desc';
if ( isset( $_GET['orderby'] ) ) {
    $getorderby = $_GET['orderby'];
}
if ($getorderby == 'date') {
    $orderby = 'date';
    $order = 'desc';
} elseif ($getorderby == 'sku_desc') {
    $orderby = 'meta_value';
    $order = 'desc';
    $meta_key = '_sku';
} elseif ($getorderby == 'sku_asc') {
    $orderby = 'meta_value';
    $order = 'asc';
    $meta_key = '_sku';
}

        $args = array(
            'post_type'             =>  array( 'product', 'product_variation' ),
            'post_status'           => 'publish',
            'ignore_sticky_posts'   => 1,
            'posts_per_page'        => $atts['limit'],
            'orderby'               => $orderby, // $ordering_args['orderby'],
            'order'                 => $order, // $ordering_args['order'],
            'paged'                 => $paged, 
            'meta_query'            => array(
                array(
                    'key'           => '_stock',
                    'value'         => $atts['stock'],
                    'compare'       => '>='
                )
            ),
            'tax_query'             => array(
                array(
                    'taxonomy'      => 'product_cat',
                    'field'         => 'slug',
                    'terms'         => $atts['category'],
                )   
            )
        );

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


ob_start();

$products = new WP_Query( $args );

$woocommerce_loop['columns'] = $atts['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(
                        'date'      => __( 'Sort by latest', 'woocommerce' ),
                        'sku_asc'   => __( 'A-Z / Low to High Numbers', 'woocommerce' ),
                        'sku_desc'  => __( 'Z-A / High to Low Numbers', 'woocommerce' )
                    ) );

                    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;

if($products->max_num_pages>1){
?>

<nav class="woocommerce-pagination"> 

<?php echo paginate_links( apply_filters(
        'woocommerce_pagination_args', array( 
            'base'      => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ), 
            'format'    => '', 
            'current'   => max( 1, get_query_var( 'paged' ) ), 
            'total'     => $products->max_num_pages, 
            'prev_text' => '&larr;', 
            'next_text' => '&rarr;', 
            'type'      => 'list', 
            'end_size'  => 3, 
            'mid_size'  => 3 
        )
    )       
);

?>

</nav>

<?php }

woocommerce_reset_loop(); 
wp_reset_postdata();

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

// Remove ordering query arguments 
WC()->query->remove_ordering_args();

return $return; 
}

I hope someone might find this helpful :)

Kind regards, JP



来源:https://stackoverflow.com/questions/54357039/how-to-add-woocommerce-pagination-and-woocommerce-ordering-dropdown-to-custom-sh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!