Help with separate 'tags' page

Hi,

For my blog, i created a separate ‘search by topic page’ ( domainname.com/tags ) where i list all tags. So far so good but there are two things that i need some help with.

a) After each tag, i would like to display the total number of articles. For example:

  • CSS (3 posts)
  • Marketing (6 posts)

b) When visiting the /tags page only the complete list of tags should be visible (no articles). As soon as a tag is clicked:

  • The page heading should contain the tag that is filtered. For example: Articles tagged with “CSS”.
  • The articles with those tags should be listed
  • The complete list of tags hided

How can I do that?


Controller:

<?php

return function($page) {

// fetch pages
$articles = page('blog')->children()->listed()->flip();

// fetch tags
$tags = $articles->pluck('tags', ',', true);
sort($tags);

// add tag filter
if($tag = urldecode(param('tag'))) {
  $articles = $articles->filterBy('tags', $tag, ',');
}

// apply pagination
$articles   = $articles->paginate(12);
$pagination = $articles->pagination();

return compact('articles', 'tags', 'tag', 'pagination');

};

Template:

<ul class="tags">
  <?php foreach($tags as $tag): ?>
    <li>
      <a href="<?= url($page->url(), ['params' => ['tag' => urlencode($tag)]]) ?>">
        <?= html($tag) ?>
      </a>
    </li>
  <?php endforeach ?>
</ul>

<?php foreach($articles as $article): ?>
  <h3><?= $article->title()->link() ?></h3>
<?php endforeach ?>

Only show articles if parameter is set:

<?php if (param('tag')) : ?>
<!-- do stuff -->
<?php endif ?>

Same logic for including the tag in the headline and hiding the tags list.

For the number of articles for each tag, I’d use a function that filters articles by the given tag and returns the count.

1 Like

Great. Thanks! Actually so simple but i couldn’t find it.

Any ideas how this should look?

In a plugin file, create a function:

function getNumberOfArticles($articles, $tag) {
  return $articles->filterBy('tags', $tag, ',')->count();
}

Then in the tags list:

<ul class="tags">
  <?php foreach($tags as $tag): ?>
    <li>
      <a href="<?= url($page->url(), ['params' => ['tag' => urlencode($tag)]]) ?>">
        <?= html($tag) . ' (' . getNumberOfArticles($articles, $tag) . ')' ?>
      </a>
    </li>
  <?php endforeach ?>
</ul>
1 Like

Thank you! I’ve learned something new.