This is all the code to also add “load more” functionality:
/*
Widget name : Filtering (accommodation)
Parameters : 'cpt'
Function : filtering()
*/
function filtering($filtering){
$taxon = get_object_taxonomies($filtering['cpt']);
$terms = get_terms($taxon[0]);
$accs = new WP_Query([
'post_type' => $filtering['cpt'],
'posts_per_page' => 6,
'order_by' => 'date',
'order' => 'desc',
'tax_query' => array(
array(
'taxonomy' => $taxon[0],
'field' => 'slug',
'operator' => 'EXISTS'
)
)
]);
$found = $accs->found_posts;
?>
<div class="filtering x-9">
<div class="filtering-cpt">
<a class="filtering-cpt-sin active" href="#!" data-load="<?php echo $found; ?>" data-type="<?php echo $filtering['cpt']; ?>" data-slug=""><?php _e('All','xlate'); ?></a>
<?php foreach($terms as $term) : ?>
<a class="filtering-cpt-sin" href="#!" data-load="<?php echo $term->count; ?>" data-type="<?php echo $filtering['cpt']; ?>" data-slug="<?php echo $term->slug; ?>"><?php echo $term->name; ?></a>
<?php endforeach; ?>
</div>
<?php
if ($accs->have_posts()): ?>
<div class="filtering-res x-9">
<?php while($accs->have_posts()) : $accs->the_post(); ?>
<div class="filtering-res-sin x-3">
<div class="filtering-res-sin-top">
<?php
$image_data = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), "large" );
$get_map_link = get_post_custom_values($key = 'map');
?>
<img src="<?php echo $image_data[0]; ?>" width="<?php echo $image_data[1]; ?>" height="<?php echo $image_data[2]; ?>" alt="<?php echo get_the_title(); ?>" />
</div>
<div class="filtering-res-sin-bot darkbg cropit xx-anim">
<div class="filtering-res-sin-bot-tit"><?php echo get_the_title(); ?></div>
<div class="filtering-res-sin-bot-bar"></div>
<div class="filtering-res-sin-bot-tog">Contact information <img src="https://lgkm.aero/wp-content/uploads/2022/11/load-more-plus-white-14x14-1-1.svg" width="12" height="12" alt="+" /></div>
<div class="filtering-res-sin-bot-con"><?php echo get_the_content(); ?></div>
<a class="filtering-res-sin-bot-but" href="<?php echo (($get_map_link != '') ? $get_map_link[0] : ''); ?>"><img src="https://lgkm.aero/wp-content/uploads/2022/11/find-on-map-white-26x34-1.svg" width="26" height="34" alt="|" /> Find on map</a>
</div>
</div>
<?php endwhile; ?>
</div>
<div class="filtering-load x-12" data-load="<?php echo $found; ?>" data-type="<?php echo $filtering['cpt']; ?>" data-slug="">Load more <img src="https://lgkm.aero/wp-content/uploads/2022/11/shop-plus-20x20-1.svg" width="14" height="14" alt="+" /></div>
<?php wp_reset_postdata();
endif; ?>
</div>
<?php }
function filtering_ajax() {
$catCpt = $_POST['type'];
$terms = get_object_taxonomies($catCpt);
$catSlug = $_POST['category'];
if ($catSlug){
$ajaxposts = new WP_Query([
'post_type' => $catCpt,
'posts_per_page' => 3,
'orderby' => 'date',
'order' => 'desc',
'tax_query' => array(
array(
'taxonomy' => $terms[0],
'field' => 'slug',
'terms' => $catSlug,
)
)
]);
} else {
$ajaxposts = new WP_Query([
'post_type' => $catCpt,
'posts_per_page' => 3,
'orderby' => 'date',
'order' => 'desc',
'tax_query' => array(
array(
'taxonomy' => $terms[0],
'field' => 'slug',
'operator' => 'EXISTS'
)
)
]);
}
$found = $ajaxposts->found_posts;
$response="";
if($ajaxposts->have_posts()) {
while($ajaxposts->have_posts()) : $ajaxposts->the_post();
$image_data = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), "large" );
$get_map_link = get_post_custom_values($key = 'map');
$response .= '
<div class="filtering-res-sin x-3">
<div class="filtering-res-sin-top">
<img src="' . $image_data[0] . '" width="' . $image_data[1] . '" height="' . $image_data[2] . '" alt="' . get_the_title() . '" />
</div>
<div class="filtering-res-sin-bot darkbg cropit vsb xx-anim">
<div class="filtering-res-sin-bot-tit">' . get_the_title() . '</div>
<div class="filtering-res-sin-bot-bar"></div>
<div class="filtering-res-sin-bot-tog">Contact information <img src="https://lgkm.aero/wp-content/uploads/2022/11/load-more-plus-white-14x14-1-1.svg" width="12" height="12" alt="+" /></div>
<div class="filtering-res-sin-bot-con">' . get_the_content() . '</div>
<a class="filtering-res-sin-bot-but" href="' . (($get_map_link != '') ? $get_map_link[0] : '') . '"><img src="https://lgkm.aero/wp-content/uploads/2022/11/find-on-map-white-26x34-1.svg" width="26" height="34" alt="|" /> Find on map</a>
</div>
</div>';
endwhile;
} else {
$response="";
}
echo $response;
exit;
}
add_action('wp_ajax_filtering_ajax', 'filtering_ajax');
add_action('wp_ajax_nopriv_filtering_ajax', 'filtering_ajax');
function filtering_ajax_load() {
$catCpt = $_POST['type'];
$terms = get_object_taxonomies($catCpt);
$catOff = $_POST['offset'];
$catSlug = $_POST['category'];
if ($catSlug){
$ajaxposts = new WP_Query([
'post_type' => $catCpt,
'posts_per_page' => 3,
'offset' => $catOff,
'orderby' => 'date',
'paged' => 1,
'order' => 'desc',
'tax_query' => array(
array(
'taxonomy' => $terms[0],
'field' => 'slug',
'terms' => $catSlug,
)
)
]);
} else {
$ajaxposts = new WP_Query([
'post_type' => $catCpt,
'posts_per_page' => 3,
'offset' => $catOff,
'orderby' => 'date',
'paged' => 1,
'order' => 'desc',
'tax_query' => array(
array(
'taxonomy' => $terms[0],
'field' => 'slug',
'operator' => 'EXISTS'
)
)
]);
}
$response="";
if($ajaxposts->have_posts()) {
while($ajaxposts->have_posts()) : $ajaxposts->the_post();
$image_data = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), "large" );
$get_map_link = get_post_custom_values($key = 'map');
$response .= '
<div class="filtering-res-sin x-3">
<div class="filtering-res-sin-top">
<img src="' . $image_data[0] . '" width="' . $image_data[1] . '" height="' . $image_data[2] . '" alt="' . get_the_title() . '" />
</div>
<div class="filtering-res-sin-bot darkbg cropit vsb xx-anim">
<div class="filtering-res-sin-bot-tit">' . get_the_title() . '</div>
<div class="filtering-res-sin-bot-bar"></div>
<div class="filtering-res-sin-bot-tog">Contact information <img src="https://lgkm.aero/wp-content/uploads/2022/11/load-more-plus-white-14x14-1-1.svg" width="12" height="12" alt="+" /></div>
<div class="filtering-res-sin-bot-con">' . get_the_content() . '</div>
<a class="filtering-res-sin-bot-but" href="' . (($get_map_link != '') ? $get_map_link[0] : '') . '"><img src="https://lgkm.aero/wp-content/uploads/2022/11/find-on-map-white-26x34-1.svg" width="26" height="34" alt="|" /> Find on map</a>
</div>
</div>';
endwhile;
} else {
$response=""; ?>
<?php }
echo $response;
exit;
}
add_action('wp_ajax_filtering_ajax_load', 'filtering_ajax_load');
add_action('wp_ajax_nopriv_filtering_ajax_load', 'filtering_ajax_load');
Then the JS part:
<script>
jQuery('.filtering .filtering-cpt-sin').on('click', function() {
jQuery('.filtering .filtering-cpt-sin').removeClass('active');
jQuery('.filtering-load').removeClass('dis');
jQuery(this).addClass('active');
jQuery('.filtering-load').attr('data-type',jQuery(this).attr('data-type'));
jQuery('.filtering-load').attr('data-slug',jQuery(this).attr('data-slug'));
jQuery('.filtering-load').attr('data-load',jQuery(this).attr('data-load'));
jQuery.ajax({
type: 'POST',
url: '/wp-admin/admin-ajax.php',
dataType: 'html',
data: {
type: jQuery(this).attr('data-type'),
offset: 0,
action: 'filtering_ajax',
category: jQuery(this).attr('data-slug')
},
success: function(res) {
jQuery('.filtering .filtering-res').html(res);
}
})
});
jQuery('.filtering .filtering-load').on('click', function() {
jQuery.ajax({
type: 'POST',
url: '/wp-admin/admin-ajax.php',
dataType: 'html',
data: {
type: jQuery(this).attr('data-type'),
offset: jQuery('.filtering-res-sin').length,
action: 'filtering_ajax_load',
category: jQuery(this).attr('data-slug')
},
success: function(res) {
jQuery('.filtering .filtering-res').append(res);
if (jQuery('.filtering-res-sin').length >= jQuery('.filtering-load').attr('data-load')){
jQuery('.filtering-load').addClass('dis');
}
}
})
});
</script>
Some CSS to make it pretty:
.filtering {display: flex;justify-content: center;flex-direction: column;align-items: center;gap: 50px 0;margin-right: auto;margin-left: calc( var(--grid) + var(--gutter) );}
.filtering-cpt {display: flex;gap: 0 20px;}
.filtering-cpt a {font-family: Averta;font-size: 21px;font-weight: 600;line-height: 20px;color:#979797;transition:color .3s;}
.filtering-cpt a.active {color:#000;}
.filtering-res {display: flex;flex-wrap: wrap;gap: calc(var(--gutter) * 2);counter-reset:count;}
.filtering-res-sin {display: flex;flex-direction: column;color:#fff;counter-increment:count;}
.filtering-res-sin a {color:#fff;}
.filtering-res-sin-top {display: flex;flex-direction: column;}
.filtering-res-sin-top img {aspect-ratio: 4/3;object-fit: cover;object-position: center;}
.filtering-res-sin-bot {padding: 42px 50px 42px 60px;display: flex;flex-direction: column;gap: 17px;position:relative}
.filtering-res-sin-bot::after {content:counter(count, decimal-leading-zero);position:absolute;left:20px;top:25px;color:#fff;font-family: Roboto;font-size: 15px;font-weight: 400;line-height: 21px;}
.filtering-res-sin-bot-tit {font-family: Averta;font-size: 24px;font-weight: 600;line-height: 29px;}
.filtering-res-sin-bot-bar {background-color:#474B56;width:100%;height:1px;}
.filtering-res-sin-bot-tog {font-family: Averta;font-size: 17px;font-weight: 600;line-height: 20px;display:flex;align-items:center;gap:0 7px;}
.filtering-res-sin-bot-but {font-family: Averta;font-size: 20px;font-weight: 600;line-height: 24px;display:flex;align-items:center;gap:0 13px;}
.filtering-load {display:flex;justify-content:center;gap:0 7px;cursor:pointer;font-family: Averta;font-size: 21px;font-weight: 600;line-height: 20px;}
.filtering-load.dis {opacity:0.4;cursor:not-allowed;}
And finally call the one function that does the trick:
$filtering = array('cpt' => 'accommodation');
filtering($filtering);
Just change the accommodation
to your own custom post type.