How to avoid duplicate post in multi - php

I am very new to Wordpress theme development and have found myself stuck at some point in coding.
I created two loops, where one loop has only 1 post and I styles it with bigger image, in the second loop I tried to fetch rest of the post but I am having some major problems.
In the second loop, the post of the first loop is also appearing, I want to avoid duplication.
When I go to page 2 or further, post from first loop is also appearing I want it to appear only on root page.
Below is my code.
First Loop
<?php
$bigi = array(
'posts_per_page' => '1',
'post__not_in' => get_option( 'sticky_posts' ),
);
$restp = new WP_Query($bigi);
?>
<!-- Loop started for bigimage single post -->
<?php if($restp->have_posts()) { ?>
<?php while($restp->have_posts()) { ?>
<?php $restp->the_post();
$post_id = get_the_ID(); ?>
<?php get_template_part('template/post/bigimage'); ?>
<?php } ?>
<?php } ?> <!-- Loop ended for rest of the post -->
<?php wp_reset_postdata(); ?>
Second Loop
<?php
$ropl= new WP_Query(array (
'post__not_in' => get_option('sticky_posts'),
'paged' => $paged,
));
?>
<!-- Loop started for bigimage single post -->
<?php if($ropl->have_posts()) { ?>
<?php while($ropl->have_posts()) { ?>
<?php $ropl->the_post(); ?>
<?php get_template_part('template/post/rop'); ?>
<?php } ?>
<?php } ?> <!-- Loop ended for rest of the post -->
<?php wp_reset_postdata(); ?>

This Should works. Change Query According Your Requirements.
<?php
$args1 = array('category_name' => 'test-cat-1', 'order' => 'ASC');
$q1 = new WP_query($args);
if($q1->have_posts()) :
$firstPosts = array();
while($q1->have_posts()) : $q1->the_post();
$firstPosts[] = $post->ID; // add post id to array
echo '<div class="item">';
echo "<h2>" . get_the_title() . "</h2>";
echo "</div>";
endwhile;
endif;
/****************************************************************************/
// array of post id's collected in first loop, can now be used as value for the 'post__not_in' parameter in second loops query $args
$args2 = array('post__not_in' => $firstPosts, 'order' => 'ASC' );
$q2 = new WP_query($args2);
if($q2->have_posts()) :
while($q2->have_posts()) : $q2->the_post();
echo '<div class="item">';
echo "<h2>" . get_the_title() . "</h2>";
echo "</div>";
endwhile;
endif;
?>

Related

Order wp_query by variable set inside the loop

