Wordpress - Load more posts with AJAX & exclude posts - php

I made a "load more" button to my website, following this awesome tutorial.
Everything works fine, but in the homepage i have 3 different loops (1 sticky post, 3 evidence) and the load more starts from post #5.
In the main loops, I have excluded the already-showed posts with the IDs and "post__not_in" and everything works fine.
The problem is when I call the load more, the loop starts from post 1. If I set to start from page 2 I have a duplicate post (that's because I have to load post in multiple of 3).
I'have tried to get the IDs list in my loadmore file with GLOBALS, but it seems not working :(
How can I pass my main loop variable to the load more query?
This is my main loop:
<?php
$myquery = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 3,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'post__not_in' => $ids
]); if($myquery->have_posts()): ?>
<div class="articles-container append-posts">
<?php
while($myquery->have_posts()) : $myquery->the_post();
$ids[] = get_the_ID(); ?>
<?php get_template_part( 'template-parts/loop', 'posts' ); ?>
<?php endwhile; ?>
</div>
This is the load-more file:
function misha_loadmore_ajax_handler(){
// prepare our arguments for the query
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // we need next page to be loaded
$args['post_status'] = 'publish';
$args['post_type'] = 'post';
$args['post_per_page'] = 3;
$args['orderby'] = 'date';
$args['order'] = 'DESC';
// it is always better to use WP_Query but not here
query_posts( $args );
if( have_posts() ) :
// run the loop
while( have_posts() ): the_post();
// look into your theme code how the posts are inserted, but you can use your own HTML of course
// do you remember? - my example is adapted for Twenty Seventeen theme
get_template_part( 'template-parts/loop', 'posts' );
// for the test purposes comment the line above and uncomment the below one
// the_title();
endwhile;
endif;
die; // here we exit the script and even no wp_reset_query() required! }

Related

How to move all the posts to move to trash

I'm facing the issue in route change by click the apply button, while selecting the move to trash.
NOTE: move to trash and apply process is working by selecting some posts. Bulkly, I trying to move to trash is facing the issue.
url : https://abcd.com/blog/probs/wp-admin/edit.php
After selecting move to trash without selecting any posts and click the apply button url changes to
Incase of delete all posts, I got a route like this
changed url : https://abcd.com/probs//wp-admin/edit.php?paged=1
For this you can try it programmatically by creating your code.
for trashing all the post you try this code:
function move_all_posts_to_trash() {
$args = array(
'post_type' => 'post', // Change this to the post type you want to move to trash
'posts_per_page' => -1, // Get all posts
'post_status' => 'publish' // Only get posts that are published
);
$posts = get_posts( $args );
foreach ( $posts as $post ) {
wp_trash_post( $post->ID ); // Move post to trash
}
}
// If you want to move single post or page you can used by default wordpress function
Basic Example
Trash the default WordPress Post, “Hello World,” which has an ID of ‘1’.
<?php wp_trash_post( $post_id = 1 ); ?>
// For Multiple Posts using WP_Query using while loop.
You can used as per requirement like create shortcode or fire hooks.
function trash_custom_posts() {
$args = array (
'post_type' => 'custom_post_type_slug',
'post_status' => 'publish',
'posts_per_page' => -1
);
$query = new WP_Query( $args );
while( $query->have_posts() ) {
$query->the_post();
$post_id = get_the_ID();
wp_trash_post( $post_id );
}
wp_reset_postdata();
}
add_action( 'init', 'trash_custom_posts' );

How to fix Wordpress pagination (page not found after 8th page)

I am having trouble with Wordpress pagination. I have a custom archive page displaying custom post types from the specific category. I want to use pagination and display 12 posts per page. My problem is that pagination works correctly but only up to the 8th page. After that I am being presented with "Page not found".
I am using theme built-in function to display page navigation (1, 2... 10, 11). It correctly shows 11 pages in total, but they seem not to work after the 8th page.
$taxonomy = 'product_cat';
$term_id = get_queried_object()->term_id;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'product',
'paged' => $paged,
'posts_per_page' => '12',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $term_id
)
)
);
<?php $wp_query = new WP_query( $args ); ?>
<?php if( $wp_query->have_posts() ): ?>
<?php while( $wp_query->have_posts() ): ?>
<?php $wp_query->the_post(); ?>
//post content
<?php endwhile; ?>
<?php endif; ?>
<?php s7upf_paging_nav();?>
<?php wp_reset_postdata(); ?>
#edit
When I go to a different category page which should have 12 pages they work correctly up to the 9th page.
If I go to the one that has 2 pages, only the first one works.
I tried updaing permalinks. Setting posts per page to 12 in wordpress settings.
When i change posts per page in my query args to -1 it correctly shows all the posts on one page.
When manually setting the number of a page to display ('paged' => '11') it also displays correct page with correct posts.
You are using the wrong query. On page you are creating your own query instead of the actual query the page already did.
This will also be better for performance.
Step 1. Check what is in the normal query.
At the top of taxonomy-product_cat.php
global $wp_query;
var_dump( $wp_query->query_vars );
That probably fits mostly.
Step 2. Do the normal loop
Remove all your query stuff (maybe keep a backup of the $args for the next step)
example: Replace
<?php if( $wp_query->have_posts() ): ?>
with
<?php if( have_posts() ): ?>
And so on.
Step 3. Edit the main query
We are going to use the hook pre_get_posts
add_action('pre_get_posts', 'so_53315648');
function so_53315648( WP_Query $wp_query ){
// only check this on the main query
if (! $wp_query->is_main_query() ){
return;
}
// only check this on the product_cat taxonomy
if ( ! $wp_query->is_tax('product_cat')) {
return;
}
// maybe do some more checks?
$wp_query->query_vars['posts_per_page'] = 12;
// Is this really needed??
//$wp_query->query_vars['posts_type'] = 'product';
// tweak the query the way you like.
}
As you can see $wp_query->query_vars should pretty much be the same $args. But do not overwrite it. This might break other stuff.
Of course I could not test your specific site. But the answer should be inside the pre_get_posts hook. And tweaking the main query instead of doing a extra separate one.
Test, also check the var_dump of step 1 that your changes are coming through.
The checks at the top are to stop other pages from being affected, maybe you need more?
Let me know.

