Хорошо, я наконец-то нашел свое решение!
1-В своем проекте я сначала создаю страницу блога (с обычными публикациями в блоге) с фильтрами категорий и кнопкой ajax load more.
Вот код в моем доме. php
<?php
/**
* The main template file
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no home.php file exists.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package mysite
*/
get_header();
?>
<div id="primary" class="content-area">
<main id="main" class="site-main">
<div class="flex-container">
<div class="flex-row">
<header class="page-header">
<?php
single_post_title('<h1 class="page-title">', '</h1>' );
?>
</header><!-- .page-header -->
</div>
<div class="flex-row">
<form action="#" method="POST" id="post_filters">
<p><a href="" id="clear">Clear</a></p>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'category' ) ) ) :
foreach( $terms as $term ) :
echo '<p><input type="radio" id="' . $term->term_id . '" value="' . $term->term_id . '" name="category_filters" class="category_filter"/><label for="' . $term->term_id. '">' . $term->name . '</label></p>';
endforeach;
endif;
?>
<!-- required hidden field for admin-ajax.php -->
<input type="hidden" name="action" value="ccfilter" />
</form>
</div>
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 5,
'paged' => $paged
);
$query = new WP_Query( $args ); ?>
<?php
if ( $query->have_posts() ) :
$count = (int)0;?>
<div id="cc_posts_wrap" class="flex-row">
<?php
while ( $query->have_posts() ) : $count++;
$query->the_post();
if($count == 1){
$span = 'flex-col-xs-12';
$limit = 20;
}
if($count == 2 || $count == 3){
$span = 'flex-col-sm-6';
$limit = 13;
}
if($count > 3){
$span = 'flex-col-sm-4';
$limit = 13;
}
//If its not 3 or higher, increase the count
$termsArray = get_the_terms($post->ID, "category"); //Get the terms for this particular item
$termsString =""; //initialize the string that will contain the terms
foreach ( $termsArray as $term ) { // for each term
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString .' ' . $span ;?> item">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="post-featured-thumbnail">
<?php
if ( has_post_thumbnail() ) {
if($count == 1){
the_post_thumbnail('blog_featured');
}else{
the_post_thumbnail();
}
}
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
category_sticker();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</div>
<div class="post-content">
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
endif;
?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php echo excerpt($limit); ?>
</div><!-- .entry-content -->
</div>
</article><!-- #post-<?php the_ID(); ?> -->
</div>
<?php endwhile;
?>
</div> <!-- end isotope-list -->
<?php global $wp_query; // you can remove this line if everything works for you
if ( $wp_query->max_num_pages > 1 ) :
echo '<div id="cc_loadmore">More posts</div>'; // you can use <a> as well
endif;
else :
get_template_part( 'template-parts/content', 'none' );
endif;
?>
</div>
</main><!-- #main -->
</div><!-- #primary -->
<?php
get_footer();
Затем в функции php, код кнопки «Загрузить еще» и фильтры функции:
/*FUNCTION FILTER AND AJAX LOAD MORE*/
add_action( 'wp_enqueue_scripts', 'cc_script_and_styles');
function cc_script_and_styles() {
if ( is_home() ) {
global $wp_query;
wp_register_script( 'cc_scripts', get_stylesheet_directory_uri() . '/js/script.js', array('jquery') );
wp_localize_script( 'cc_scripts', 'cc_loadmore_params', array(
'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $wp_query->query_vars ), // everything about your loop is here
'current_page' => $wp_query->query_vars['paged'] ? $wp_query->query_vars['paged'] : 1,
'max_page' => $wp_query->max_num_pages
) );
wp_enqueue_script( 'cc_scripts' );
}
}
add_action('wp_ajax_loadmorebutton', 'cc_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmorebutton', 'cc_loadmore_ajax_handler');
function cc_loadmore_ajax_handler(){
$params = json_decode( stripslashes( $_POST['query'] ), true );
$params['paged'] = $_POST['page'] + 1;
$params['post_status'] = 'publish';
query_posts( $params );
if( have_posts() ) :
while( have_posts() ): the_post();
$termsArray = get_the_terms($post->ID, "category");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString ;?> flex-col-sm-4 item">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="post-featured-thumbnail">
<?php
if ( has_post_thumbnail() ) {
if($count == 1){
the_post_thumbnail('blog_featured');
}else{
the_post_thumbnail();
}
}
;
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
category_sticker();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</div>
<div class="post-content">
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
endif;
?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php echo excerpt($limit); ?>
</div><!-- .entry-content -->
</div>
</article><!-- #post-<?php the_ID(); ?> -->
</div>
<?php
endwhile;
endif;
die;
}
add_action('wp_ajax_ccfilter', 'cc_filter_function');
add_action('wp_ajax_nopriv_ccfilter', 'cc_filter_function');
function cc_filter_function(){
if( isset( $_POST['category_filters'] ) )
$args['tax_query'] = array(
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => $_POST['category_filters'],
"posts_per_page" => 5
)
);
query_posts( $args );
global $wp_query;
if( have_posts() ) : $count = (int)0;
ob_start();
while( have_posts() ): $count++;
the_post();
if($count == 1){
$span = 'flex-col-xs-12';
$limit = 20;
}
if($count == 2 || $count == 3){
$span = 'flex-col-sm-6';
$limit = 13;
}
if($count > 3){
$span = 'flex-col-sm-4';
$limit = 13;
}
$termsArray = get_the_terms($post->ID, "category");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString .' ' . $span ;?> item">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="post-featured-thumbnail">
<?php
if ( has_post_thumbnail() ) {
if($count == 1){
the_post_thumbnail('blog_featured');
}else{
the_post_thumbnail();
}
}
;
if ( 'post' === get_post_type() ) :
?>
<div class="entry-meta">
<?php
category_sticker();
?>
</div><!-- .entry-meta -->
<?php endif; ?>
</div>
<div class="post-content">
<header class="entry-header">
<?php
if ( is_singular() ) :
the_title( '<h1 class="entry-title">', '</h1>' );
else :
the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
endif;
?>
</header><!-- .entry-header -->
<div class="entry-content">
<?php echo excerpt($limit); ?>
</div><!-- .entry-content -->
</div>
</article><!-- #post-<?php the_ID(); ?> -->
</div>
<?php
endwhile;
$posts_html = ob_get_contents();
ob_end_clean();
else:
$posts_html = '<p>Nothing found for your criteria.</p>';
endif;
echo json_encode( array(
'posts' => json_encode( $wp_query->query_vars ),
'max_page' => $wp_query->max_num_pages,
'found_posts' => $wp_query->found_posts,
'content' => $posts_html
) );
die();
}
Затем в отдельном js файле функции для кнопки загрузки дополнительных функций и фильтров:
jQuery(function($){
/* LOAD MORE FUNCTION */
$('#cc_loadmore').click(function(){
$.ajax({
url : cc_loadmore_params.ajaxurl, // AJAX handler
data : {
'action': 'loadmorebutton', // the parameter for admin-ajax.php
'query': cc_loadmore_params.posts, // loop parameters passed by wp_localize_script()
'page' : cc_loadmore_params.current_page // current page
},
type : 'POST',
beforeSend : function ( xhr ) {
$('#cc_loadmore').text('Loading...'); // some type of preloader
},
success : function( posts ){
if( posts ) {
$('#cc_loadmore').text( 'More posts' );
$('#cc_posts_wrap').append( posts ); // insert new posts
cc_loadmore_params.current_page++;
if ( cc_loadmore_params.current_page == cc_loadmore_params.max_page )
$('#cc_loadmore').hide(); // if last page, HIDE the button
} else {
$('#cc_loadmore').hide(); // if no data, HIDE the button as well
}
}
});
return false;
});
/* FILTERING FUNCTION */
$('#post_filters').change(function(){
$.ajax({
url : cc_loadmore_params.ajaxurl,
data : $('#post_filters').serialize(), // form data
dataType : 'json', // this data type allows us to receive objects from the server
type : 'POST',
success : function( data ){
cc_loadmore_params.current_page = 1;
cc_loadmore_params.posts = data.posts;
cc_loadmore_params.max_page = data.max_page;
$('#cc_posts_wrap').html(data.content);
if ( data.max_page < 2 ) {
$('#cc_loadmore').hide();
} else {
$('#cc_loadmore').show();
}
}
});
return false;
}); });
Для сообщений в блоге , все готово и работает !
Пояснения:
Как вы можете видеть здесь, в функциях. php и функция cc_script_and_styles и - ' cc_loadmore_params ' используются повсеместно в файле js. Будьте внимательны, чтобы написать одну и ту же функцию во всех местах!
Действие вызова ajax в файле js, ' loadmorebutton ', является то же имя, что и в хуке ' wp_ajax_loadmorebutton ' в функциях. php
add_action ('wp_ajax_loadmorebutton', 'cc_loadmore_ajax_handler'); add_action ('wp_ajax_nopriv_loadmorebutton', 'cc_loadmore_ajax_handler');
Значение скрытого ввода в home. php: 'ccfilter' такое же, как в хуке функции cc_filter_function () {
и
add_action('wp_ajax_ccfilter', 'cc_filter_function');
add_action('wp_ajax_nopriv_ccfilter', 'cc_filter_function');
- Теперь мы также хотим добавить аналогичные фильтры и кнопку загрузки еще для пользовательский тип записи.
Вот мой архив пользовательских типов записей:
get_header();
?>
<div id="primary" class="content-area">
<main id="main" class="site-main">
<div class="flex-container">
<div class="flex-row">
<header class="page-header">
<?php
post_type_archive_title( '<h1 class="page-title">', '</h1>' );
?>
</header><!-- .page-header -->
</div>
<div class="flex-row">
<form action="#" method="POST" id="formation_filters">
<p><a href="" id="clear">Clear</a></p>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'categories-formations' ) ) ) :
foreach( $terms as $term ) :
echo '<p><input type="radio" id="' . $term->term_id . '" value="' . $term->term_id . '" name="category_formation_filters" class="category_formation_filters"/><label for="' . $term->term_id. '">' . $term->name . '</label></p>';
endforeach;
endif;
?>
<!-- required hidden field for admin-ajax.php -->
<input type="hidden" name="action" value="ccformationfilter" />
</form>
</div>
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'post_type' =>'formation',
'posts_per_page' =>5,
'paged' => $paged
);
$query = new WP_Query( $args );?>
<?php if ( $query->have_posts() ) : ?>
<div id="cc_formation_wrap" class="flex-row">
<?php while ( $query->have_posts() ) : $query->the_post();
$termsArray = get_the_terms( $post->ID, "categories-formations" );
$termsString = "";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug.' ';
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
} ;
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="entry-meta">
<?php if(get_field('duree')){
$duree = get_field_object('duree');
echo '<div><span class="isotope-duree">' . get_field('duree') . '</span></div>';
}
?>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
<a href="<?php esc_url( the_permalink() );?>" rel="bookmark">Voir</a>
</div>
</article>
</div> <!-- end item -->
<?php endwhile;
?>
</div> <!-- end isotope-list -->
<?php
if ( $query->max_num_pages > 1 ) :
echo '<div id="cc_formation_loadmore">More posts</div>';
endif;
else :
get_template_part( 'template-parts/content', 'none' );
endif; ?>
</div>
</main>
</div>
<script>
var posts_myajax = '<?php echo serialize( $query->query_vars ) ?>',
current_page_myajax = 1,
max_page_myajax = <?php echo $query->max_num_pages ?>
</script>
<script src="<?php bloginfo('template_url')?>/js/load-more.js"></script>
<?php get_footer();?>
Здесь мы создаем фильтры того же типа, мы только что изменили название таксономии и объявили параметр post_type. Мы делаем наш ajax вызов в нижней части файла с новыми именами переменных. И мы вызываем отдельный js файл load-more. js.
Для того, чтобы сохранить чистую структуру, я также создал отдельный файл с именем :formation-query. php. В функциях. php, я вызываю это с помощью:
require get_template_directory() . '/inc/formation-query.php';
Мы не дублируем функцию cc_script_and_styles () { Мы просто создаем две наши функции для загрузки больше и фильтров с новые имена переменных.
add_action('wp_ajax_loadmoreformationbutton', 'cc_formation_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmoreformationbutton', 'cc_formation_loadmore_ajax_handler');
function cc_formation_loadmore_ajax_handler(){
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1;
$args['post_status'] = 'publish';
$args["post_type"] = 'formation';
query_posts( $args );
global $wp_query;
if( have_posts() ) :
while( have_posts() ): the_post();
$termsArray = get_the_terms($post->ID, "categories-formations");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
} ;
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
<a href="<?php esc_url( get_permalink() );?>" rel="bookmark">Voir</a>
</div>
</article>
</div> <!-- end item -->
<?php
endwhile;
endif;
die;
}
add_action('wp_ajax_ccformationfilter', 'cc_formation_filter_function');
add_action('wp_ajax_nopriv_ccformationfilter', 'cc_formation_filter_function');
function cc_formation_filter_function(){
$args["post_type"] = 'formation';
$args['tax_query'] = array(
array(
'taxonomy' => 'categories-formations',
'field' => 'id',
'terms' => $_POST['category_formation_filters'],
"posts_per_page" => 5
)
);
$query = new WP_Query($args);
if( $query->have_posts() ) :
ob_start();
while( $query->have_posts() ): $query->the_post();
$termsArray = get_the_terms($post->ID, "categories-formations");
$termsString ="";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug;
}
?>
<div class="<?php echo $termsString;?> flex-col-md-4 item related-formation-post">
<article id="post-<?php the_ID(); ?>" <?php post_class();?>>
<div class="isotope-thumbnail">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('masonryLayout');
}
?>
</div>
<div class="isotope-title">
<h3><?php the_title(); ?></h3>
</div>
<div class="entry-meta">
<?php if(get_field('duree')){
$duree = get_field_object('duree');
echo '<div><span class="isotope-duree">' . get_field('duree') . '</span></div>';
}
?>
</div>
<div class="isotope-excerpt">
<?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?>
</div>
<div class="isotope-cta">
<a href="<?php esc_url( get_post_permalink($post->ID) );?>" rel="bookmark">Voir</a>
</div>
</article>
</div> <!-- end item -->
<?php
endwhile;
$posts_html = ob_get_contents();
ob_end_clean();
else:
$posts_html = '<p>Nothing found for your criteria.</p>';
endif;
echo json_encode( array(
'posts' => json_encode( $query->query_vars ),
'max_page' => $query->max_num_pages,
'found_posts' => $query->found_posts,
'content' => $posts_html
) );
die();
}
Теперь в отдельном файле load-more. js файл:
/* LOAD MORE FUNCTION ON FORMATION ARCHIVE PAGE */
$('#cc_formation_loadmore').click(function(){
data = {
'action': 'loadmoreformationbutton',
'query': posts_myajax,
'page' : current_page_myajax
};
$.ajax({
url : '/mysite/wp-admin/admin-ajax.php', // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
$('#cc_formation_loadmore').text('Loading...');
},
success : function( posts ){
if( posts ) {
$('#cc_formation_loadmore').text( 'More posts' );
$('#cc_formation_wrap').append( posts );
current_page_myajax++;
if ( current_page_myajax == max_page_myajax )
$('#cc_formation_loadmore').hide();
} else {
$('#cc_formation_loadmore').hide();
}
}
});
return false;
});
/* FILTERING FUNCTION ON FORMATION ARCHIVE PAGE */
$('#formation_filters').change(function(){
$.ajax({
url : '/mysite/wp-admin/admin-ajax.php',
data : $('#formation_filters').serialize(),
dataType : 'json',
type : 'POST',
success : function( data ){
current_page_myajax = 1;
posts_myajax = data.posts;
max_page_myajax = data.max_page;
$('#cc_formation_wrap').html(data.content);
if ( data.max_page < 2 ) {
$('#cc_formation_loadmore').hide();
} else {
$('#cc_formation_loadmore').show();
}
}
});
return false;
});
});
Как видите,
Теперь вы можете дублировать это, если вам нужно, чтобы другие загружали больше кнопок и фильтров для других пользовательских типов записей!
Мне потребовалось некоторое время, чтобы понять, что названия функций должны были быть одинаковым в каждом файле. Разные петли, конечно, также важны.