Not active tags disappear

#1

I would like to filter projects by tags.
Here is projects.php controller:

<?php

return function($page) {

  // fetch the basic set of pages
  $projects = $page->children()->listed();

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

  // fetch all tags
  $tags = $projects->pluck('tags', ',', false);

  return compact('projects', 'tags', 'tag');

};

And here is template:

<?php if(count($projects->pluck('tags', ',', true)) > null): ?>
    <!-- Tags -->
    <div class="column">
      <h3 class="title"><?= $site->labelTags() ?></h3>
      <div class="tags">
        <?php foreach($projects->pluck('tags', ',', true) as $tag): ?>
        <a class="tag is-medium is-light <?php e($tag == urldecode(param('tag')), 'is-dark') ?>" href="<?= url('projects', ['params' => ['tag' => $tag]]) ?>">
          <?= $tag ?>
        </a>
        <?php endforeach ?>
      </div>
    </div>
    <?php endif ?>

It works well, but looks like it shows only the tags of projects, that are in view. For example, when I go to /projects/, then I see all tags, when I filter by some tag, then only those tags are left, that are in filtered projects.

How can I show all tags after applying tag filter?

0 Likes

#2

The problem i think is this bit, because it changes as you move through the pages, since $page means this page (as in, the one you are currently looking at) :slight_smile:

// fetch the basic set of pages
$projects = $page->children()->listed();

I think if you give it a fixed point it will stop that…

// fetch the basic set of pages
$projects = $site->find('YOURPROJECTPARENTPAGE')->children()->listed();
0 Likes

#3

Tried chaning to:
$projects = $site->find('projects')->children()->listed();

and result is the same, By the way, to make this change work, if I understand right, I also had to change top part to: return function($site, $pages, $page) {

0 Likes

#4

You need to do the same on this line too:

  // fetch all tags
  $tags = $projects->pluck('tags', ',', false);

change

  // fetch all tags
  $tags = $site->find('projects')->children()->listed()->pluck('tags', ',', false);

Since that was also picking up on $projects, which was getting filtered higher up.

I use the full set in my own filter, but yes ur right, u need those:

return function($kirby, $site, $pages, $page)
0 Likes

#5

Changed, but get the same result.

0 Likes

#6

It’s probably what you are doing in the template then… heres my own tag filter. you dont need to pluck the tags again:

<div class="categories">
  <div class="draw">
    <?php foreach($tags as $tag): ?>
    <div class="block-col">
      <a <?php e(urlencode($tag) == $currenttag, ' class="active"') ?> href="<?= url($section, ['params' => ['tag' => urlencode($tag)]]) ?>">
        <?= html($tag) ?>
      </a>
    </div>
    <?php endforeach ?>
  </div>
</div>

You can get the current tag with this in your controller, and that will put the the active class on the current tab:

  $currenttag = $kirby->request()->params()->tag();
0 Likes

#7

I think I tried something similar before, but then tags are duplicated, probably showing same tag as many times, as there are projects with it.

0 Likes

#8

Well, the above should work, it’s come from my own site. All I can suggest is working through “make a blog” cook book guide, since this is explained in there.

0 Likes

#9

I also did by that example, but it was giving duplicated tags. Maybe the reason is newest Kirby version (3.1.0)

0 Likes

#10

It works fine with the current version. Just pick over what you have done carefully and see where the mistake lies.

0 Likes

#11

Copied one more time the same code, still duplicated.

0 Likes

#12

Interesting, this code https://getkirby.com/docs/cookbook/content/filtering-with-tags#blog-controller makes duplicates but tried with this https://getkirby.com/docs/cookbook/content/filtering-with-tags#tagcloud and it works fine. Thank you for help.

0 Likes

#13

It’s the order in your controller:

<?php

return function($page) {

  // fetch the basic set of pages
  $projects = $page->children()->listed();
  
// to get all tags of all projects, put it here
// fetch all tags
  $tags = $projects->pluck('tags', ',', true); // set to true to only get unique tags
  // add the tag filter
  if($tag = urldecode(param('tag'))) {
    $projects = $projects->filterBy('tags', $tag, ',');
  }



  return compact('projects', 'tags', 'tag');

};

In your template, don’t repeat code, but use the $tags variable throughout:

<?php if(count($tags) > 0): ?>
    <!-- Tags -->
    <div class="column">
      <h3 class="title"><?= $site->labelTags() ?></h3>
      <div class="tags">
        <?php foreach($tags as $tag): ?>
        <a class="tag is-medium is-light <?php e($tag == urldecode(param('tag')), 'is-dark') ?>" href="<?= url('projects', ['params' => ['tag' => $tag]]) ?>">
          <?= $tag ?>
        </a>
        <?php endforeach ?>
      </div>
    </div>
    <?php endif ?>
1 Like