I want to create a load more function using ajax for a post category. I've followed this article on how to proceed, but after I add the function to register the endpoint, it will give me a 404 error about the second page that didn't exists.
Is there any error in the code or another way without using plugins to implement this in WP? (I'm an experienced PHP developer but I don't use wordpress a lot and it's all new for me for some aspects).
functions.php
<?php
add_action('rest_api_init', 'portfolio_ajax_api');
function portfolio_ajax_api(){
register_rest_route( 'portfolio', '/all-posts', array(
'methods' => 'GET',
'callback' => 'get_portfolio'
));
}
function get_showcase($request){
$posts_data = array();
$paged = $request->get_param('page');
$paged = (isset($paged) || !(empty($paged))) ? $paged : 1;
$posts = get_posts( array(
'post_type' => 'post',
'status' => 'published',
'posts_per_page' => 9,
'orderby' => 'post_date',
'order' => 'DESC',
'paged' => $paged
));
foreach($posts as $post){
$id = $post->ID;
$post_thumbnail = (has_post_thumbnail($id)) ? get_the_post_thumbnail_url($id) : null;
$post_cat = get_the_category($id);
$featured = (get_field('project_featured', $id)) ? true : false;
$posts_data[] = (object)array(
'id' => $id,
'slug' => $post->post_name,
'type' => $post->post_type,
'title' => $post->post_title,
'featured_img_src' => $post_thumbnail,
'featured' => $featured,
'category' => $post_cat[0]->cat_name
);
}
return $posts_data;
}
?>
template file:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$portfolio = new WP_Query(array(
'post_type' => 'post',
'status' => 'published',
'category_name' => 'portfolio',
'posts_per_page'=> 1,
'orderby' => 'post_date',
'order' => 'DESC',
'paged' => $paged
));
?>
<div class="card-columns">
<?php if( $portfolio->have_posts() ): while( $portfolio->have_posts() ): $portfolio->the_post(); ?>
<div class="card hide">
<a href="<?php the_permalink(); ?>">
<img class="card-img-top w-100" src="<?php the_post_thumbnail_url('full'); ?>" id="case-studies">
<div class="overlay"><h4 class="text-center" id="client-name"><?php the_title(); ?></h4></div>
</a>
</div>
<?php endwhile; ?>
<?php endif; wp_reset_postdata(); ?>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 text-center" id="show-more">
<button class="btn btn-outline-dark" id="load-more"><?php _e('Visualizza altro') ?></button>
</div>
</div>
main.js
$('#load-more').on('click', function(e){
e.preventDefault();
var pull_page = 1;
var jsonFlag = true;
if(jsonFlag){
pull_page++;
$.getJSON("/u/wp-json/portfolio/all-posts?page=" + pull_page, function(data){
if(data.length){
pull_page++;
console.log(data.length);
$.each(data, function(i, item){
var html = '<div class="card">';
html += '<a href="'+ item.permalink +'">';
html += '<img class="card-img-top w-100" src="'+ item.featured_img_src +'" id="case-studies" />';
html += '<div class="overlay"><h4 class="text-center" id="client-name">'+ item.title +'</h4></div>';
html += '</a>';
html += '</div>';
$('body').find('.card-columns')
.append(html);
});
}
else{
jsonFlag = false;
}
}).done(function(data){
if(data.length >= 4){
jsonFlag = true;
}
else{
jsonFlag = false;
}
});
}
}); // end load more
EDIT:
I've solved the issue about the 404 error, It was due to the fact that wordpress is installed inside a subfolder of my local development server, so I've changed the url to match the correct route.
Now the problem is that I need to display all posts with the $.each()
loop inside a bootstrap card and I can't figure out how to proceed correctly. this because the html code for my cards is using the php wordpress loop generated by the wp_query on page load.
I want to create a load more function using ajax for a post category. I've followed this article on how to proceed, but after I add the function to register the endpoint, it will give me a 404 error about the second page that didn't exists.
Is there any error in the code or another way without using plugins to implement this in WP? (I'm an experienced PHP developer but I don't use wordpress a lot and it's all new for me for some aspects).
functions.php
<?php
add_action('rest_api_init', 'portfolio_ajax_api');
function portfolio_ajax_api(){
register_rest_route( 'portfolio', '/all-posts', array(
'methods' => 'GET',
'callback' => 'get_portfolio'
));
}
function get_showcase($request){
$posts_data = array();
$paged = $request->get_param('page');
$paged = (isset($paged) || !(empty($paged))) ? $paged : 1;
$posts = get_posts( array(
'post_type' => 'post',
'status' => 'published',
'posts_per_page' => 9,
'orderby' => 'post_date',
'order' => 'DESC',
'paged' => $paged
));
foreach($posts as $post){
$id = $post->ID;
$post_thumbnail = (has_post_thumbnail($id)) ? get_the_post_thumbnail_url($id) : null;
$post_cat = get_the_category($id);
$featured = (get_field('project_featured', $id)) ? true : false;
$posts_data[] = (object)array(
'id' => $id,
'slug' => $post->post_name,
'type' => $post->post_type,
'title' => $post->post_title,
'featured_img_src' => $post_thumbnail,
'featured' => $featured,
'category' => $post_cat[0]->cat_name
);
}
return $posts_data;
}
?>
template file:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$portfolio = new WP_Query(array(
'post_type' => 'post',
'status' => 'published',
'category_name' => 'portfolio',
'posts_per_page'=> 1,
'orderby' => 'post_date',
'order' => 'DESC',
'paged' => $paged
));
?>
<div class="card-columns">
<?php if( $portfolio->have_posts() ): while( $portfolio->have_posts() ): $portfolio->the_post(); ?>
<div class="card hide">
<a href="<?php the_permalink(); ?>">
<img class="card-img-top w-100" src="<?php the_post_thumbnail_url('full'); ?>" id="case-studies">
<div class="overlay"><h4 class="text-center" id="client-name"><?php the_title(); ?></h4></div>
</a>
</div>
<?php endwhile; ?>
<?php endif; wp_reset_postdata(); ?>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 text-center" id="show-more">
<button class="btn btn-outline-dark" id="load-more"><?php _e('Visualizza altro') ?></button>
</div>
</div>
main.js
$('#load-more').on('click', function(e){
e.preventDefault();
var pull_page = 1;
var jsonFlag = true;
if(jsonFlag){
pull_page++;
$.getJSON("/u/wp-json/portfolio/all-posts?page=" + pull_page, function(data){
if(data.length){
pull_page++;
console.log(data.length);
$.each(data, function(i, item){
var html = '<div class="card">';
html += '<a href="'+ item.permalink +'">';
html += '<img class="card-img-top w-100" src="'+ item.featured_img_src +'" id="case-studies" />';
html += '<div class="overlay"><h4 class="text-center" id="client-name">'+ item.title +'</h4></div>';
html += '</a>';
html += '</div>';
$('body').find('.card-columns')
.append(html);
});
}
else{
jsonFlag = false;
}
}).done(function(data){
if(data.length >= 4){
jsonFlag = true;
}
else{
jsonFlag = false;
}
});
}
}); // end load more
EDIT:
I've solved the issue about the 404 error, It was due to the fact that wordpress is installed inside a subfolder of my local development server, so I've changed the url to match the correct route.
Now the problem is that I need to display all posts with the $.each()
loop inside a bootstrap card and I can't figure out how to proceed correctly. this because the html code for my cards is using the php wordpress loop generated by the wp_query on page load.
I've solved the problem, I was made a mistake with the variable pull_page
that is inside the click event. I've moved the variable outside the event and now all works fine. Here is the updated code!
var pull_page = 1;
var jsonFlag = true;
$('#load-more').on('click', function(e){
e.preventDefault();
if(jsonFlag){
pull_page++;
$.getJSON("/u/wp-json/portfolio/all-posts?page=" + pull_page, function(data){
if(data.length){
pull_page++;
console.log(data.length);
$.each(data, function(i, item){
var html = '<div class="card">';
html += '<a href="'+ item.permalink +'">';
html += '<img class="card-img-top w-100" src="'+ item.featured_img_src +'" id="case-studies" />';
html += '<div class="overlay"><h4 class="text-center" id="client-name">'+ item.title +'</h4></div>';
html += '</a>';
html += '</div>';
$('body').find('.card-columns')
.append(html);
});
}
else{
jsonFlag = false;
}
}).done(function(data){
if(data.length >= 4){
jsonFlag = true;
}
else{
jsonFlag = false;
}
});
}
}); // end load more
$request->get_param('page')
is not set properly? put it in your return and check, if its correct / hardcode another value just for testing.. – honk31 Commented Feb 18, 2019 at 17:50getJSON()
was wrong. The problem now I need to fix is how to show inside my bootstrap cards the json response. I want to use the$.each()
function but with no success! – ZWPDev Commented Feb 18, 2019 at 17:54