Specifying 'post_per_page' for multiple post loop - php

I have created a post loop that displays 2 different types of post ('portfolio' and 'post').
<?php
$work = array(
'post_type' => array('portfolio','post'),
'posts_per_page' => '8',
);
$loop = new WP_Query( $work );
while ( $loop->have_posts() ) : $loop->the_post();
if ( get_post_type() == 'portfolio' ) {
// My portfolio code will go here
}
else if ( get_post_type() == 'post' ) {
// My post code will go here
}
endwhile;
?>
This seems to work fine, but what I would like to do is limit the number of posts each type displays. I've set it so that it limits 8 overall but i'd like to expand this further and limit each type to 4 (4 + 4 = 8 overall).

Hey there I can not think of an easy solution but you have some possibilities to achieve this.
Query all posts and make a counter (bad performance if you have very much posts)
$work = array(
'post_type' => array('portfolio','post'),
'posts_per_page' => -1,
);
$count_portfolio = 0;
$count_post = 0;
$loop = new WP_Query( $work );
while ( $loop->have_posts() ) : $loop->the_post();
if ( get_post_type() == 'portfolio' && $count_portfolio < 4 ) {
$count_portfolio++;
}
else if ( get_post_type() == 'post' && $count_post < 4) {
$count_post++;
}
if($count_portfolio >=3 && $count_post >=3) {
break;
}
endwhile;
Make two different queries - one for the last four portfolios and one for the last 4 posts
// pseudo code
$allposts = array_merge($query1->posts, $query2->posts);
usort($allposts,'orderbydate_custom_function');
foreach($allposts as $post) {
// do output
}
Make a custom call with $wpdb to query exactly what you want

Related

Exclude specific category from Related Posts

Looking to exclude specific category (ID = 100) from "Related Posts" feed at bottom of Blog pages. Extra bonus if it can also exclude from the sidebar archive (not sure if they are connected??)
I'm using WP Theme "TheFox", have asked them - not part of their theme.
I "think" it has to do in the functions.php. I have found some similar questions, and code, but have not had any luck.
I'm a complete noob for .php, so be gentle :)
I've found some other attempts, no luck. Not registering or effecting the feed.
$categories_to_exclude [ 100 ];
$first_cat = false;
$categories = get_the_category( $post->ID );
while ( ! empty( $categories ) && false === $first_cat ) {
if ( in_array($categories[0]->cat_ID, $categories_to_exclude) ) {
array_shift($categories);
}
else {
$first_cat = $categories[0]->cat_ID;
}
}
What I could gather from your question is that You want to ignore one category (may be more) in the related post query?
use the following CODE (some explanation is given within the CODE in comments):
// set the category ID (or multiple category IDs)
// you want to ignore in the following array
$cats_to_ignore = array( 2 );
$categories = wp_get_post_categories( get_the_ID() );
$category_in = array_diff( $categories, $cats_to_ignore );
// ignore only if we have any category left after ignoring
if( count( $category_in ) == 0 ) {
$category_in = $categories;
}
$cat_args = array(
'category__in' => $category_in,
'posts_per_page' => 4,
'orderby' => 'date',
'post__not_in' => array( get_the_ID() )
);
$cat_query = new WP_Query( $cat_args );
while ( $cat_query->have_posts() ) : $cat_query->the_post();
/* just example markup for related posts */
echo '<h2>' . get_the_title() . '</h2>';
endwhile;
// reset $post after custom loop ends (if you need the main loop after this point)
wp_reset_postdata();
Use the below code, it must work
$categories_to_exclude [ 81, 11, 21 ];
$first_cat = false;
$categories = get_the_category( $post->ID );
while ( ! empty( $categories ) && false === $first_cat ) {
if ( in_array($categories[0]->cat_ID, $categories_to_exclude) ) {
array_shift($categories);
}
else {
$first_cat = $categories[0]->cat_ID;
}
}
You get the categories with get_the_category. Then in the while loop you skip the first category if it's 81, and look again. If it's not 81 (and you still have categories available), you asign it to $first_cat and carry on.

How to get the next $args when if:false?

