Jump to content

Different styles for results of an array (page grid)


MilenKo
 Share

Recommended Posts

Recipe-Header-Images.thumb.jpg.0a45ed3dfb6f3647ca2bc2fba69198d7.jpg

Hello good people. I was looking today on a header styling that I would like to use in my next project where I want to grab X-amount of posts and place them in a grid with different sizes and layout (hopefully you will understand me better from the layout shown above ). So far I was able to pull an array of posts and present them on the front-end using identical code for all results, however I have never dealt with a similar presentation where the 1st and 2nd posts have one style, 3rd has another, 4th different again and so on.

Let's say in this scenario I would grab some results with $pages->find(...) but how would then I apply the different styling for every result?

Link to comment
Share on other sites

it's pretty simple, you just set a counter before the loop and increment it at the end of each loop increment... then you can use that incremental counter to conditionally add a class where needed.

for example:

$count = 0;
foreach($items as $item) {
    $class = ['default-class'];
    if($count == 2) $class[] = 'some-other-class';
	$classOut = implode(' ', $class);
	// echo your div with the imploded classes..
    $count++;
}

 

  • Like 1
Link to comment
Share on other sites

Had this written before Macrura's post so I'll leave it here.

$x = 0;
foreach($recipes as $recipe){
    $class = "class";
    $imageSrc = $recipe->image->first()->size(200,200)->url;
    if($x == 1){
        $class = "otherClass";
        $imageSrc = $recipe->image->first()->size(500,200)->url;
    }
    echo "<div class='{$class}'><img src='{$imageSrc}'></div>";
    $x++;
}

 

You can also use css :nth-child pseudo class

  • Like 2
Link to comment
Share on other sites

You could also try something like that:

$styles = array("class1", "class2", "class3");
$recipes = $pages->find('your-selector');

foreach($recipes as $key => $recipe){
    $class = (isset($styles[$key])) ? $styles[$key] : "default-class";
    echo "<div class='$class'><img src='{$recipe->images->first->url}'></div>";
}

 

  • Like 2
Link to comment
Share on other sites

Very interesting, that CSS-Grid stuff. I'm thrilled. Here is a short list of usefull links:

(must read)
http://jensimmons.com/post/feb-27-2017/learn-css-grid
http://gridbyexample.com/examples/

(some specs and technical info)
http://gridbyexample.com/browsers/
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_and_Progressive_Enhancement
https://drafts.csswg.org/css-grid/#grid-containers

(some more)
https://css-tricks.com/css-grid-one-layout-multiple-ways/

PS: you also can support older browsers with different fallbacks, there are tuts over that too.

  • Like 5
Link to comment
Share on other sites

Thank you very much, guys. It is amazing how many answers I got and what is more important some approach choices and suggestions.

I will start playing and share the code if somebody is looking for something like that. I liked the idea of @Nukro to make the styles in an array however it won't be just a class change so it might be easier to use the approach of @Macrura and @fbg13 where I would use something like:

if($x == 1){ ...some code... }

if($x == 2){ ...some code... }

if($x == 3){ ...some code... }  etc.

Again I am super pleasantly surprised how simple it is to work with PW and its API...^-^

 

Link to comment
Share on other sites

  • 2 months later...

Hello again.

I have done most of the functionality, fields etc. so now am back to the presentation and to that styling grid. My need is to have an array of 10-12 posts, where the first two are large images (different styling and code), the next 4 are smaller images (code differs from the first ones). After the first 6 the array repeats.

For sure I can do an array of all 12 posts and do some if/then check for the counter being 1, 2, 7, 8 but I am looking of an elegant way to achieve that as I might need to have 18, 24 etc. so having a check of the counter would become silly the more results I will have to pull.

I thought i could grab the first two elements using something like:

$large = array_slice($input, 0, 2);

$small = array_slice($input, 2, 2); but am not sure how to tie up the things with the loop so that it repeats until the N-number of results in the array...

Link to comment
Share on other sites

@LostKobrakai Thank you very much for your simple but elegant example.

I am just a bit confused about implementing your code with the recipe results array. What would be $post content.. If I got it correctly, $post would be my get/find results query?

$recipes = $pages->find('/recipes/');
foreach($recipes->getValues() as $index => $post) {
	$is_large = $index % 6 == 1 || $index % 6 == 2

	if($is_large) 
	else 
}
Link to comment
Share on other sites

Ok, having some ideas thanks to @LostKobrakai, @Macrura and @fbg13 I started playing with the results to see what is going to happen. I must admint that the PHP Modulus operator really made my day and would digg more into it as it literally would solve any of my future needs for every N-th or result-on-every - kind of queries. With some code tinkering I was able to get the posts showing, however instead of starting with two large, it started with a small followed by two large. That made me think why so in the title field I echoed $index and that shown the reason. The modulus result started from 0 but not from 1.That was easy to fix by quering $is_large = $index + 1 % 6 ... but I decided to make it simpler so instead of checking if the result is 1 & 2, I got it checcking for 0 & 1. That showed the results properly (2 large, 4 small, 2 large, 4 small).

As usual it won't be that pleasant if there are no challenges... I noticed that the results are not properly alligned to the code grid. Looking at the theme code I found that there are two different styles for the first and second post in the row. So following the same logic, I came up with the following code that made it work like a charm:

<div class="masonry-grid" data-layout-mode="fitRows">
  
<?php $recipes = $pages->find("template=recipes-inner, sort=-published, limit=12");
foreach($recipes as $index => $latest) {

if ($index % 6 == 0 ) $class = 'first-in-row'; // Post aligned to left
elseif ($index % 6 == 1 ) $class = 'last-in-row'; // Post alligned to right

if ($index % 6 == 0 || $index % 6 == 1) { ?> <!-- Define code for first two results -->

  <!-- Large Post -->   
  <div class="masonry-item any half <?=$class?>">
    ...
  </div>
  <!-- /Large Post -->
  <? }
else { ?> <!-- Define code for the other 4 posts -->

  <!-- Small Post -->
  <div class="masonry-item any half <?=$class?>">
    ...
  </div>
  <!-- /Small Post -->
  <? } 

} ?>
</div>

So far so good. Event though the code works fine, I am wondering would it be possible to avoid a double query and make it more elegant. Any suggestions are more than welcome and greatly appreciated (as usual) ;)

Link to comment
Share on other sites

Ok, giving it a bit of a time and following up made me rethink the approach. As far as it was done to be working, but the code was still not good (only the last-in-row) was applied on the small posts, I decided to go for odd:even and that did the job as needed:

<div class="masonry-grid" data-layout-mode="fitRows">
	<?php $i=1; // Defining the rows counter
	$recipes = $pages->find("template=recipes-inner, sort=-published, limit=12");	
	foreach($recipes as $index => $latest) { // 
		$class = ($i & 1) ? 'first-in-row' : 'last-in-row'; // Checking up if the result is even or odd and assigning proper class		
		if ($index % 6 == 0 || $index % 6 == 1) { ?> <!-- Checking up for the first and second post in an array of 6 -->
			<!-- Large Post -->   
			... Your Code ...
			<!-- /Large Post -->
	<? }
		else { ?>   
			<!-- Small Post -->
			... Your Code ...
			<!-- /Small Post -->
	<? } $i++; } ?>						 
</div>

Now I can move on knowing that the class is applied properly on every post and the first two in the row of 6 are large as the theme required.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...