Define variable - use in WP loop - php

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(); ?>

Related

PHP Even and ODD items in one of two columns, put first item in even column

My count loop currently works but it is not working correctly. I need every second item to go into the right column and the rest stay in the left. So 1, 3, 5 etc in the column called split-left and 2, 4, 6 to go into the column called split-right
<!-- SPLIT EFFECT PAGE BUILDER -->
<div class="page-builder">
<?php if( have_rows('split_effect_page_builder') ): ?>
<div class="split-left">
<?php $i = 1; ?>
<?php while ( have_rows('split_effect_page_builder') ) : the_row(); ?>
<?php get_template_part('template-parts/page', 'builder'); ?>
<?php
if($i % 2 == 0){
echo '</div><div class="split-right">';
$i = 0;
}
$i++;
?>
<?php endwhile; ?>
</div>
<?php else : ?>
<?php // no layouts found ?>
<?php endif; ?>
</div>
<!-- END SPLIT EFFECT PAGE BUILDER -->
Seems you just need to reset your counter whenever it reaches 2..
<?php
if($i == 2){
echo '</div><div class="split-right">';
$i =0; // set back to zero...
}
$i++; // and now it's 1 again so next iteration would be left aligned
?>
PS.. not sure why you close a PHP tag only to immediately re-open it.. That won't break anything, but probably a good habit to get rid of.

Php continue not working if not empty?

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.

Conditional styling for post containers in The Loop

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; ?>

Equivalent of ExpressionEngine switch tag in wordpress/php?

In ExpressionEngine while in their version of 'the loop' I can add a tag to any element like this:
<li class="{switch='one|two|three|four|five|six'}">
The first iteration of the li will have class one, the next is two, and the loop again after six. I'm needing this similar functionality in a wordpress site, but not sure how to accomplish that. Is there a built in wordpress function or will I need to code some sort of function in php?
Currently, using this in attempt at using #Leonard's solution, but the class 'four' is being repeated over and over instead of cycling
<?php
$argsGallery = array(
'post_type' => 'gallery',
'orderby' => 'menu_order',
'order' => 'ASC'
);
$the_query = new WP_Query( $argsGallery );
// The Loop
while ( $the_query->have_posts() ) : $the_query->the_post();?>
<div class="<?php cycle('four|three|five|two|six|four'); ?> columns">
<div class="thumb">
<a class="jackbox"
data-group="images"
data-thumbnail="<?php the_field('image'); ?>"
data-title="Image One"
data-description="#description_1"
href="<?php the_field('image'); ?>"
>
<div class="jackbox-hover jackbox-hover-black">
<p><?php the_field('image_description'); ?> </p>
</div>
<img
src="<?php the_field('image'); ?>"
alt="responsive lightbox"
/>
</a>
</div>
</div>
<?php
endwhile;
wp_reset_query();
wp_reset_postdata();
?>
Found this question whilst looking for the exact same thing... top of Google 20mins after you posted it. Crazy... anyway!
I've come up with a function that I've tested (albeit quickly) that you can drop in to your functions.php and it works with a standard Wordpress loop. It may need adapting for some needs but hopefully it's a good start point.
It uses the current_post count from the $wp_query array and works out where it needs to be in the cycle values.
function cycle($input, $delimiter = '|', $query = false) {
if($query == false):
global $wp_query ;
$current_post = $wp_query->current_post + 1;
else:
$current_post = $query->current_post + 1;
endif;
$switches = explode($delimiter, $input);
$total_switches = count($switches) ;
$current_set = ceil( $current_post / $total_switches) ;
$i = (($current_post - ($current_set * $total_switches)) + $total_switches) - 1 ;
echo $switches[$i];
}
Then you can use it in a STANDARD loop like so:
<?php cycle('first|second|third|fourth'); ?>
Or you can custom delimit if needs be:
<?php cycle('first*second*third', '*'); ?>
Or if your using it with a CUSTOM wp_query you must use it like this with the query fed in as the third argument:
<?php cycle('first|second|third', '|', $the_query); ?>
I'm sure there is a tidier way to feed in that custom query, I'll keep looking and update if/ when I find a way!
This is known as a cycle function. Unfortunately, PHP does not have such a function natively.
You will need to custom write one, either by:
Creating a function. Here's a good example.
Directly in your loop with a counter and modulus. The following is a contrived example:
$cycles = array('one', 'two', 'three');
for ($i = 0; $i < 9; ++$i) {
echo $cycles[$i % 3];
}
I know enough WP and I never see something like that. Maybe that's why ExpressionEngine is payed (have already built-in solutions like that. In WP you must to do it at hand). Here an idea to make it by your own:
UPDATE: #jason-mccreary 's answer I know that I was wrong. I didn't know nothing about cycles. But here I have a snippet that seems to work like that:
function cycle($chunks)
{
if ( ! is_array($array = explode('|', $chunks)))
return;
static $i = 0;
echo $array[$i ++];
if ($i >= count($array))
$i = 0;
}
?>
<?php for ($i = 0; $i < 9; ++ $i) : ?>
<li class="<?php echo cycle('one|two|three|four|five|six'); ?>"></li>
<?php endfor; ?>
OUTPUT:
<li class="one"></li>
<li class="two"></li>
<li class="three"></li>
<li class="four"></li>
<li class="five"></li>
<li class="six"></li>
<li class="one"></li>
<li class="two"></li>
<li class="three"></li>

PHP Wordpress loop for 2posts to echo class and third to echo class2

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.

Categories