I'm working on the search results output for Wordpress website and would like to split a row each third post. Here is what I have at the moment:
<?php if ( have_posts() ) : ?>
<div class="post-wrapper">
<?php
while ( have_posts() ) :
the_post();
?>
<?php get_template_part( 'partials/content', get_post_format() ); ?>
<?php endwhile; ?>
</div>
<?php else : ?>
<?php get_template_part( 'partials/content', 'none' ); ?>
<?php endif; ?>
Now it gets all results but just in one column and I'd like to have three columns. Theme is using Bootstrap so all I need is to add a 'row' each third post but I just can't figure out how to implement this into the PHP template as above. Can somebody help me?
Try this for inspiration. Outputs:
0
1
2
-- BREAK --
3
4
5
-- BREAK --
6
7
8
-- BREAK --
9
Code:
<?php
// Loop 10 times.
for ($i = 0; $i < 10; $i++)
{
// If $i MOD 3 evaluates to zero, then we've reached the end of a group of three items.
// Skip when $i is zero, unless you want to show a break before any output.
if ($i && !($i % 3))
// Output a row separator
echo "-- BREAK --\n";
// Output a row with some column values.
echo "$i\n";
}
Group every 3 posts in one row. Checking the total number of posts avoids a new div in the last element.
$loop_posts = new WP_Query(
array(
'post_type' => 'post',
'post_status' => 'publish',
'no_found_rows' => true,
)
);
$count = 1;
$found_posts= $loop_posts->post_count;
if ($loop_posts->have_posts()) :
echo '<div class="row">';
while ( $loop_posts->have_posts() ) : $loop_posts->the_post(); ?>
<?php
get_template_part( 'includes/news_element', get_post_format() );
if($count % 3==0 && $count <= $found_posts){
echo '</div><div class="row">';
}
$count++;
?>
<?php
endwhile;
echo '</div>';
wp_reset_postdata();
endif;
Related
I'm trying to output a WP loop with a (class name) variable which changes depending on which iteration it is, as defined in this regex.
$mod = 0;
$rows = 0;
for ($i = 0; $i < 10; ++$i) {
$output = " ";
if ($rows % 2 == 1) {
$output = "flip";
}
// Build the post - includes the variable $output
get_template_part( 'partials/loop', 'main' );
if (++$mod % 2 == 0) {
$mod = 0;
++$rows;
}
}
But this doesn't work; instead outputting many duplicates of the same posts with no output.
I'm clearly doing something wrong; maybe approaching the problem in the wrong way.
Tip: The expression tests for every other pair such as 11 - 00 - 11 - 00
The loop, showing desired variable position:
<div class="post small-12 medium-6 columns <?php echo $output; ?>" id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink() ?>">
<h2 class="blog-title">
<?php the_title(); ?></h2>
</a>
</div> <!-- ends post -->
You can't pass a variable to your template via get_template_part(). You need to instead include your template with:
include( locate_template( 'partials/loop-main.php' ) );
// or whatever your template name is...
However, this also highly depends on where you loop is (since you haven't shown it).
For more information, see this answer on WPSE.
So in your case, you'd have something like:
<?php if ( have_posts() ): ?>
<?php // Your initial iterator/counter logic goes here... ?>
<?php /* Start the Loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>
<?php
// Test your counter to see if you need to add a class on this post
// include() the template, rather than get_template_part() so that we can pass the
// counter to the partial template.
include( locate_template( 'partials/loop-main.php' ) );
// Increment the counter
?>
<?php endwhile; ?>
<?php endif; wp_reset_postdata(); ?>
I am having a loop and that loop has only sticky posts in it. So my logic works like this:
"If Sticky Posts are "EMPTY" break the loop". That code works as expected and looks like this:
<?php //we will get "Sticky Posts" only with this loop and exlude Featured Category
$category = get_cat_ID('Featured');
$col = 1; //Let's create first column
$sticky = get_option( 'sticky_posts' );
$args = array(
/* Add whatever you need here - see http://codex.wordpress.org/Class_Reference/WP_Query */
'paged' => $paged,
'category__not_in' => array($category),
'post__in' => $sticky,
'ignore_sticky_posts' => 1
);
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query($args);
/*Below is IMPORTANT PART*/
if($wp_query->have_posts()):?><?php while ( $wp_query->have_posts() ) :
$wp_query->the_post();if(empty($sticky))break;?>
<div <?php post_class('col'.$col); ?> id="post-<?php the_ID(); ?>">
<?php if ($col == 1) echo '<div class="row">';//If column 1 create first row ?>
<?php if ($col == 2) echo '<div class="row2">';//If column 2 create second row ?>
<h3 class="mytitle"><?php the_title(); ?></h3>
<div class="entry">
<?php if ( has_post_thumbnail() ):?>
<div class="featured_img">
<?php
the_post_thumbnail();
echo '<div class="featured_caption">' . get_post(get_post_thumbnail_id())->post_excerpt . '</div>';
?>
</div><!--/featured_img-->
<?php endif; ?>
<?php // let's enable more link on pages...
global $more;
$more = 0;
?>
<?php the_content(__('Read more','override')); ?>
<div class="clear"></div>
<div class="custom_fields"><?php the_meta(); ?></div><br/>
<p class="postmetadata">
<?php _e('Filed under:','override'); ?> <?php the_category(', ') ?> <?php _e('by','override'); ?> <?php the_author(); ?><br/><?php the_tags(__('Tags:','override'), ', ', '<br />'); ?>
<?php _e('Posted on: ','override'); ?><?php the_time(get_option('date_format')); ?><br/>
<?php if ( comments_open() ) {
comments_popup_link(__('No Comments »','override'), __('1 Comment »','override'), __('% Comments »','override'));}
else {
_e('Comments are disabled!','override');
}
?>
<?php edit_post_link(__(' Edit','override'), __(' |','override'), ''); ?>
</p>
</div><!--/entry-->
</div><!--/post_class-->
<?php /*Enable Two Column Layout*/
if($col==1) {
$col=2;
echo "</div>";
}
else if($col==2) {
$col=1;
echo "</div>";
}
endwhile; ?>
<?php endif; ?><!--END if THE LOOP (Sticky)-->
<?php
$wp_query = null;
$wp_query = $temp;
wp_reset_query();
?>
Now before this working code I tried a different logic that goes like this:
"If NOT EMPTY continue the loop" so now everything in my code stays the same except:if($wp_query->have_posts()):?><?php while ( $wp_query->have_posts() ) :
$wp_query->the_post();if(empty($sticky))break;?> so now that code becomes:if($wp_query->have_posts()):?><?php while ( $wp_query->have_posts() ) :
$wp_query->the_post();if(!empty($sticky))continue;?>
Now this is where i got confused because if(!empty($sticky))continue; part does not work as expected because my loop CONTINUES (returns other posts) even if there are no "Stickies". I thought that loop will STOP if there are no stickies but it is not the case. My var_dump($sticky)
shows this if there are sticky postsarray(1) { [0]=> int(214) } and shows this if there are no stickiesarray(0) { }.
My question is: Why the loop continues to return other posts if using if(!empty($sticky))continue; (i thought it will return ONLY "Stickies" if they exist and return NOTHING if they are not here. )
Thank you!!
First off, let me poit out that your logic doesn't quite agree with your code :).
From what I understand from your code, you want to iterate all posts WP_Query() returned, but only render sticky ones. Your if is inside the wile loop, so you have to check if the current post is sticky or not. However, if(empty($sticky)) doesn't do that. It checks if there are any sticky posts at all. A way to check the current post would be if(is_sticky(the_ID())).
Now, concerning continue:
From the php manual:
continue is used within looping structures to skip the rest of the
current loop iteration and continue execution at the condition
evaluation and then the beginning of the next iteration.
So as you can see, continue doesn't stop the loop, but rather attempts to start the next iteration ignoring the rest of the code for the current step. Which is what you want, if the current post is not sticky, in other words if(!is_sticky(the_ID())).
However, I think you don't really need any check at all, since you already specified that you want WP_Query() to fetch only stickies ('post__in' => $sticky).
See also: this WordPress Answers topic.
I don't know well the wordpress code, but in that code, the $sticky variable is never updated in the while loop. So maybe you have to add $sticky = get_option( 'sticky_posts' ); right before the if condition.
My loop displays posts in two columns using this:
<?php
if (have_posts()): while (have_posts()) : the_post();
$count++;
?>
<?php if ($count == 1) : ?>
<div class="home-ci-row">
<div style="padding: 0px;" class="main-column-item-wrap">
CONTENT OF POST : Title, Thumbnail, Excerpt... etc
</div>
<div class="home-ci-gap"></div><!-- /* the gap */ -->
<?php elseif ($count == 2) : ?>
<div style="padding: 0px;" class="main-column-item-wrap">
CONTENT OF POST : Title, Thumbnail, Excerpt... etc
</div> <!-- main-column-item-wrap -->
</div><!-- /* home-ci-row*/ -->
<?php $count = 0; ?>
<?php else : ?>
// No posts
<?php endif; endwhile; endif; ?>
You can see that the <div class="home-ci-row"> opens in the first count & closes in the second one </div>
so when my loop has an even number of posts works great, but with odd number it doesn't close the div
so My idea is this: If loop has even number
If loop has odd number of posts
By the way, you can do something like:
<?php
$count=0;
while(have_posts()){
if($count%2==0){
echo '<div class="home-ci-row">';
//draw your left div here
}else if($count%2==1){
//draw your gap here
//draw your right div here
echo '</div>';
}
$count++;
}
//close div if count is an odd number
if($count%2==1) echo '</div>';
?>
Is it possible to swap to a for loop? Is this what you need?
for ($i = 0; $i < $numberOfElements; $i++)
{
//if (odd number) && (this is the last element)
if (($i % 0 == 1) && ($i == $numberOfElements - 1))
{
//Special Case
}
else
{
//Normal Case
}
}
Caveat: Watch out for errors, PHP isn't my strongest language
This question was answered on WP Development StackExchange by fischi
Quoting from his answer:
You could do this much easier. As you are making a layout that can be achieved by floats, there is no need to declare a Row every second time.
In my Code example I just youse the $count to determine the Class of the HTML-Element. In combination with the total Number of Posts displayed.
If the total number of posts $wp_query->post_count is reached by the $count AND the total number is odd, I give the Element the Class fullwidth. In the same way, I determine if it is the first or the second (see the IF-Statement).
All I need to do afterwards is output the corresponding Class for each HTML-Element in the Loop. Besides the Class, no Element is diffferent from each other.
I use the Modulo Operator in PHP ( % ) to determine odd/even. It delivers 1 if I use $count % 2 and $count is odd. If you are not sure about this operator, read about it here.
So your code could look like this:
<?php
$count = 0;
if (have_posts()): while (have_posts()) : the_post();
if ( ++$count == $wp_query->post_count && ( $wp_query->post_count % 2 ) == 1 ) {
// if final count is reached AND final count is odd
// full width item
$postclass = "fullwidth";
$opentag = '';
$closingtag = '</div>';
} else if ( ( $count % 2 ) == 1 ) {
// if $count is odd it is the first item in a 'row'
$postclass = "halfwidth first";
$opentag = '<div class="home-ci-row">';
$closingtag = '';
} else {
// second item in a row
$postclass = "halfwidth second";
$opentag = '';
$closingtag = '</div>';
}
?>
<?php echo $opentag; ?>
<div class="main-column-item-wrap <?php echo $postclass; ?>">
CONTENT OF POST : Title, Thumbnail, Excerpt... etc
</div><!-- main-column-item-wrap -->
<?php echo $closingtag; ?>
<?php endwhile; endif; ?>
I have a query that gets the 5 highest rated content on my blog how can i make it so for each post that is shown with the query 1 is added to the a $number variable?
Basically what i want is to give the highest rated content a number between 1-5 the first gets 1 the second get 2, third get 3 and so on.
<?php ( query_posts('category_name=music&showposts=3&orderby=comment_count&order=desc&post_status=future,publish') ) ; ?>
<?php while ( have_posts() ) : the_post(); ?>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
Try this - just set $number to 0 and then use ++ to increment the number,
<?php ( query_posts('category_name=music&showposts=3&orderby=comment_count&order=desc&post_status=future,publish') ) ; ?>
<?php $number=0; while ( have_posts() ) : the_post(); $number++; ?>
Rated #<?= $number ?>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
Problem.
What I am trying to do is to call a category specific loop, however, I want whats returned to display from most recent first, to be numerically numbered so that for every 2 that is displayed, will echo a css class ascertained to them and the 3rd result to display a completely different class as this is how I have written my html. Here is what I am trying to get the HTML to display:
<div id="content">
<div class="block1"></div>
<div class="block1"></div>
<div class="block2"></div>
<div class="block1"></div>
<div class="block1"></div>
<div class="block2"></div>
</div>
If there are more results then the first two will be named in the first div and the 3rd of all the results will have that class name assigned to it.
Help would be more than greatly appreciated.
Remarked:
<?php query_posts( 'cat=featured&showposts=4' ); ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php foreach($recent as $index => $postObj) {
$class = $index + 1 % 3 === 0 ? 'block2' : 'block1';
}
?>
<h1><?php the_title(); ?></h1>
<?php endwhile; else: ?>
<p>Sorry, no posts matched your criteria.</p>
<?php endif; ?>
<?php get_footer(); ?>
however its returning the number of posts but under the posts its returning
Warning: Invalid argument supplied for foreach()
Have tried trial and error however, I think that my grammar is atrocious.
What you're looking for is the modulo operator. What modulo does is find the remainder of a division operation. In effect the result is in a range of 0..N-1, where N % N = 0.
foreach($posts as $index => $postObj) {
$class = $index + 1 % 3 === 0 ? 'block2' : 'block1';
This accomplishes what you want because the loop logic looks like:
1 % 3 = 1 -> block1
2 % 3 = 2 -> block1
3 % 3 = 0 -> block2
Your code needs to be:
<?php
query_posts( 'cat=featured&showposts=4' );
$index = 1;
if ( have_posts() ) :
while ( have_posts() ) : the_post();
$class = $index++ % 3 === 0 ? 'block2' : 'block1';
?>
<div class="<?php echo $class ?>">
<h1><?php the_title(); ?></h1>
</div>
<?php endwhile; else: ?>
<p>Sorry, no posts matched your criteria.</p>
<?php endif; ?>
<?php get_footer(); ?>
The $index++ operator means, "increment $index after this use of it." So, notice how the loop is set up. Before the loop we set $index to 1. Inside the loop we set $class using our modulo technique, then increment $index. Then we have to create a container DIV, like you mentioned, and echo the class there.