Combine two queries into one loop

Hey guys,
Did a couple general searches, couldn’t find the solution I was looking for, maybe I didn’t pose the question right.

What I have right now is a list of items in a page’s structure that I want to be interspersed with summaries from a page’s children. Here’s what they look like one after another…

<?php foreach($page->image_blocks()->toStructure() as $image_block): ?>
  <div style="background-image:url(<?php echo $image_block->image()->toFile()->url(); ?>)" class="one-third picture-cover"></div>
<?php endforeach; ?>
<?php foreach($page->children() as $special): ?>
  <div class="one-third big-pad">
    <p>
      <a class="button" href="<?php echo $special->url(); ?>"><?php echo $special->title(); ?></a>
    </p>
    <?php echo $special->text()->kirbytext(); ?>
  </div>
<?php endforeach; ?>

This pulls some images from the parent page as well as summaries from the children, which is great, except what I’m looking to do here is fold the two together. I tried my hand at array_merge, but couldn’t get any results. Right now I’m working on a a while loop, but I’m not sure I’m building it right (the result may very well return an unequal number of the two content blocks).

Thanks in advance.

I’m not sure I understand what exactly you want to get? If I do understand you right, then you want one image block and then the first page of the children, then the next image block and the second child page etc?

If so, you could use the nth() method on the children within the first foreach loop:

<?php $i=1; foreach($page->image_blocks()->toStructure() as $image_block): ?>
  <div style="background-image:url(<?php echo $image_block->image()->toFile()->url(); ?>)" class="one-third picture-cover"></div>
<?php $special = $page->children()->nth($i); ?>
<div class="one-third big-pad">
    <p>
      <a class="button" href="<?php echo $special->url(); ?>"><?php echo $special->title(); ?></a>
    </p>
    <?php echo $special->text()->kirbytext(); ?>
  </div>
<?php $i++; endforeach; ?>

Or better yet: Count the number of structure field items first and then use a while loop if number of structure field items and number of children is likely not the same.

1 Like

Yeah, that’s the approach I’m going for. nth() was probably the function I was reaching for but couldn’t find.

I’ll give this a try, thank you.

Okay, got a plan that works, counting each of the two block types and then switching which to pull based on what’s available.

I’m including the code I went with below, maybe a little inelegant, but hopefully it’s helpful to somebody. Thanks again @texnixe - nth() was what I wanted in this case.

<?php
  $pictures = $page->image_blocks()->toStructure()->count();
  $specials = $page->children()->count();
  $i = $pictures + $specials;
  $p = 0;
  $s = 0;
  if ($pictures > 0) {
    $choose = "pictures";
  } else {
    $choose = "specials";
  }
  while ($i >= 0) {
    if ($choose == "pictures") { ?>
      <div
        style="background-image:url(<?php echo $page->image_blocks()->toStructure()->nth($p)->image()->toFile()->url(); ?>)" class="one-third picture-cover">
      </div>
      <?php 
      $p++;
      if ($s < $specials) {
        $choose = "specials";
      }
    } else if ($choose == "specials") { ?>
      <div class="one-third big-pad">
        <p>
          <a class="button" href="<?php echo $page->children()->nth($s)->url(); ?>"><?php echo $page->children()->nth($s)->title(); ?></a>
        </p>
        <?php echo $page->children()->nth($s)->text()->kirbytext(); ?>
      </div>
      <?php 
      $s++;
      if ($p < $pictures) {
        $choose = "pictures";
      }
    }
    $i--;
  }
?>