Jump to content

How do I loop through a sliced array?


phil_s
 Share

Recommended Posts

I am finishing up my first processwire site (yay), and this last bit is giving me a bit of a headache:
For a news slider, I want to output x number of posts, with three posts per slide. (for a theoretically unlimited number of slides)

I figure in theory this should work something like the code below, however the looping logic, among other things :) is still somewhat beyond me:

<?php
    $items_per_page = 3;
    $start = ($pages->get("/news/")->find("sort=sort")->pageNum - 1) * $items_per_page;
    $total = count($pages->get("/news/")->find("sort=sort"));
    $slicedarticles = $pages->get("/news/")->find("sort=sort")->slice($start, $items_per_page);
    
    foreach ($slicedarticles as $slicedarticle => $total) {
        echo "<div class='slide'>";
        
        foreach ($slicedarticle as $article) {
            echo "<h3>{$article->title}</h3><p>{$article->body}</p>";
        }
        
    echo "</div>";
    }
?>

Can someone point me in the right direction with this?

Much appreciated!

Cheers,

Phil

Link to comment
Share on other sites

Not sure what kind of markup you are after, but getting and looping three posts is simple as this:

$articles = $pages->find("parent=/news/, limit=3");

foreach($articles as $article) {
  echo "<div class='slide'>$article->title</div>";
}
Link to comment
Share on other sites

@apeisa, sorry, edited the initial post to make this more clear:

I want to output x number of posts, and "package" them into slides (each slide containing three posts).

Makes more sense?

Link to comment
Share on other sites

Hm, there are several things to correct in your code. First one, and most important, is that slice() will give you only one array

$a->slice($n, $limit) -> Returns a new WireArray containing a slice of items starting from the $n'th item and including up to $limit number of items.

and I don't think this is what you are looking after.

Second one, is the way you are using the => sign in your foreach. When you do "$slicedarticle => $total", what will happen is that $slicedarticle will be populated the key of this element, and $total will be the value of the element. So, the content that you had on these variables will simply be lost. Read here http://php.net/manual/en/control-structures.foreach.php

What I interpret that you want, is to create the amount of slides needed so you have only three elements on each slide. Is that right? If so, try this:

$items_per_page = 3;

$myPages = $pages->get(1)->find('sort=sort');

$nrSlides = count($myPages)/$items_per_page;

while($nrSlides > 0) {

    echo "<div class='slide'>";

        for($i=$items_per_page; $i>0; $i--) {
            
            if(count($myPages)) {
         
                $article = $myPages->shift();

                echo "<h3>{$article->title}</h3><p>{$article->id}</p>";

            }

        }

    echo "</div>";

    $nrSlides--;
}
 

Edit: By your new explanation, I think this is what you want :)

Also, look for shift() on the cheatsheet http://cheatsheet.processwire.com/ to understand what's happening in my code:

Remove (shift) the first $item from the WireArray and return it.

Edit2: changed the if statement in the code for something better

Link to comment
Share on other sites

@apeisa, sorry, edited the initial post to make this more clear:

I want to output x number of posts, and "package" them into slides (each slide containing three posts).

Makes more sense?

$articles = $pages->find("parent=/news/, limit=18");

$out = '';
foreach ($articles as $key => $article) {
  if ($key == 0) $out .= "<div class='slide first'>"; // Open the first .slide
  else if ($key % 3 == 0) $out .= "</div><div class='slide'>"; // Close the previous slide and open next
  $out .= "<div class='post'><h2>$article->title</h2></div>"; // render the actual markup
}
$out .= "</div>"; // Close the final .slide

echo $out;

not tested and written in browser. You can omit the limit if you want to.

  • Like 2
Link to comment
Share on other sites

  • 11 months later...

@Apeisa, just went through my old posts and noticed I never replied back! Sorry, and  thank you very much, this worked perfectly!

$articles = $pages->find("parent=/news/, limit=18");

$out = '';
foreach ($articles as $key => $article) {
  if ($key == 0) $out .= "<div class='slide first'>"; // Open the first .slide
  else if ($key % 3 == 0) $out .= "</div><div class='slide'>"; // Close the previous slide and open next
  $out .= "<div class='post'><h2>$article->title</h2></div>"; // render the actual markup
}
$out .= "</div>"; // Close the final .slide

echo $out;

not tested and written in browser. You can omit the limit if you want to.

  • Like 1
Link to comment
Share on other sites

Actually there is a solution for working with slice_array. The thing is that $pages->get("/news/")... returns a PageArray thing, which is not a php array, but probably an object (not sure).

But there is a way to get this data as a php array like this:

$array=$pages->get("/news/")->getArray();

This one you can slice.

And there is a native way to slice PageArray (diogo wrote about it):

$pages->get("/news/")->slice($n, $limit). Read about it here.

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...