Limited Loop that Ignores Pagination?

There’s probably a better way to ask this. I’m working on a blog, using an ever-so-slightly modified loop from the Kirby Starter Kit for the main page:

<?php if($articles->count()): ?>
     <?php foreach($articles as $article): ?>

       <li class="single-post-summary">

         <h1><?= $article->title()->html() ?></h1>
         <span class="post-meta"><?= $article->date('F jS, Y') ?> — By <strong>Diana South</strong></span>
         <p><?= $article->text()->kirbytext()->excerpt(50, 'words') ?></p>
         <a href="<?= $article->url() ?>" class="post-link">Read More</a>

       </li>

     <?php endforeach ?>
   <?php else: ?>
     <li>No posts yet.</li>
   <?php endif ?>

I have pagination working as well.

I want another loop that -only- shows the latest five posts in a small “Recent Posts” list, but isn’t effected by the pagination, so when I go to page 2, the main list is filtered to the next 5 posts, while this smaller list only shows the most recent 5.

This is my first Kirby project. I’m sorry if this is a stupid noob question.

The best place to add this logic is in a controller, if you are using the Starter Kit you already have it, look at site/controllers/blog.php. You can change it to get the latest 5 articles and store the result in a separate variable before doing the pagination:

<?php

return function($site, $pages, $page) {
  $perpage  = $page->perpage()->int();
  $articles = $page->children()
                   ->visible()
                   ->flip();

  $latest   = $articles->limit(5);

  $articles = $articles->paginate(($perpage >= 1)? $perpage : 5);
  
  return [
    'articles'   => $articles,
    'latest'     => $latest,
    'pagination' => $articles->pagination()
  ];
};

Then you’ll have access to the $latest variable in you template and you can loop over it just like you are doing with $articles.

1 Like

And instead of putting the code for the recent articles directly into the blog template, put it in a snippet (e.g. recent-articles.php), which you can then include in your template like this:

<?php snippet('recent-articles', ['latest' => $latest]) ?>
2 Likes

I love you people. Thank you! Kirby as an experience has been amazing, but I gotta say the community has been amazing too. Thanks so much for the help!

2 Likes

For anyone that happens to have the same question, this is the exact loop I ended up putting in a snippet as per @texnixe’s suggestion:

<?php if($latest->count()): ?>

    <?php foreach($latest as $latest): ?>

        <li class="single-post-summary">

          <a href="<?= $latest->url() ?>"><?= $latest->title()->html() ?></a>

        </li>

    <?php endforeach ?>

<?php else: ?>

  <li>No posts yet.</li>

<?php endif ?>

Note @pedroborges blog controller as well. I missed a change he made moving the pagination control out of the initial “$articles” = business and my new loop was also being changed by pagination. Follow their suggestions exactly and it’s perfect!

Thanks again!