Create formula to add classes based on field length - php

I need some insight on how to create a formula that will determine what class to add to a div element based on the number of div's being displayed.
Currently I am using ACF to create a repeater field that will have one sub-field that links to a page based what the admin selects. These fields will display in their own div's based on a while loop. I am using Bootstrap classes such as col-sm-12, col-sm-6, and col-sm-4.
while( have_rows( 'project_repeater' ) ): the_row();
$post_object = get_sub_field( 'project_type' );
$count = count( get_field('project_repeater') ); // Output 4
$mod = $count % 3; // Output 1
if( $post_object ):
$post = $post_object;
setup_postdata( $post );
$classname = '';
if( $mod == 1 ) {
if( $count == 1 ) {
$classname .= 'col-sm-12';
} elseif( $count == 4 ) {
$classname .= 'col-sm-6';
} else { // $count == 7
$classname .= 'col-sm-4';
}
} elseif( $mod == 2 ) {
if( $count == 2 ) {
$classname .= 'col-sm-6';
} elseif( $count == 5 ) {
// $classname .= 'col-sm-12';
} else { // $count == 8
// $classname .= 'col-sm-4';
}
} else { // $mod == 0
$classname .= 'col-sm-4';
}
?>
<div class="project-cat <?php echo $classname; ?>">
<a href="<?php the_permalink( $post ); ?>">
<h5><?php the_title(); ?></h5>
<p><?php the_excerpt(); ?></p>
</a>
</div>
<?php
wp_reset_postdata();
endif;
endwhile;
Now when $count == 5, I need it to set the first 3 div's to have col-sm-4 and then the last 2 div's to have col-sm-6 (this will display the divs in this order stacked on top of each other: 3,2).
When $count == 7, it will need to be similar to when $count == 5 but have the first 3 as col-sm-4 and the last 4 as col-sm-6 (3,2,2)
When $count == 8, it will be slightly different where I have the first 6 as col-sm-4 and the last 2 as col-sm-6 (3,3,2).
Instead of using if statement after if statement, there has to be a better way to create a formula that will determine which class to use based on the number of div elements that are being displayed.

This is more math and logic problem rather than coding problem.
Why don't you 1. get the number of elements.
divide by 3 and floor the result. So you can know how many rows of col-xx-4 you are going to have.
let's say you have 14 items in total. Than fist 12 element should have col-md-4.
if you round 14/3 = 4
what is left is 14 - (3*4) = 2 so if what is left is 1 than you can use col-md-12 class, if it is 2 than col-md-6.
so while outputting you assign class col-md-4 to first 12 elements (round 14/3 = 4) and then assign appropriate class to the remaining elements (14 - (3*4) = 2) based on their number (1 or 2)
Do you think it will work for you?
Sequence
set a few variables
$total = total number of items. You can simply run the loop with a counter.
$md4-limit = floor($total/3)*3;
$remaining = $total - $md4-limit;
then when you are running the loop, use the $i and for each element increment that value and when outputting check
if ($i <= $md4-limit) {
$class = ' col-md-4 ';
} else {
if($remaining == 1) { $class = ' col-md-12 '; }
if($remaining == 2) { $class = ' col-md-6 '; }
}
then echo class into column html where the class should be :)
ANOTHER option is to add row width options to the your ACF repeater field and just construct the grid on the back end.

Thanks to you Nick you helped me out a lot, I did find what I was doing wrong and why it wasn't displaying like you said it would. I was not defining $i properly. But here is the code and everything works! Thanks again to you Nick!
$count = count( get_field('project_repeater') );
$limit = floor( $count / 3 ) * 3;
$remaining = $count - $limit;
$i = 0;
while( have_rows( 'project_repeater' ) ): the_row();
$post_object = get_sub_field( 'project_type' );
if( $i < $limit ) {
$classname = 'col-sm-4';
} else {
if( $remaining == 1 ) {
$classname = 'col-sm-12';
}
if( $remaining == 2 ) {
$classname = 'col-sm-6';
}
}
if( $post_object ):
$post = $post_object;
setup_postdata( $post );
?>
<div class="project-cat <?php echo $classname; ?>">
<a href="<?php the_permalink( $post ); ?>">
<h5><?php the_title(); ?></h5>
<p><?php the_excerpt(); ?></p>
</a>
</div>
<?php
wp_reset_postdata();
endif;
$i++;
endwhile;

Related

How to display the rating of the current post in the WordPress loop?

