Filter collections by tags

Hello,

I followed the cookbook recipe for creating a collection filter by tags. But I’m not able to get it working; my code is:

<?php foreach($articles = $page->children()->listed()->sortBy('date', 'asc')->flip()->paginate(6) as $blog): ?>

And I am struggling with this:

<?php foreach($articles = $page->children()->listed()->sortBy('date', 'asc')->flip();
if($type = param('type')) {
  $articles = $articles->filterBy('typenews', $type, ',');
}->paginate(6) as $blog): ?> 

This is my blueprint:

sections:
  meta:
    type: fields
    fields:
      typenews:
        label: Blog Type
        type: radio
        options:
          news: News
          press: Press

Somehow I am struggling all night long and can’t get it working. Hope someone can help me.

Thanks in advance!

First of all, don’t ever start defining your variables inside the loop (and definitely not an if statement inside it), do it like in the cookbook recipe you mentioned (that’s why we write these things :wink:):

<?php
// First, we define our set of unfiltered articles
$articles = $page->children()->listed()->sortBy('date', 'asc'); // on a side note, I removed flipping as it is superflous, use `asc` or `desc` as required.

// In case of a URL parameter, we filter the `$articles` by the given field
// If you use spaces or other special characters in your tags, `urlencode()` the tag when creating the link and `urldecode()` again here
if ($type = param('type')) {
 $articles = $articles->filterBy('typenews', $type, ',');
}

// we apply pagination to the collection as a last step
$articles->paginate(6);

// it usually makes sense to also define the pagination object for the navigation:
$pagination = $articles->pagination();
?>

Then loop through articles

<?php foreach ($articles as $article) : ?>
<!-- your markup here -->
<?php endforeach ?>

I’d put the variables definition in a controller…

1 Like

Thanks for you help and advice. Really appreciated it!
I think I do understand what I did wrong.

Thanks again!

I am still struggling with the routing.

Using:

config.php

<?php

return [
    'debug' => true,
    'routes' => [
        [
            'pattern' => 'news/type/(:any)',
            'action' => function ($type) {
                return page('news')->render([
                    'type' => $type
                ]);
            }
        ]
    ]
];

and controller:

news.php (same name as page template.

<?php

return function ($page, $type) {

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

    if ($type) {
        $articles = $articles->filterBy('typenews', $type, ',');
    }

    return [
        'articles' => $articles
    ];

};

It seems that this should work. Where do I make a mistake?

Yes, that code should work. Unfortunately, you don’t tells us what exactly does not work.

So I can only make assumptions. Assuming that filtering doesn’t take place as expected, I wonder if you are actually using the $articles variable in your template’s foreach loop?