如何实现分页是自定义短代码?

时间:2017-04-20 07:30:21

标签: php wordpress pagination woocommerce

我正在使用woocommerce 3.0.3,wordpress 4.7.3。

我创建了一个带有以下代码的自定义shortocde(参考默认[产品] woocommerce的短代码),但是分页不起作用,第2页变成空白。

<?php
add_shortcode('poster_products', 'poster_products');

if ( ! function_exists('poster_products') ){
    function poster_products( $atts ) {
        $atts = shortcode_atts( array(
            'columns' => '4',
            'orderby' => 'title',
            'order'   => 'asc',
            'ids'     => '',
            'skus'    => '',
            'posts_per_page' => -1
        ), $atts, 'products' );

        $query_args = array(
            'post_type'           => 'product',
            'post_status'         => 'publish',
            'ignore_sticky_posts' => 1,
            'orderby'             => $atts['orderby'],
            'order'               => $atts['order'],
            'posts_per_page'      => $atts['posts_per_page'],
            'paged'               => max( 1, get_query_var( 'paged' ) ),
            'post__in'            => $atts['ids'],
            //'meta_query'          => WC()->query->get_meta_query(),
            //'tax_query'           => WC()->query->get_tax_query(),
        );

        if ( ! empty( $atts['skus'] ) ) {
            $query_args['meta_query'][] = array(
                'key'     => '_sku',
                'value'   => array_map( 'trim', explode( ',', $atts['skus'] ) ),
                'compare' => 'IN',
            );
        }

        if ( ! empty( $atts['ids'] ) ) {
            $query_args['post__in'] = array_map( 'trim', explode( ',', $atts['ids'] ) );
        }

        return poster_product_loop( $query_args, $atts, 'products' );
    }
}