There is a post type the posts of this post type are displayed with this code:
<?php
$args = array (
'post_type' => 'brands',
'posts_per_page' => -1
);
$brands = new WP_Query( $args );
?>
<?php while ( $brands->have_posts() ) : $brands->the_post(); ?>
<p class="name"><?php the_title(); ?></p>
<?php endwhile;?>
Near the title, I need to display the rating of this post. To do this, inside the loop, I write this code:
<?php
$comments = get_approved_comments( $post_id );
foreach( $comments as $comment ){
$rate = get_comment_meta( $comment->comment_ID, 'rating', true );
if( isset( $rate ) && '' !== $rate ) {
$i++;
$total += $rate;
$avrating = round($total / $i, 1);
}
}
?>
<?php
global $post;
$stars = '';
for ( $i = 1; $i <= $avrating + 1; $i++ ) {
$width = intval( $i - $avrating > 0 ? 20 - ( ( $i - $avrating ) * 20 ) : 20 );
if ( 0 === $width ) {
continue;
}
$stars .= '<span style="overflow:hidden; width:' . $width . 'px" class="dashicons dashicons-star-filled"></span>';
if ( $i - $avrating > 0 ) {
$stars .= '<span style="overflow:hidden; position:relative; left:-' . $width .'px;" class="dashicons dashicons-star-empty"></span>';
}
}
echo $stars;
?>
But as a result, I get the same values for all posts. And I need to get different values corresponding to the post, if any, and display nothing if there is no rating. Help please, I myself cannot solve this issue.
I found a solution. There may be better options, but right now my code works and solves my needs. All I've done is to place test before the code that prints rating:
<?php $comments = get_approved_comments( $post_id ); ?>
<?php if($comments == true): ?>
<?php endif; ?>
As a result, we first check to see if the post has confirmed the comments. If there is, then there is a rating (in my case, a comment cannot be left unrated). If there are more elegant solutions I'll be glad to see.

How to add "first" and "last" class to rows of divs?

I am trying to add class first to the first div of a row and class last to the last div of a row. The number of divs in a row is user selectable and stored in a variable. the total number of divs is also user selectable and stored in a variable.
Here's what I have tried, but it adds the class only to the first row and not repeating for the rest.
$number_of_cols = 4; //User Selectable
$posts_per_page = 16; //User Selectable
$mas_query = new WP_Query( $args );
if ( $mas_query->have_posts() ) :
$count = 0;
while ( $mas_query->have_posts() ) : $mas_query->the_post();
$count++; ?>
<div class="blog-masonry-grid-items masonry-col-<?php echo $number_of_cols; echo ( $count == 1 || $count == $number_of_cols + 1 ? ' masonry-col-first' : ''); echo ( $count == $number_of_cols ? ' masonry-col-last' : '');?>">
<div class="grid-item-image-wrap"><?php if ( has_post_thumbnail() ) { the_post_thumbnail('medium_large'); } ?></div>
<div class="grid-item-content-wrap"><?php the_title( '<h3 class="entry-title grid-entry-title">', '</h3>' );?></div>
</div>
<?php endwhile; endif; ?>
How do I make it repeat for all divs pragmatically?
Thanks
You can take advantage of the modulos operator, the remainder after a division:
while ( $mas_query->have_posts() ) : $mas_query->the_post();
$count++;
// Boolean values
$firstOfRow = ($count % $number_of_cols === 1);
$lastOfRow = ($count % $number_of_cols === 0);
When count is 1, 5, etc., the remainder is 1 and when count is 4, 8, etc. the remainder is 0.
Use this code it will work for you:
<div class="blog-masonry-grid-items masonry-col-<?php if($count == 1){ echo $number_of_cols.' masonry-col-first'; }else if{($count ==$number_of_cols) echo $number_of_cols.' masonry-col-last';}?>">
<div class="grid-item-image-wrap"><?php if ( has_post_thumbnail() ) { the_post_thumbnail('medium_large'); } ?></div>
<div class="grid-item-content-wrap"><?php the_title( '<h3 class="entry-title grid-entry-title">', '</h3>' );?></div>
</div>

How to change Div class based on number range

