How to add aria-current to active filter / page

I have a portfolio page. The user can filter between different categories, using the links below.

<ul class="filter">
	<li><a href="<?= $page->url() ?>">All</a></li>
	<li><a href="<?= $page->url() ?>?filter=branding">Branding</a></li>
	<li><a href="<?= $page->url() ?>?filter=web">Web</a></li>
	<li><a href="<?= $page->url() ?>?filter=graphics">Graphics</a></li>
</ul>

I presume the current active page will stay the ‘Portfolio’ page (this will have the aria-current). My question is how can I add a class so that I can highlight the current filter/link?

I’ve tried the following, but all four links are highlighted. And I now realise that if the Portfolio page is the current page then what I really want to do is an a class to the active filter.

<ul class="filter">
	<li><a <?php e($page->isActive(), 'aria-current') ?> href="<?= $page->url() ?>">All</a></li>
	<li><a <?php e($page->isActive(), 'aria-current') ?> href="<?= $page->url() ?>?filter=branding">Branding</a></li>
	<li><a <?php e($page->isActive(), 'aria-current') ?> href="<?= $page->url() ?>?filter=web">Web</a></li>
	<li><a <?php e($page->isActive(), 'aria-current') ?> href="<?= $page->url() ?>?filter=graphics">Graphics</a></li>
</ul>

I don’t understand what’s going on.
I’d like the ‘All’ filter/page link to be highlighted when someone is on the All page (no filter). Not sure what’s possible?

$page refers to the current page and in the case of filtering, the page is always the same. So $page->isActive() will therefore always return true. The only difference is your content on the page.

Such a filter would usually look like this instead of your hard coded example:

<?php
$filterBy = get('filter');
$filters  = ['branding', 'web', 'graphics']; // in a real life example, these values would be fetched from the posts
?>
<nav class="filter">
  <ul>
      <li><a href="<?= $page->url() ?>">All</a></li>
      <?php foreach ($filters as $filter): ?>
      <li <?= $filter === $filterBy ? 'class="active"' : ''?>><a href="<?= $page->url() ?>?filter=<?= $filter ?>"><?= $filter ?></a></li>
      <?php endforeach ?>
  </ul>
</nav>

So that means the filter is active when the $filterBy variable (which fetches the query value from the request) is the same as the value in the loop.

The following is based on the kirbycasts/projects.php at main · getkirby/kirbycasts · GitHub

<?php

$filterBy = get('filter');
$unfiltered = $page->children()->listed();
$projects = $unfiltered
  ->when($filterBy, function($filterBy) {
    return $this->filterBy('categories', $filterBy);
  });

$pagination = $projects->pagination();
$filters = $unfiltered->pluck('categories', null, true);

?>


<ul class="filter">
  <li><a href="<?= $page->url() ?>">All</a><li>
  <?php foreach ($filters as $filter): ?>
  <li <?= $filter === $filterBy ? 'class="active"' : ''?>><a href="<?= $page->url() ?>?filter=<?= $filter ?>"><?= $filter ?></a></li>

  <?php endforeach ?>
</ul>


<ul class="portfolio">
<?php foreach ($projects as $project): ?>
	<li>
		<a href="<?= $project->url() ?>">
			<?php if ($image = $project->portfolio_thumbnail()->toFile()): ?>
			<img src="<?= $image->url() ?>" alt="">
			<?php endif ?>
			<p><strong><?= $project->heading()->html() ?></strong><br><?= $project->subheading()->html() ?></p>
		</a>
	</li>
<?php endforeach ?>
</ul>

It’s getting there, but the <ul class="filter"> is weird. It looks like it has combined categories:

Many case-studies should have more than one category.

Also how do I make the words start with an upper case, and to be in the order I want them to be in? I’m also not confident I know how to remove the pagination code (I don’t need the pages to be paginated).

Also how do I add the active class to All when someone is on this page?

Many thanks

If you have a comma separated list of value (like from a tags or multiselect field, then you need to pass the separator:

`$filters = $unfiltered->pluck('categories', ',', true);`