I am new in programming... (The question absolutely about programming, but I use wordpress) I try to be very clear:
I have a subdomain based multisite network. If the users posts to their sites, I get a clone from the current post to my network home. This clone have a canonical url, what shows to the original post, and the post slug's also concur (the ID's dont.)
example: x user posted:
url: xusersite.network.com/4243345/this-is-slug-by-post-title
canonical: xusersite.network.com/4243345/this-is-slug-by-post-title
I get:
url: network.com/123677745/this-is-slug-by-post-title
canonical: xusersite.network.com/4243345/this-is-slug-by-post-title
Now I want get the clone post's ID, on the subsite, by the original post... so I have this code:
switch_to_blog( 1 );
$canonical = 'xusersite.network.com/4243345/this-is-slug-by-post-title';
$slug = 'this-is-slug-by-post-title'; // current slug
$args = array(
'name' => $slug,
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => 1
);
$my_posts = get_posts($args);
Thats ok, but the problem, if an another user posted with the same title for his blog, example: y user posted:
url: yusersite.network.com/72543/this-is-slug-by-post-title
canonical: yusersite.network.com/72543/this-is-slug-by-post-title
I get a post, with the same slug:
url: network.com/776536556733/this-is-slug-by-post-title
canonical: yusersite.network.com/72543/this-is-slug-by-post-title
So my php knowledge now here it is, I can do this:
if( $my_posts ) :
$cloneid = $my_posts[0]->ID;
$clonecanonical = wp_get_canonical_url( $cloneid );
if( $clonecanonical == $canonical ) :
$exit = 'true';
else :
$exit = 'false';
endif;
endif;
How can I get the next $my_posts, so $my_posts[1]->ID, if the $exit is false? How can I get the right $my_posts?
Not sure to have understood, but you should get the numeer of posts in my posts using count($my_posts) and then use a for or while to iterate through the full $my_posts.
something like this:
if( $my_posts ) :
$numPosts=count($my_posts)
//if $numPosts = 0 then $my_posts[0] does not exist
//but if you are here $numPosts must be > 0
if $numPosts > 0 {
for ( $i = 0; $i < $numPosts; $i++ ){
$cloneid = $my_posts[$i]->ID;
$clonecanonical = wp_get_canonical_url( $cloneid );
if( $clonecanonical == $canonical ) :
$exit = $my_posts[$i]->ID;
endif;
}
}
endif;

Multiple if Statements issue

I am having a problem with multiple if statements. I am using && but it seems to only work for the first statement.
The code is like such:
global $post;
$args = array( 'post_id' => $post->ID );
$comment = get_comments( $args );
$user = wp_get_current_user();
if ( 3 <= count( $comment ) && $post->post_author == $user->ID) {
echo do_shortcode( '[button]' );
} else {
comment_form();
}
It basically stats that if there is less than 3 comments then show the comment form but if there is more than 3 and is the post author then show a button. The button shows but only if there are more than 3 comments. It doesn't check if it is only the post author or not, like I want it to.
What you are describing are two cases in which the button should be showed. So there have to be two ways to get into the if-block. You have to refactor your if-statement with the logical or-operator ||.
for example:
if($post->post_author == $user->ID || 3 <= count($comment)) {
echo do_shortcode( '[button]' );
} else {
comment_form();
}
I had to change the code like so to get it to work.
global $post,$current_user;
$args = array( 'post_id' => $post->ID );
$comment = get_comments( $args );
get_currentuserinfo();
if ($post->post_author == $current_user->ID ) {
echo do_shortcode( '[button]' );
} elseif ( 3 <= count( $comment ) ) {
// blank
} else {
comment_form();
}

Wordpress, random product only on home search page

