Wordpress-具有Ajax的多分类Ajax过滤器加载更多帖子

时间:2018-10-13 10:01:45

标签: php ajax wordpress filter taxonomy

经过一个月的尝试,终于可以正常工作了,但是有一个小问题我无法解决!如果他发现了两个分类法之间的帖子,则过滤器是可以的,但是如果没有任何帖子,它应该给我get_template_part( 'template-parts/content', 'none' );,但他停止了过滤...!

这是模板页面。

<?php
/**
 * Template Name: Cat Filter Full Width
 *
 * Use this template to build pages with Page Builders.
 * 
 * @package HitMag
 */

get_header(); ?>

<div class="filter-content-area" style="position: relative;">
    <div id="primary-filter">
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="misha_filters">

<?php echo "<label><input type='checkbox' name='all'> All</label>"; ?>

    <?php

        if( $terms = get_terms( 'zones', 'orderby=name%parent=0' ) ) : // to make it simple I use default categories
            echo '<select name="categoryfilter"><option>All Creative Zones...</option>';
            foreach ( $terms as $term ) :
                echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
            endforeach;
            echo '</select>';
        endif;
    ?>
    <?php

        if( $terms = get_terms( 'category', 'orderby=name%parent=0&exclude=233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,18,212,214,47,35,125,6,17,209,252' ) ) : // to make it simple I use default categories
            echo '<select name="categoryfilter2"><option>Select Zone...</option>';
            foreach ( $terms as $term ) :
                echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
            endforeach;
            echo '</select>';
        endif;
    ?>
    <button>Apply filter</button>
    <input type="hidden" name="action" value="myfilter">

</form>
    </div>
</div>
        <?php


$args = array(
    'orderby' => 'date',
    'post_type' => 'post',
    'post_status' => 'publish',
    'ignore_sticky_posts' => 1,
    'posts_per_page' => 18,
    'tax_query' => array(
        array(
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => array('galleries')
        ),
    )
);

$query = new WP_Query( $args );

        if ( $query->have_posts() ) : ?>
                <div id="responses">
            <?php

            $archive_content_layout = get_option( 'archive_content_layout', 'th-grid-2' );
            echo '<div class="posts-wrap ' . esc_attr( $archive_content_layout ) . '">';

                /* Start the Loop */
                while ( $query->have_posts() ) : $query->the_post();

                    get_template_part( 'template-parts/content', get_post_format() );

                endwhile;

            echo '</div><!-- .posts-wrap -->';
        wp_reset_postdata();
?>
</div>
<?php 
global $wp_query;

if (  $query->max_num_pages > 1 ) :
    echo '<div id="misha_loadmore">More posts</div>'; // you can use <a> as well
endif;
            the_posts_pagination();

        else :

            get_template_part( 'template-parts/content', 'none' );

        endif; ?>

        </main><!-- #main -->
    </div><!-- #primary -->

<?php
get_sidebar();
get_footer();

我的loadmore脚本的js

function misha_my_load_more_button_scripts() {

    global $wp_query; 

    wp_register_script( 'misha_filter_scripts', get_stylesheet_directory_uri().'/custom-js/myloadmorebutton.js', array('jquery'), '1.0.0', true );
    wp_enqueue_script( 'misha_filter_scripts' );

    // now the most interesting part
    // we have to pass parameters to myloadmore.js script but we can get the parameters values only in PHP
    // you can define variables directly in your HTML but I decided that the most proper way is wp_localize_script()
    wp_localize_script( 'misha_filter_scripts', 'misha_loadmore_button_params', array(
        'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
        'posts' => json_encode( $query->query_vars ), // everything about your loop is here
        'current_page' => $query->query_vars['paged'] ? $query->query_vars['paged'] : 1,
        'max_page' => $query->max_num_pages
    ) );
}

add_action( 'wp_enqueue_scripts', 'misha_my_load_more_button_scripts', 1 );

这是过滤器功能。

function misha_filter_function(){

    $args = array(
        'post_type' => 'post',
        'post_status' => 'publish',
        'ignore_sticky_posts' => 1,
        'posts_per_page' => '18'
    );

        $args['tax_query'] = array(
            'relation' => 'AND',
        );

if( empty( $_POST['all'] ) ) {
    if( isset( $_POST['categoryfilter'] ) )
            $args['tax_query'] = array(
                array(
                    'taxonomy' => 'zones',
                    'field' => 'id',
                    'terms' => $_POST['categoryfilter'],
                )
            );

if( isset( $_POST['categoryfilter'] ) )
    $args['tax_query'][] = array(
        array(
            'taxonomy' => 'zones',
            'field' => 'id',
            'terms' => $_POST['categoryfilter'],
        )
    );


if( isset( $_POST['categoryfilter2'] ) )
    $args['tax_query'][] = array(
        array(
            'taxonomy' => 'category',
            'field' => 'id',
            'terms' => $_POST['categoryfilter2'],
        )
    );
} 

    $query = new WP_Query( $args );

global $wp_query;

    if( $query->have_posts() ) :

        ob_start(); 

            $archive_content_layout = get_option( 'archive_content_layout', 'th-grid-2' );
            echo '<div class="posts-wrap ' . esc_attr( $archive_content_layout ) . '">';

        while( $query->have_posts() ): $query->the_post();

            get_template_part( 'template-parts/content', get_post_format() );


        endwhile;

            echo '</div><!-- .posts-wrap -->';
        wp_reset_postdata();
        $content = ob_get_contents(); // we pass the posts to variable
        ob_end_clean(); // clear the buffer

    else :
        get_template_part( 'template-parts/content', 'none' );
    endif;

    echo json_encode( array(
        'posts' => serialize( $query->query_vars ),
        'max_page' => $query->max_num_pages,
        'found_posts' => $query->found_posts,
        'content' => $content
    ) );

    die();
}
add_action('wp_ajax_myfilter', 'misha_filter_function'); 
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');