I have a custom loop that pulls all the child pages of the current page, and displays them. However, I need to order this query by the $first_row_image variable that is pulled inside the loop.
This is done by grabbing the title row at the end() of an array (The array being a repeater field in Advanced Custom Fields).
I know my below code isn't right, but I can't work out how to do it.
<?php function flo_add_child_pages() {
global $post;
$args = array(
'post_type' => 'page',
'post_parent' => $post->ID,
'cat' => '3368',
'posts_per_page' => -1,
'meta_key' => $first_row_image,
'orderby' => 'meta_value',
'order' => 'ASC'
);
$the_query = new WP_Query( $args );
?>
<?php if ( $the_query->have_posts() ) : ?>
<div class="child-flex">
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php
$rows = get_field('breadcrumbs' ); // get all the rows
$first_row = end($rows); // get the first row
$first_row_image = $first_row['title' ]; // get the sub field value
?>
<?php if($first_row_image) : ?>
<a href="<?php the_permalink(); ?>" rel="post-<?php the_ID(); ?>" class="one-half">
<?php echo $first_row_image; ?><i class="fa fa-angle-right rotate-icon" style="float: right; margin-top: 5px;"></i>
</a>
<?php endif;?>
<?php endwhile; ?>
</div><?php wp_reset_postdata(); ?>
<?php endif;
}
In my experience, it's usually better to do complex sorting after the query instead of as part of the query.
For one thing, you defined 'meta_key' => $first_row_image, but $first_row_image is undefined at that point, so the query can't execute on it. For another thing, given the way that ACF stores repeater values, it'd be almost impossible to query on them.
I'd do it this way:
Run the query
Check to see if you have posts
Use usort to write a custom sorting function on the $query->posts array.
<?php
function reorder_by_last_title($page1, $page2) {
$page1_rows = get_field('breadcrumbs', $page1['ID']); // get all the rows
$page1_first_row = end($page1_rows); // get the first row
$page1_first_row_image = $page1_first_row['title']; // get the sub field value
$page2_rows = get_field('breadcrumbs', $page2['ID']);
$page2_first_row = end($page2_rows);
$page2_first_row_image = $page2_first_row['title'];
return $page1_first_row_image > $page2_first_row_image;
}
function flo_add_child_pages() {
global $post;
$args = array(
'post_type' => 'page',
'post_parent' => $post->ID,
'cat' => '3368', // Not sure why this is needed-- did you enable categories for pages?
'posts_per_page' => 500, // Use a big number instead of -1
);
$child_pages_query = new WP_Query($args);
if ($child_pages_query->have_posts()) :
// Reorder child pages by last breadcrumbs title.
usort($child_pages_query->posts, 'reorder_by_last_title' );
?>
<div class="child-flex">
<?php while ($child_pages_query->have_posts()) : $child_pages_query->the_post(); ?>
<?php
$rows = get_field('breadcrumbs'); // get all the rows
$first_row = end($rows); // get the first row
$first_row_image = $first_row['title']; // get the sub field value
?>
<?php if ($first_row_image) : ?>
<a href="<?php the_permalink(); ?>" rel="post-<?php the_ID(); ?>" class="one-half">
<?php echo $first_row_image; ?><i class="fa fa-angle-right rotate-icon"
style="float: right; margin-top: 5px;"></i>
</a>
<?php endif; ?>
<?php endwhile; ?>
</div><?php wp_reset_postdata(); ?>
<?php endif;
}

List each custom post type separately in a wp_query without repeating the loop

