We have a page that is divided into two columns. Each column has a loop that fills the column with Posts from different categories.
What we want:
Column A - Shows posts with category X and Y
Column B – Shows posts with category X (Except posts that also have category Y)
The problem:
We’re not able to exclude from Column B the posts that are from category X but also Y – The idea is to show in column B post only with category X
From what we have researched we assume that we will have to customize the loop in column B but we don't know how to access it.
What are we missing here?
It's fairly easy to understand. When you define a new custom query (a custom loop), you're referencing a multitude of arguments against it.
In your case we are interested by the categories parameters.
Category Parameters
Show posts associated with certain categories.
cat (int) – use category id.
category_name (string) – use category slug.
category__and (array) – use category id.
category__in (array) – use category id.
category__not_in (array) – use category id.
Source # https://developer.wordpress.org/reference/classes/wp_query/#category-parameters
We are going to use the category__in and category__not_in parameters. And we will be fetching the category id via the category slug using get_category_by_slug.
Here is our final result. I've added comments, you can add more arguments of you want by looking at the CODEX to view the full list. Modify and have fun!
<?php
// Column A
$x = get_category_by_slug( 'category_x_slug' )->term_id; // ... get category x ID
$y = get_category_by_slug( 'category_y_slug' )->term_id; // ... get category y ID
$args = [
'post_type' => 'post'
'posts_per_page' => 6,
'category__in' => [ $x, $y, ], // ... Column A: post with category x, category y
];
$query = new WP_Query( $args ); // ... loop start
if( $query->have_posts() ):
while( $query->have_posts() ): $query->the_post();
// ... post template start
the_title( '<h1>', '</h1>' );
the_excerpt();
// ... post template end
endwhile;
else:
echo "No posts yet!";
endif; // ... loop end
wp_reset_postdata(); ?>
<?php
// Column B
$x = get_category_by_slug( 'category_x_slug' )->term_id;
$y = get_category_by_slug( 'category_y_slug' )->term_id;
$args = [
'post_type' => 'post'
'posts_per_page' => 6,
'category__in' => [ $x, ], // ... Column B: post with category x
'category__not_in' => [ $y, ], // ... Without post with category y
];
$query = new WP_Query( $args ); // ... loop start
if( $query->have_posts() ):
while( $query->have_posts() ): $query->the_post();
// ... post template start
the_title( '<h1>', '</h1>' );
the_excerpt();
// ... post template end
endwhile;
else:
echo "No posts yet!";
endif; // ... loop end
wp_reset_postdata(); ?>
Related
I Use the latest WP, WC and Storefront Theme versions. On the showcase page, I need to display all categories with products. For example, Bed Category: bed 1, bed 2, bed 3 ..., chairs of the following category: chair 1, chair 2, ... etc. I want to implement the following, or / or a) load a display case with 4 products in each category, after the first scroll, Ajax will download the next 4-8-12 products in each category b) will download all the products of the first category, and the next categories will be loaded after scrolling.
I tried different options. The usual Ajax query works with posts, for me it doesn't work with products.
This is how I display all products by category:
<?php
$args_tax = array(
'taxonomy' => 'product_cat',
'hierarchical' => 0,
'hide_empty' => 1,
);
$all_categories = get_categories( $args_tax );
foreach ($all_categories as $cat) {
echo '<h2>' . $cat->name . '</h2>';
$args_prod = array(
'post_type' => 'product',
'posts_per_page' => -1,
'product_cat' => $cat -> slug,
'order' => 'ASC',
);
$loop = new WP_Query( $args_prod );
woocommerce_product_loop_start();
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
wp_reset_query(); ?>
If I understand correctly, in case (a) (loading 4 products in each category, and then loading the rest after the scroll), I need to specify posts_per_page = 4 in args_prod, and then connect ajax. But the problem is that $ loop-> max_num_pages is always equal 1 (even if there are 30 products and posts_per_page = 4).
In the script -
<script>
var ajaxurl = "<?php echo site_url() ?>/wp-admin/admin-ajax.php";
var products_query = "<?php serialize($loop->query_vars) ?>";
</script>
I get the "SyntaxError: Unexpected identifier" error. And then ajax does not work, because the original query is not correct. I would be grateful for a hint how to write correctly in this case?
ajax button code after category products grid
<div id="loadmore"Load More</div>
ajax handler
jQuery(function($){
$('#loadmore').click(function(){
$(this).text('Loading...');
var data = {
'action': 'loadmore',
'query': products_query,
};
$.ajax({
url:ajaxurl,
data:data,
type:'POST',
success:function(data){
if( data ) {
let btn = '#loadmore';
let wrapper = '#showcase';
$(btn).text('Load More');
$(wrapper).append(data);
}
}
});
});
});
in function.php
function loadmore_posts(){
$args = unserialize( stripslashes( $_POST['query'] ) );
query_posts( $args );
if( have_posts() ) :
woocommerce_product_loop_start();
while( have_posts() ): the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
woocommerce_product_loop_end();
wp_reset_postdata();
endif;
die();
}
add_action('wp_ajax_loadmore', 'loadmore_posts');
add_action('wp_ajax_nopriv_loadmore', 'loadmore_posts');
////////////////////
In option (b) (load the first category, and after scrolling the rest), I added number = 1 to args_tax, and offset = 1 in requests, but I also don't quite understand how to write a query to the database correctly.
I would be grateful for any help or hint in the right direction.
Any thoughts on how to make it work?
I am altering a template file of the Search & Filter Wordpress Plugin to show additional post counts.
The plugin uses the standard Wordpress loop to query posts by certain parameters. The number of posts can be counted by using found_posts.
Now I want to display a second post count that takes additional parameters into account, eg. post_status. I have to stick to the regular WP loop to keep the query from the Plugin intact.
Something like this in the commented line:
if ( $query->have_posts() ) {
echo $query->found_posts 'posts found';
// echo $query->found_posts(array('post_status=>'private') 'private posts found';
while ($query->have_posts()) {
$query->the_post();
the_title();
}
}
The code works fine, except for the commented part which obviously doesn't work.
Is there a way to add another post_count with additional parameters to the standard loop?
Thanks
Georg
You could not add like this echo $query->found_posts(array('post_status=>'private') but before your loop just use below code to count posts by status. in your case you want to count posts by status private so add below code.
$args = array('post_type' => 'your_post_type_name','post_status' => array('publish', 'pending', 'draft', 'future', 'private', 'inherit', 'trash')
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
echo $query->found_posts 'posts found';
// echo $query->found_posts(array('post_status=>'private') 'private posts found';
$count_posts = wp_count_posts('post');
$private_posts = $count_posts->private;
echo $private_posts. 'private posts found';
while ($query->have_posts()) {
$query->the_post();
the_title();
}
}
similarly if you want to show count for publish or draft posts you can add below code.
$publish_posts = $count_posts->publish;
$draft_posts = $count_posts->draft;
you could count any other posts by its status is well.
I have a wp query loop. I want to check if the post belongs to some categories. I can get the category using the_category(). I have tried
if(the_category()==`car`){do somthing}
and how to push all the remaining posts except the car category after to all the 'car' category.
the_category() returns many categories.
You might want to try get the category
$categories = get_the_category();
foreach($categories as $cat) {
if($cat->cat_name == 'car') {
// do something
}
}
You can run two queries here. The first query gets all posts from the car caregory. The second query gets all other posts except posts from the car category. Just remember to change CATID FOR CAR with the id of the car category, and don't forget the minus sign before the ID in the second query. The minus sign means exclude.
You can read more on this in the codex: WP_Query
$do_not_duplicate = array();
$args = array(
'cat' => CATID FOR CAR
);
$carargs = new WP_Query( $args );
if( $carargs->have_posts()):
while ($carargs->have_posts()) : $carargs- >the_post();
$do_not_duplicate[] = $post->ID;
<----your loop---->
endwhile;
endif;
wp_reset_postdata();
$args2 = array(
'cat' => -CATID FOR CAR,
'post__not_in' => $do_not_duplicate
);
$restargs = new WP_Query( $args2 );
if( $restargs->have_posts()):
while ($restargs->have_posts()) : $restargs- >the_post();
$do_not_duplicate[] = $post->ID;
<----your loop---->
endwhile;
endif;
wp_reset_postdata();
I am creating a new wordpress theme for my friend. I want to know how to get the "post number" of a particular post. I don't want the total count of posts. For example, Post No.1 , Post No. 2 etc., Very similar to page numbers in a book.
The wordpress post ID is generally random and i couldn't use it.
any help ?
thanks,
karthik.
EDIT: THIS WORKS.
Okay, so this works. thanks to this. This function will return '1' for 'first post', '2' for 'second post' and so on..
function Get_Post_Number($postID){
$temp_query = $wp_query;
$postNumberQuery = new WP_Query(array ( 'orderby' => 'date', 'order' => 'ASC', 'post_type' => 'any','posts_per_page' => '-1' ));
$counter = 1;
$postCount = 0;
if($postNumberQuery->have_posts()) :
while ($postNumberQuery->have_posts()) : $postNumberQuery->the_post();
if ($postID == get_the_ID()){
$postCount = $counter;
} else {
$counter++;
}
endwhile; endif;
wp_reset_query();
$wp_query = $temp_query;
return $postCount;
}
you can use this to display the number.
<?php $currentID = get_the_ID(); ?>
<?php $currentNumber = Get_Post_Number($currentID); ?>
<?php echo $currentNumber; ?>
If you are in the loop that displays posts, you can use get_the_ID() to return the post's id. If you are outside the loop and you have the post in $post, you can do $post->ID.
I'm trying to display related posts based on a custum taxonomy. I found a query at wordpress.org that kind of works. However the original post gets duplicated in the results multiple times. (words is the name of the custom taxonomy I use) What seems to happen is that the single post gets duplicated according to what amount showpost is set. Any idea's what could cause this?
The code:
<?php
//for in the loop, display all "content", regardless of post_type,
//that have the same custom taxonomy (e.g. words) terms as the current post
$backup = $post; // backup the current object
$found_none = '<h2>No related posts found!</h2>';
$taxonomy = 'words';// e.g. post_tag, category, custom taxonomy
$param_type = 'words'; // e.g. tag__in, category__in, but genre__in will NOT work
$post_types = get_post_types( array('public' => true), 'names' );
$tax_args=array('orderby' => 'none');
$tags = wp_get_post_terms( $post->ID , $taxonomy, $tax_args);
if ($tags) {
foreach ($tags as $tag) {
$args=array(
"$param_type" => $tag->slug,
'post__not_in' => array($post->ID),
'post_type' => $post_types,
'showposts'=>5,
'caller_get_posts'=>1
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<h3><?php the_title(); ?></h3>
<?php $found_none = '';
endwhile;
}
}
}
if ($found_none) {
echo $found_none;
}
$post = $backup; // copy it back
wp_reset_query(); // to use the original query again
?>
It's inside the foreach loop that you're getting duplications. That code is effectively saying;
Get all the terms for taxonomy type $param_type
For each term, get 5 posts that are tagged with that term
So if you have a post that is tagged with more than one term of the same taxonomy, it's likely it will appear more than once.
You can iteratively add queried posts into the post__not_in array to ensure they don't appear again;
Add $post_not_in = array($post->ID); just above if ($tags) {
Then replace the line post__not_in' => array($post->ID), with post__not_in' => $post_not_in,.
Finally, drop $post_not_in[] = get_the_ID(); inside your while loop, after $found_none = '';
As for me i use this plugin for custom taxonomy relate post. I hope that plugin will help your problem.