此功能适用于Ajax loadmore帖子。

add_action('wp_ajax_loadmorebutton', 'misha_loadmore_button_ajax_handler');
add_action('wp_ajax_nopriv_loadmorebutton', 'misha_loadmore_button_ajax_handler');

function misha_loadmore_button_ajax_handler(){

    $args = unserialize( stripslashes( $_POST['query']) );
    $args['paged'] = $_POST['page'] + 1; 
    $args['post_status'] = 'publish';

$query = new WP_Query( $args );

    global $wp_query;

    if( $query->have_posts() ) :

            $archive_content_layout = get_option( 'archive_content_layout', 'th-grid-2' );
            echo '<div class="posts-wrap ' . esc_attr( $archive_content_layout ) . '">';

        while( $query->have_posts() ): $query->the_post();

            get_template_part( 'template-parts/content', get_post_format() );


        endwhile;

            echo '</div><!-- .posts-wrap -->';


    else :
        get_template_part( 'template-parts/content', 'none' );
    endif;

    die; 
}

最后还有JS用于过滤器功能action和loadmore。

jQuery(document).ready( function($) {

    /*
     * Load More
     */
    $('#misha_loadmore').click(function(){

        $.ajax({
            url : misha_loadmore_button_params.ajaxurl, // AJAX handler
            data : {
                'action': 'loadmorebutton', // the parameter for admin-ajax.php
                'query': misha_loadmore_button_params.posts, // loop parameters passed by wp_localize_script()
                'page' : misha_loadmore_button_params.current_page // current page
            },
            type : 'POST',
            beforeSend : function ( xhr ) {
                $('#misha_loadmore').text('Loading...'); // some type of preloader
            },
            success : function( data ){
                if( data ) {

                    $('#misha_loadmore').text( 'More posts' );
                    $('#responses').append(data); // insert new posts
                    misha_loadmore_button_params.current_page++;

                    if ( misha_loadmore_button_params.current_page == misha_loadmore_button_params.max_page ) 
                        $('#misha_loadmore').hide(); // if last page, HIDE the button

                } else {
                    $('#misha_loadmore').hide(); // if no data, HIDE the button as well
                }
            }
        });
        return false;
    });

    /*
     * Filter
     */
    $('#misha_filters').submit(function(){

        $.ajax({
            url : misha_loadmore_button_params.ajaxurl,
            data : $('#misha_filters').serialize(), // form data
            dataType : 'json', // this data type allows us to receive objects from the server
            type : 'POST',
            beforeSend : function(xhr){
                $('#misha_filters').find('button').text('Filtering...');
            },
            success:function(data){

                $('html,body').animate({ scrollTop: $("#main").offset().top }, "slow");

                // when filter applied:
                // set the current page to 1
                misha_loadmore_button_params.current_page = 1;

                // set the new query parameters
                misha_loadmore_button_params.posts = data.posts;

                // set the new max page parameter
                misha_loadmore_button_params.max_page = data.max_page;

                // change the button label back
                $('#misha_filters').find('button').text('Apply filter');

                // insert the posts to the container
                $('#responses').html(data.content);

                // hide load more button, if there are not enough posts for the second page
                if ( data.max_page < 2 ) {
                    $('#misha_loadmore').hide();
                } else {
                    $('#misha_loadmore').show();
                }
            }
        });

        // do not submit the form
        return false;

    });

});

1 个答案:

答案 0 :(得分:1)

由于要将模板的输出分配给变量$content,因此需要在过滤器函数的else分支中使用输出缓冲。就像您在if分支中所做的一样。其余部分看起来像这样:

else :
    ob_start(); // start the buffer to capture the output of the template
    get_template_part( 'template-parts/content', 'none' );
    $content = ob_get_contents(); // pass the output to variable
    ob_end_clean(); // clear the buffer

与您当前问题无关的警告。您不应使用unserialize的方式。这是非常不安全的。 manual中有一个红色警告,通过搜索PHP对象注入,您可以轻松找到其危险性的解释。

帮个忙,并使用json_encode/decode。因为query_vars是一个简单的数组,所以不会有什么区别。