if ( ! function_exists('poster_product_loop') ){
    function poster_product_loop( $query_args, $atts, $loop_name ) {

        global $woocommerce_loop;
        $columns                     = absint( $atts['columns'] );
        $woocommerce_loop['columns'] = $columns;
        $woocommerce_loop['name']    = $loop_name;
        $query_args                  = apply_filters( 'woocommerce_shortcode_poster_product_query', $query_args, $atts, $loop_name );
        $transient_name              = 'wc_loop' . substr( md5( json_encode( $query_args ) . $loop_name ), 28 ) . WC_Cache_Helper::get_transient_version( 'product_query' );
        $products                    = get_transient( $transient_name );
        if ( false === $products || ! is_a( $products, 'WP_Query' ) ) {
            $products = new WP_Query( $query_args );
            set_transient( $transient_name, $products, DAY_IN_SECONDS * 30 );
        }
        ob_start();
        if ( $products->have_posts() ) {
            ?>

            <?php do_action( "woocommerce_shortcode_before_{$loop_name}_loop", $atts ); ?>

            <?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 do_action( "woocommerce_shortcode_after_{$loop_name}_loop", $atts ); ?>


            <?php
            do_action('woocommerce_pagination_after_poster_product_loop', $products);
        } else {
            do_action( "woocommerce_shortcode_{$loop_name}_loop_no_results", $atts );
        }
        woocommerce_reset_loop();
        wp_reset_postdata();

        do_action( 'woocommerce_after_shop_loop' );

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

add_action('woocommerce_pagination_after_poster_product_loop', 'woocommerce_pagination_after_poster_product_loop');
if ( ! function_exists( 'woocommerce_pagination_after_poster_product_loop' ) ) {
    function woocommerce_pagination_after_poster_product_loop($products) {
        //wc_get_template( 'loop/pagination.php' );

        if ( ! defined( 'ABSPATH' ) ) {
            exit; // Exit if accessed directly
        }
        global $wp_query;
        if ( $products->max_num_pages <= 1 ) {
            return;
        }
        ?>
        <nav class="woocommerce-pagination">
        <?php
        echo paginate_links( apply_filters( 'woocommerce_pagination_args', array(
            'base'         => esc_url_raw( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
            'format'       => '?paged=%#%',
            'add_args'     => false,
            '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
}

分页创建网址结构,如/page/2/

第2页源代码显示

</nav> 
<!DOCTYPE html> 

if ( ! function_exists('poster_products') ){ 

echo var_dump(get_query_var( 'page' )); //  ""
echo var_dump(get_query_var( 'paged' ));  // ""

function poster_products( $atts ) {
        return "poster_products getting called"; 

不返回任何内容,因此第2页没有调用poster_products

1 个答案:

答案 0 :(得分:0)

已经有一个多月了,但当时我已经完成了这段代码,现在对我有用。

/**
* Creates poster_products shortcode
*/
add_shortcode('poster_products', 'poster_products');

if ( ! function_exists('poster_products') ){

    function poster_products( $atts ) {

        $atts = shortcode_atts( array(
            'columns'  => '3',
            'orderby'  => 'title',
            'meta_key' => '',
            'order'    => 'asc',
            'ids'      => '',
            'skus'     => '',
            'posts_per_page' => -1
        ), $atts, 'products' );

        $page_number = is_front_page() ? max( 1, get_query_var( 'page' ) ) : max( 1, get_query_var( 'paged' ) ); 

        $query_args = array(
            'post_type'           => 'product',
            'post_status'         => 'publish',
            'ignore_sticky_posts' => 1,
            'orderby'             => $atts['orderby'],
            'meta_key'            => $atts['meta_key'],
            'order'               => $atts['order'],
            'posts_per_page'      => $atts['posts_per_page'],
            'paged'               => $page_number,
            //'meta_query'          => WC()->query->get_meta_query(),
            //'tax_query'           => WC()->query->get_tax_query(),
        );

        if ( ! empty( $atts['skus'] ) ) {
            $query_args['meta_query'][] = array(
                'key'     => '_sku',
                'value'   => array_map( 'trim', explode( ',', $atts['skus'] ) ),
                'compare' => 'IN',
            );
        }

        if ( ! empty( $atts['ids'] ) ) {
            $query_args['post__in'] = array_map( 'trim', explode( ',', $atts['ids'] ) );
        }

        $query_args['tax_query'][] = array(
            'taxonomy' => WC_PRODUCT_VENDORS_TAXONOMY,
            'operator' => 'EXISTS'
        );

        return poster_product_loop( $query_args, $atts, 'products' );
    }
}

/**
* Adds Poster Product Grid to poster_products shortcode
*/
if ( ! function_exists('poster_product_loop') ){
    function poster_product_loop( $query_args, $atts, $loop_name ) {

        global $woocommerce_loop;
        $columns                     = absint( $atts['columns'] );
        $woocommerce_loop['columns'] = $columns;
        $woocommerce_loop['name']    = $loop_name;
        $query_args                  = apply_filters( 'woocommerce_shortcode_poster_product_query', $query_args, $atts, $loop_name );
        $transient_name              = 'wc_loop' . substr( md5( json_encode( $query_args ) . $loop_name ), 28 ) . WC_Cache_Helper::get_transient_version( 'product_query' );
        $products                    = get_transient( $transient_name );
        if ( false === $products || ! is_a( $products, 'WP_Query' ) ) {
            $products = new WP_Query( $query_args );
            set_transient( $transient_name, $products, DAY_IN_SECONDS * 30 );
        }
        ob_start();

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

            <?php do_action( "woocommerce_shortcode_before_{$loop_name}_loop", $atts ); ?>

            <?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 do_action( "woocommerce_shortcode_after_{$loop_name}_loop", $atts ); ?>


            <?php
            do_action('woocommerce_after_sms_user_poster_product_loop', $products);

        } else {
            do_action( "woocommerce_shortcode_{$loop_name}_loop_no_results", $atts );
        }
        woocommerce_reset_loop();
        wp_reset_postdata();

        //do_action( 'woocommerce_after_shop_loop' );

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