WooCommerce pagination + Ajax WP_Query

I have a custom Wordpress widget which allows the user to filter products via attributes (custom taxonomies).
It all happens via an Ajax call, but I'm having trouble keeping the pagination up to date based on the filtered results.
For example:
If the page loads 30 products, 10 to a page = 3 pages of results.
The user then filters by an attribute which reduces that 30 products to 20. I need the pagination to change to just 2 pages of results.
Here's a sample of the WP_Query that replaces the default page content. You can see the woocommerce_pagination() which doesn't appear to work in this environment.
// Args
$args = array(
'post_type' => 'product',
'posts_per_page' => 10,
'orderby' => 'name',
'order' => 'ASC',
'tax_query' => $tax_query
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
woocommerce_product_loop_start();
while( $query->have_posts() ): $query->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
woocommerce_product_loop_end();
// TODO - get pagination working
woocommerce_pagination();
wp_reset_postdata();
else :
echo '<p>No products found</p>';
endif;
WooCommerce pagination works based on global $wp_query variable. But you are using your own $query variable. That's why it is obvious why it is not working.
You have 2 ways to go:
First is using query_posts instead of WP_QUERY class.
The second way is a small hack, where you can cheat $wp_query pagination argument.
Here it is:
global $wp_query;
$wp_query->max_num_pages=$query->max_num_pages;
// TODO - get pagination working
woocommerce_pagination();

wordpress query_posts alternative

I am creating a website that integrates a portfolio which uses custom post types, this was done based off of this tutorial.
So far it is exactly what I am looking for and works great except for one small detail. In order to fetch the posts from the new custom post type the author of the tutorial used the query_posts() codex. So the top of my portfolio page looks like this:
<?php
/* Template Name: Portfolio */
get_header();
query_posts('post_type=portfolio&posts_per_page=10');
?>
What I gather is that this declares "get posts from "post type" portfolio and show 10 per page". My problem is that I can't go get content from my portfolio page. It seems that now my portfolio page only fetches the content from the custom post type, and I can't use:
<?php while ( have_posts() ) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; // end of the loop. ?>
to get content from the actual page.
This is what I am trying to do, I've replaced:
query_posts('post_type=portfolio&posts_per_page=10');
with:
add_action( 'pre_get_posts', 'add_my_post_types_to_query' );
function add_my_post_types_to_query( $query ) {
if ( is_page( 8 ) && $query->is_main_query() )
$query->set( 'post_type', array( 'portfolio' ) );
return $query;
}
This seems like the right track, but it stills doesn't work. I'm not getting the posts from my custom post type.
Any ideas how I could modify this? I am also still learning so being clear with explanations would be greatly appreciated.
Thank you!
Editing the pre_get_posts will replace the original query and you will not have the content for your page at all. I would only recommend going this approach if you only wanted to display the content of your portfolio post type and not the content of your portfolio page.
For general post queries it is recommended to use WP_Query or get_posts.
http://codex.wordpress.org/Class_Reference/WP_Query
http://codex.wordpress.org/Template_Tags/get_posts
If you use the WP_Query function the wp_reset_postdata() will restore the post data back to the original so you can get the content of your original page.
$args = array(
'posts_per_page' => 10,
'post_type' => 'portfolio',
);
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
} else {
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
Now you will be able to use the original loop to show the content of your page
<?php while ( have_posts() ) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; // end of the loop. ?>
Usually, I stick my query posts in a variable, like so:
$catid = get_cat_ID('My Category Name');
$args = array(
'posts_per_page' => 5,
'orderby' => 'post_date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
'category' => $catid
);
$posts_array = get_posts($args);
Then you can loop it like so:
<?php foreach ($posts_array as $post) : setup_postdata($post);?>
<h1><?php the_title(); ?></h1>
<p><?php the_content(); ?></p>
<?php endforeach; ?>
Finally, to access your page content you can use the variable $post, it's automatically set by wordpress. No need to add any more code than this to access your page content.
<?php foreach( $posts as $post ) : setup_postdata($post); ?>
<h1><?php the_title(); ?></h1>
<p><?php the_content(); ?></p>
<?php endforeach; ?>
The foreach loop for your page content is a little overkill, and there is a better way to do it (most likely at least), but I haven't been bothered to look into it further yet! It works though!

Custom post type archive, more pages don't work

I have a site on which a lot of video's will be posted next week. The videos are posted with a custom post type, with just 'to', 'from' and yt video id. I wan to load a lot the videos on an archieve page, but not more than x per page. So x posts on page 1, x on page 2 and so on. Unfortunately, the page number doesn't show up, the 'p' container just stays empty. Here is my code:
$args = array( 'post_type' => 'video'/*, 'posts_per_page' => 3 */);
$loop = new WP_Query( $args );
if (have_posts()) :
while ( $loop->have_posts()) : $loop->the_post();
<?php endwhile; ?>
<p><?php posts_nav_link('∞','«« View newer posts','View older posts »»'); ?></p>
<?php endif; ?>
I have emptied the part between the while, because in that part I only call to basic functions like the_permalink and the_content.
As it turns out, using posts_nav_link in tandem with WP_Query doesn't work as expected, since posts_nav_link relies on the global $wp_query object, and doesn't recognize the custom WP_Query instance.
This Answer should provide you the details you need in order to get everything to work.
<?php
global $wp_query;
$temp_wp_query = $wp_query;
$wp_query = null;
$paged = get_query_var('paged');
$args = array(
'post_type' => 'video',
'paged' => $paged ? $paged : 1
/*, 'posts_per_page' => 3 */
);
$loop = new WP_Query( $args );
$wp_query = $loop;
if ($loop->have_posts()) :
while ( $loop->have_posts()) : $loop->the_post();
<?php endwhile; ?>
<p><?php posts_nav_link('∞','«« View newer posts','View older posts »»'); ?></p>
<?php
endif;
$wp_query = $temp_wp_query;
?>

Categories