Show all categories/tags with pagination

I have an issue with displaying all article categories (identically to tags). Now with current code it displays all the categories used by articles but the issue is if some category is opened the category loop shows only current category instead of all categories + current one.

Blog controller:

<?php

  return function ( $site, $pages, $page ) {

    $articles = $page->children()->visible();

    if ( $category = urldecode( param( 'category' ) ) ) {
      $articles = $articles->filterBy( 'categories', $category, ',' )->sortBy( 'date' )->flip();
    } else {
      $articles = $articles->sortBy( 'date' )->flip();
    }
    
    $categories = $articles->pluck( 'categories', ',', true );

    $articles = $articles->paginate( 6 );
    $pagination = $articles->pagination();

    return compact( 'articles', 'categories', 'category', 'pagination' );

  };

?>

Blog template:

<ul class="categories">
  <?php foreach ( $categories as $category ) : ?>
    <li class="category<?php if ( $category == urlencode( param( 'category' ) ) ) : ?> category--active<?php endif; ?>">
      <a href="<?php echo url( $page->url() . '/' . url::paramsToString( [ 'category' => $category ] ) ) ?>" rel="category tag"><?= $category ?></a>
    </li>
  <?php endforeach ?>
</ul>

<?php if ( $articles->count() ) : ?>
  <ol>
    <?php foreach ( $articles as $article ) : ?>
      <li>
        <a href="<?= $article->url() ?>" rel="bookmark"><?= $article->title()->html() ?></a>
      </li>
    <?php endforeach ?>
  </ol>
<?php else: ?>
  <p>No content</p>
<?php endif ?>

<?php if ( $pagination->hasPages() ) : ?>
  <ul>
    <?php if ( $pagination->hasPrevPage() ) : ?>
      <li>
        <a href="<?= $pagination->prevPageURL() ?>" rel="prev">&lsaquo; Previous</a>
      </li>
    <?php endif ?>
    <?php if ( $pagination->hasNextPage() ) : ?>
      <li>
        <a href="<?= $pagination->nextPageURL() ?>" rel="next">Next &rsaquo;</a>
      </li>
    <?php endif ?>
  </ul>
<?php endif ?>

It’s an issue with the order of your variables, put the $categories assignment directly at the beginning after you first define your articles:

<?php

  return function ( $site, $pages, $page ) {

    $articles = $page->children()->visible();
    $categories = $articles->pluck( 'categories', ',', true );

    if ( $category = urldecode( param( 'category' ) ) ) {
      $articles = $articles->filterBy( 'categories', $category, ',' )->sortBy( 'date' )->flip();
    } else {
      $articles = $articles->sortBy( 'date' )->flip();
    }
    
    $articles = $articles->paginate( 6 );
    $pagination = $articles->pagination();

    return compact( 'articles', 'categories', 'category', 'pagination' );

  };

And better avoid the closing tag at the end of the controller :wink:

1 Like

Thank you!! :trophy:

1 Like