I have a custom wordpress search page with page navigation numbers, my client asks me to random products on page 1 but not for others, but all products displayed randomly on home page should not displayed on others pages.
For the query i have this code :
$args = array(
'post_type' => 'products',
'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1 )
)
and for the random :
if( $args['paged'] == 1) {
$args['orderby'] = 'rand';
} else {
$args['order'] = 'DESC':
}
the results are there when i do a search, and first page random well, but some products that are already displayed on home page because of the random are also displayed on others pages (ex : page 2 ).
The aim is not display products that are already displayed on home page.
I already do something similar :
if( $page == 1 ) shuffle($r->posts);
But it shuffle only first the 10 products on page 1, and others products on others pages never display on page 1.
After some thoughts i think store first 10 random products to cookie or session and do a NOT IN for others pages ? like this ?
if( $args['paged'] == 1 ){
$args['orderby'] = 'rand';
$r = new Wp_Query($args);
$randomFirstPage = wp_list_pluck( $r->posts, 'ID' );
print_r($randomFirstPage);
setcookie( 'firstPageResults', $randomFirstPage, time()+3600, '/', 'mydomain.com/dev' );
}else{
$not_in = $_COOKIE['firstPageResults'];
$args['NOT IN'] = $not_in;
$r = new Wp_Query($args);
}
Sorry for bad english, and may you help me please ?
Thanks
Try this aproach:
<?php
$products1_ids = array();
$products2_ids = array();
$allproducts = get_posts(array('post_type' => 'products'));
$p=1; foreach($allproducts as $products) {
if(is_page(1) && $p<11) {
$products1_ids[] = $products->ID;
}
if(!is_page(1) && $p>10) {
$products1_ids[] = $products->ID;
}
$p++; }
shuffle($products1_ids);
shuffle($products2_ids);
$post_in = is_page(1) ? $products1_ids : $products2_ids;
$products = new WP_Query(array(
'post_type' => 'products',
'posts_per_page' => 10,
'post__in' => $post_in,
));
if($products->have_posts()) {
while($products->have_posts()) { $products->the_post();
echo '<div class="post">'
the_title();
echo '</div>';
}
}
Hope it helps
Your posted code above uses $args['NOT IN'] = $not_in;, but according to the WP_Query docs the argument to exclude posts by id is post__not_in:
$query = new WP_Query(
array('post_type' => 'post', 'post__not_in' => array(2, 5, 12, 14, 20))
);
So try:
$args['post__not_in'] = $not_in;

Insert a post type every x posts in custom loop

I was hoping someone could help me with this problem.
I'm trying to make a loop in wordpress with two different post types ('product' and 'outfits')
The code below is working fine, this outputs a list of the two post types ordered by newest to older.
$loop = new WP_Query( array(
'post_type' => array( 'product', 'outfits' ),
'posts_per_page' => 15
) );
$counter = 0;
?>
<?php if ( $loop->have_posts() ) { while ( $loop->have_posts() ) { $loop->the_post();
$counter++; ?>
<?php $loop->is_home = false; ?>
<?php
$large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'large');
$titulo = get_the_title();
$content = apply_filters ('the_content', $post->post_content); ?>
<div class="caja-<?php echo $counter; ?>">
<?php if ( $post->post_type == "product" ) {
//some stuff
<?php } else {
//some stuff
} ?>
</div>
<?php } } wp_reset_postdata();
What I would like to do is to insert a product post type after X number of outfits.
I was trying to merge a similar solution I've found in other question with no luck. I'm not a php expert so any help is appreciated
<?php
$args = array('post_type'=>'post', 'posts_per_page'=>9, 'category_name'=>'news');
$posts = get_posts($args);
$args = array('post_type'=>'testimonials', 'posts_per_page'=>3);
$testimonials = get_posts($args);
// see how many of the regular posts you got back //
$post_count = count($posts);
// see how many testimonials you got back //
$testimonial_count = count($testimonials);
// add them up to get the total result count //
$total_count = $post_count + $testimonial_count;
// Loop through the total number of results //
for($i = 1; $i <= $total_count; $i++){
// assuming you want to show one testimonial every third post //
if($i % 3 == 0){
// this means you're on the a third post, show a testimonial //
setup_postdata($testimonials[$i]);
}
else{
/** show a regular post */
setup_postdata($posts[$i]);
}
/** and now handle the output */
?><h1><?php the_title();?></h1><?php
} ?>
$x = 3;
$products = get_posts(array(
'post_type' => 'product',
'posts_per_page' => -1
));
$outfits = get_posts(array(
'post_type' => 'outfit',
'posts_per_page' => -1
));
foreach ($outfits as $num => $outfit) {
if ( ($num+1) % $x == 0) {
if (isset($products[($num+1)/$x - 1])) {
array_splice( $outfits, $num, 0, array($products[($num+1)/$x - 1]) );
}
}
}
foreach ($outfits as $outfit) {
$posts_id[] = $outfit->ID;
}
$query = new wp_query(array(
'post_type' => array('outfit', 'product'),
'post__in' => $posts_id,
'posts_per_page' => 15,
'orderby' => 'post__in'
));

Categories