How to add the pagination function?

           <?php

        $callback = function($p) {
          return $p->date('Y');
        };

        $articles = page('blog')->children()->visible()->group($callback);

          foreach($articles as $year => $articlesPerYear): ?>

          <h2 class="uk-h3"><?= $year ?></h2>

            <div class="uk-child-width-1-2@s uk-grid-match" uk-grid>

              <?php foreach($articlesPerYear as $article) : ?>

                <div>

                  <a class="uk-link-reset" href="<?= $article->url() ?>">

                    <div class="uk-card uk-card-default uk-card-hover">

                      <div class="uk-card-header">
                      
                        <h3 class="uk-heading-bullet"><?= $article->title()->html() ?></h3>
                      
                      </div>

                      <div class="uk-card-body"> 

                        <p><?= $article->text()->excerpt(300) ?></p>

                      </div>

                    </div>

                  </a>

                </div> 
              
              <?php endforeach ?> 

            </div>

      <?php endforeach ?>

This is my code for grouping the blog articles on a page after the years in which they are written. But I want also a pagination after 10 articles.

I know the cookbook article but it doesn’t work or I have make a mistake. Hope someone can help me.

Thanks

Markus

While you can use pagination on the grouped collection, it will only paginate the groups, not the articles itself, so that you would end up with one (or more) group(s) per pagination page. I guess that’s not what you want and you would lose the year information as well.

If you want to show x articles per page while grouping your articles by year, you need a workaround:

<?php
//grab articles and sort by date
$articles = $page->children()->sortBy('date', 'desc')->paginate(5);
// use map function to create a "virtual" year field with the year value of the date field to make it easier to get the unique year values
$articles = $articles->map(function($p) {
  $p->year = $p->date('Y');
  return $p; 
});

// get all unique year values from articles
$years = $articles->pluck('year', ',', true);

?>

<?php 
//loop through years
foreach($years as $year): ?>
  <h2><?= $year ?></h2>
  <?php 
// loop through articles and check if the value of the year field is identical to the year
// if so, print the title
foreach($articles as $article): ?>
    <?php if($article->year() === $year): ?>
      <?= $article->title().'--'.$article->date('Y-m-d').'<br>'; ?>
    <?php endif ?>
  <?php endforeach ?>
<?php endforeach ?>

<?php snippet('pagination', ['pagination' => $articles->pagination()]) ?>

@texnixe

Thanks for the workaround. I will think about it.

I also think about an alternative where I don’t need a pagination.

This alternative could be that I only show four articles with excerpts. All older articles could be on an archive page with year grouping but without pagination. There will be show only the title (with link to the article) and the date of the article.

As I say I will think about it. And see what is easier for me in this moment of PHP learning.

Well, that’s completely up to you.

Now that I think of it, you can also use group() to group the paginated articles. So adding it here for reference, in case someone else needs this:

<?php
$callback = function($p) {
  return $p->date('Y');
};
$articles = $page->children()->sortBy('date', 'desc')->paginate(5);
$groups = $articles->group($callback);
foreach($groups as $year => $list): ?>
  <h2><?= $year ?></h2>
  <?php foreach($list as $article): ?>
    <p><?= $article->title() ?></p>
  <?php endforeach ?>
<?php endforeach ?>

@texnixe Thanks for this second solution. I think this one is something which I understand and can work with.