I am using ACF and dont know how to manage to replace div class name if the custom_field number is
equal and less then 30 class="color1"
equal and less then 50 class="color2"
equal and less then 90 class="color3"
Can you please tell me how to do that?
if( $post_objects ):
foreach( $post_objects as $post_object):
echo the_field("casino_rating", $post_object->ID);
endforeach; endif;
Thanks
Atif
I'm assuming you want to get the casino rating and display a different class depending on what appears?
In this case you could use this code:
if( $post_objects ):
foreach( $post_objects as $post_object ):
$casino_rating = get_field("casino_rating", $post_object->ID);
// This part here will decide what class to get
if( $casino_rating < 30 ){
echo 'class="color1"';
} elseif( $casino_rating < 50 ){
echo 'class="color2"';
} elseif( $casino_rating < 90 ){
echo 'class="color3"';
}
endforeach;
endif;
You might want to be careful though and make sure this is only outputting class= if there's no other class attached to the element, otherwise there'll be HTML errors.
Slightly more compact version that should achieve the same thing
if( $post_objects ):
foreach( $post_objects as $post_object ):
$rating = get_field("casino_rating", $post_object->ID);
$color = ($rating >= 31) ? "color2" : "color1";
$color = ($rating >= 51 ) ? "color3" : $color;
echo 'class="'.$color.'"';
endforeach;
endif;
or if you are going to use this a lot make a function for it At the bottom of your page
function color($rating) {
$color = ($rating >= 31) ? "color2" : "color1";
$color = ($rating >= 51 ) ? "color3" : $color;
return $color;
}
Then you can do
if( $post_objects ):
foreach( $post_objects as $post_object ):
$rating = get_field("casino_rating", $post_object->ID);
echo 'class="'.color($rating).'"';
endforeach;
endif;

Wrap Every 1 - 4 Wordpress Posts within a DIV

I am trying to wrap every row of wordpress posts with a div with a class of row.
Have been trying to follow the answers from another question linked below But seem to be having trouble as my loop is a little different. Also I would like any rows with 1 or more posts to be wrapped in a row also...
I need to wrap every 4 wordpress posts in a div
<?php
query_posts('cat=2');
$i = 0;
$wrap_div = "<div class='row'>";
if ( have_posts() ) :
$total_posts = $wp_query->post_count;
echo $wrap_div;
while ( have_posts() ) : the_post();
?>
<div class="four columns gameListing" id="" data-count="">
<img class="gameLogo" src="" >
<div class="gameInfo">
<h2 class="gameTitle"></h2>
<div class="gameRating"></div>
</div>
<a class="gameCta" rel="" data-post-id="" >
<span class="title" data-id="">Click to Play</span
</a>
</div>
<?php
if ( $i % 4 == 0 && $i != 0 && ( $i + 1 ) != $total_posts ) {
echo '</div>' . $wrap_div;
}
$i ++;
?>
<?php endwhile; endif; ?>
<?php wp_reset_query(); ?>
Can be a situation when post_count not multiple of 4
<?php
$my_query = new WP_Query( array( 'category__in' => 2 ) );
$wrap_avery = 4;
$index = 0;
$need_end_div = $my_query->post_count % $wrap_avery > 0;
while( $my_query->have_posts() ) {
$my_query->the_post();
$index++;
// open row if index = 1, 5, 9...
if( ($index - 1) % $wrap_avery == 0 ) {
echo "<div class='row'>";
}
//todo: block HTML here
// close row if index = 4, 8, 12...
if( $index % $wrap_avery == 0 ) {
echo '</div>';
}
}
// close div if posts count not multiple of 4
if($need_end_div) {
echo '</div>';
}
BTW you should no use query_posts

Getting no more than 2 categories shown and last one to remove ending slash

I am trying to show at most 2 categories per post in wordpress and managed to do so, just that don't know how could I detect the second one.
<?php
while ( have_posts() ) : the_post();
$terms = get_terms( 'directory_categories', 'orderby=name&hide_empty=1&hierarchical=0' );
// I am getting the categories
$i = 0;
$len = count($terms); // counting the categories
foreach($terms as $term) {
// terms is an array of objects (http://codex.wordpress.org/Function_Reference/get_terms)
$i++;
if ($i < 3) {
//if it reached second loop then displays with '/'
$array[] = $term->name;
$limit = count($array);
?>
<?php echo $term->name; ?>/
<?php
// else if it reached second loop and second loop is 2 then it should omit the slash
} elseif($i < 3 && i == 2) { ?>
<?php echo $term->name; ?>
<?php } else { } ?>
<?php } ?> <!-- end foreach -->
endwhile;
?>
CURRENT OUTPUT is
Category 1 / Category 2/
EXPECTED OUTPUT is without the ending slash
Category 1 / Category 2
I am very sure that logic is wrong, please let me know where am I mistaking.
Use this code instead (i've put comments so you can easily maintain it):
<?php
while ( have_posts() ) : the_post();
$tax = 'directory_categories'; // your taxonomy
$total = 2; // number of categories to show for each post
$sep = ' / '; // separator you want to use
$terms = get_the_terms(get_the_ID(), $tax);
if ($terms && !is_wp_error($terms)) {
$terms = array_values($terms);
foreach ($terms as $key => $term) {
echo '' . $term->name . '';
if ($key < $total - 1 && count($terms) >= $total) {
echo $sep;
}
if ($key == $total - 1) {
break;
}
}
}
endwhile;
?>

Categories