I'm using an AJAX search to pull 3 custom post types from wordpress (post, guides, advice). As you can see in my if while loop, the results show which results are which but I'm trying to section them out individually so it will show something like this:
section 1
blog posts
section 2
guides
The problem seems to be that I need to edit the if while loop because adding anything inside that loop will just cause it to be in that loop. Does anyone know the best way to modify the if while loop to achieve this?
function data_fetch(){
$the_query = new WP_Query(
array(
'posts_per_page' => 6,
's' => esc_attr( $_POST['keyword'] ),
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
)
);
global $post;
if( $the_query->have_posts()) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<?php $type = get_post_type();
$term = $_POST['keyword'];
$i++;
$total = $the_query->found_posts;
?>
<span class="search-title">
<?php if ($type == 'post'):?>
<?php echo 'Article: ';?>
<?php elseif($type == 'guide' ):?>
<?php echo 'Guide: ';?>
<?php elseif($type == 'advice' ):?>
<?php echo 'advice: ';?>
<?php endif;?>
<?php the_title();?><br>
</span>
<?php endwhile; ?>
<?php
wp_reset_postdata();
else:
echo '<h3>No Results Found</h3>';
endif;
die();
}
If I were you, I'd probably just do three separate queries. They seem simple enough that it shouldn't cause any issues at all. Otherwise you have to either sort through or reorder the WP_Query results somehow.
If you're set on the single query, however - since these are such short HTML strings, I'd probably just control the output with the Output Buffer.
Basically you can create an associative array, and add the HTML strings to the appropriate keys. You could get a bit more elaborate and have them be nested arrays, but since your output is so light, you can probably get by just by having HTML strings as the values for the keys.
I took the liberty of cleaning up your code a little bit and removing some unused variables, etc.
function data_fetch(){
// Build the Query Arguments
$the_query = new WP_Query( array(
's' => esc_attr($_POST['keyword']),
'posts_per_page' => 6,
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
) );
// Do we have posts?
if( $the_query->have_posts()){
// We do. Start an array that will fill with HTML from the output buffer
$output = array(
'post' => '',
'guides' => '',
'advice' => '',
);
// Loop through the posts
while( $the_query->have_posts() ){
$the_query->the_post();
ob_start(); // Turn on the output buffer
$type = get_post_type(); ?>
<span class="search-title">
<?php echo ($type == 'post') ? 'Article: ' : ucwords($type).': '; // Output "Articles: " for posts, or just capitalize the other post type names ?>
<?php the_title();?><br>
</span>
<?php $output[$type] .= ob_get_clean(); // Add the HTML output from the buffer to our array
}
wp_reset_postdata();
// Here we have an array with 3 HTML strings that we can output wherever
echo $output['post'];
echo $output['guides'];
echo $output['advice'];
} else {
echo '<h3>No Results Found</h3>';
}
}
if I understood your concern, I propose to divide your code by creating a generic class.
and you make calls to the different Post Type :
class Custom_Query {
public $post_type;
public $key_word;
public function __construct($post_type, $keyword) {
$this->post_type = $post_type;
$this->key_word = $keyword;
}
public function getResult() {
echo '<h1>Article : ' . $this->post_type . '</h1>';
$the_query = new WP_Query(
array(
'posts_per_page' => 6,
's' => esc_attr($this->key_word),
'post_type' => array($this->post_type),
'post_status' => 'publish'
)
);
if ($the_query->have_posts()):
while ($the_query->have_posts()): $the_query->the_post();
echo '<span class="search-title">';
echo '' . the_title() . '<br>';
echo '</span>';
endwhile;
else:
echo '<h3>No Results Found</h3>';
endif;
wp_reset_postdata();
}
}
global $post;
$type = get_post_type();
$term = $_POST['keyword'];
$article = new Custom_Query($type, $term);
$article->getResult();
You were on the right track initially. You can just use the standard post objects to check for post type. You can adjust to fit your needs, but try something like this:
<?php
query = new WP_Query( array(
's' => esc_attr($_POST['keyword']),
'posts_per_page' => 6,
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
) );
if ($query->have_posts()) {
while ($query->have_posts()):
$query->the_post();
?>
<div class="posts">
<?php
if ($query->post->post_type === 'post') {
// add your content
} else if ($query->post->post_type === 'guides' {
// add your content
} else {
// add your content
}
?>
</div>
<?php endwhile;
} else {
// no posts found
}

PHP showing certain content top of page, rest afterwards

Wordpress team members have a select in admin that lets you pick a number to display the team in a certain order on Archive page. The Select returns a value of the number, which i retrieve.
However, I want to display all the members that have the value of 1 first, and any members after that show up below. At the moment, the IF statements only shows the content if they exist (obviously), i would like to however make it work somehow so it shows Members with value 1 first, then members with value 2. Thank you!
$images = get_field('image');
$titles = get_the_title();
$positions = get_field('position');
$link = get_permalink($post->ID);
if ($positions[0] == 1) {
echo "<div class='employee'>";
echo "<img src='$images'>";
echo "<h2>$titles</h2>";
echo "</div>";
}
if ($positions[0] == 2) {
echo "<div class='employee'>";
echo "<img src='$images'>";
echo "<h2>$titles</h2>";
echo "</div>";
}
If you want to sort the $positions array you could use
sort($positions);
You you can easily sort by a meta value with get_posts()...
<?php
$args = array(
'post_type' => 'team_members',
'posts_per_page' => -1,
'meta_key' => 'position',
'orderby' => 'meta_value',
'order' => 'ASC'
);
$posts = get_posts( $args );
?>
<?php if( $posts ): ?>
<ul>
<?php foreach( $posts as $post ): setup_postdata( $post ) ?>
<li class='employee'>
<img src='$images'>
<h2>$titles</h2>
</li>
<?php endforeach; ?>
</ul>
<?php wp_reset_postdata(); ?>
<?php endif; ?>

How to get post content from its ID in WordPress multi site?

I'm running a multi site and I want to pull post with certain categories from two blogs. Therefore I am running a loop for each of the blog to pull the posts as one of the category is in blog 1 while the other category is in blog 2.
<?php $value = array(); ?>
<?php
// Get the values from $_POST
$original_blog_id = get_current_blog_id(); // get current blog
$bids = array(1,2); // all the blog_id's to loop through EDIT
foreach($bids as $bid):
switch_to_blog($bid);
$args = array(
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'Music',
'field' => 'slug',
'terms' => array('artist', 'club')
),
)
);
$the_query = new WP_Query( $args );
?>
<?php $postids = array(); ?>
<?php if ( $the_query->have_posts() ) { ?>
<?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
<?php $postids[]=get_the_ID(); ?>
<?php endwhile; ?>
<?php $value[] = $postids; ?>
<?php
} else {
// no posts found
echo 'Nothing found.';
}
?>
<?php endforeach; ?>
<?php
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($value));
$list = iterator_to_array($it,false);
$posts = new WP_Query(array(
'post__in' => $list,
'post_type' => 'post',
));
?>
<?php
foreach ($posts as $post) {
setup_postdata($post);
?>
<?php echo the_title(); ?>
<?php
}
wp_reset_postdata(); ?>
<?php switch_to_blog($original_blog_id); ?>
The reason why I'm getting the IDs inside an array:
<?php $postids[]=get_the_ID(); ?>
because I want to fetch random post's. If at this point instead of the above statement I get the title and content of the posts then it will show in sequential order. Something like this:
BLOG1: POST1,POST2, POST : BLOG2: POST1, POST2, POST3
But I want Posts in random order like this:
BLOG1: POST1, BLOG2: POST3, BLOG1: POST2, BLOG2: POST1: BLOG2: POST2
So everything is working fine, I am able to get the posts IDs even outside the foreach loop but the problem is:
I am not able to get post content from those IDs. It only gives me posts from blog 2 because the current blog is 2. But it doesn't show anything from blog1 even though the postID is in the list array.
Can anyone please help?
The solution can be the following, just add the code into your themes footer.php files, although this can be put anywhere within your WordPress theme, example:
<?php
if (!function_exists('display_posts_from_blogs')) {
function display_posts_from_blogs($blog_id) {
global $switched;
switch_to_blog($blog_id); //switched to blog id 2, for example
// Get latest Post
$latest_posts = get_posts('category=-3&numberposts=6&orderby=post_name&order=DSC');
$cnt =0;
?>
<ul>
<?php foreach($latest_posts as $post) : setup_postdata($post);?>
<li>
<?php echo $post->post_title; ?>
</li>
<?php endforeach ; ?>
<?php restore_current_blog(); //switched back to main site
} //end function
}
?>

How do I show an image from the latest post in wordpress

In Wordpress, I want to show the 2 latest posts along with the post thumbnail for just the first post.
I have been playing around with the code below, but an image always ends up being shown for the first post as well as the second, when I only want to show an image for the first.
<?php
$cat_args = array(
'orderby' => 'name',
'order' => 'ASC',
'child_of' => 0
);
$post_args = array(
'numberposts' => 2,
'category' => $category->term_id
);
$posts = get_posts($post_args);
foreach($posts as $post) {
?>
<?php the_title(); ?>
<?php the_post_thumbnail('blog_post_image'); ?>
<?php
}
}
?>
You're sort of missing any condition that would allow you to selectively display the image.
<?php
foreach($posts as $key=>$post) {
the_title();
if (0 == $key) {
the_post_thumbnail('blog_post_image');
}
}
Assuming $posts is a 0-based enumerated array. Notice the addition of $key to the foreach, as well as the if before printing the thumbnail
<?php $loop = 1; ?>
<?php foreach($posts as $post): ?>
<?php the_title(); ?>
<?php if($loop == 1): ?>
<?php the_post_thumbnail('blog_post_image'); ?>
<?php endif; ?>
<?php $loop++; endforeach; ?>

Categories