My filtering via routes does not work

Hello guys,

I am a little bit overwhelmed with filtering via routes. My problem is that I haven’t learned PHP so far, so I don’t understand how to apply the guides from the docs to my site. First I gonna describe what I want to archive:

I want to build a site for my friends where they can upload short video clips from the video games. Every video page should have different categories.

  1. Which game (Valorant, Among Us, …)
  2. Which player (Nickname)
  3. Optional tags (Win, fail, funny, etc)

In my content root folder, I have an unlisted page called “Games” with every game as a subpage. The same with “Players”.

The blueprint for the video page has two multiselect fields. With the first one, the user can select a game from the games subpages and with the second from the players subpages. After that there comes a tags field.

categories:
  label: Game
  type: multiselect
  max: 1
  options: query
  query: 
    fetch: site.find('games').children
    text: "{{ page.title }}"
    value: "{{ page.title }}"
players:
  label: Spieler/in
  type: multiselect
  options: query
  query: 
    fetch: site.find('player').children
    text: "{{ page.title }}"
    value: "{{ page.title }}"
tags:
  label: Tags
  query: page.siblings.pluck("tags", ",", true)

On frontend side, I print the game, the player and the tags. Now the user should be able to click on a game, and should be able to see all videos from this game. The same with the player and tags.

<div class="box-links">

   <?php foreach ($subpage->categories() as $category): ?>
      <a href="<?= $site->url() ?>/<?= $category ?>" class="button <?= $category ?>"><?= $category ?></a>
   <?php endforeach ?>

   <?php foreach ($subpage->players() as $player): ?>
      <a href="<?= $site->url() ?>/<?= $player ?>" class="button player"><?= $player ?></a>
   <?php endforeach ?>

   <?php foreach ($subpage->tags()->split() as $tag): ?>
      <a href="<?= $site->url() ?>/<?= $tag ?>" class="tag"><?= $tag ?></a>&nbsp;
   <?php endforeach ?>

</div>

Now I thought it could be a way to make the link like this: domain.com/valorant or domain.com/nickname Kirby reads that and does the filtering. I made my config and controller like this, but when I click on the game link, I get the error page with the default template. I want to print the homepage with home.php template with filtered posts.

config:

return [
  'routes' => [
    [
      'pattern' => '/valorant',
      'action' => function ($categories) {
        return page('home')->render([
          'categories' => $categories
        ]);
      }
    ]
  ]
];

controller:

return function ($site, $categories) {

    $videos = $site
    ->find('home')
    ->children()
    ->listed();

    if ($categories) {
        $videos = $videos->filterBy('categories', $categories);
    }

    return [
        'videos' => $videos
    ];

};

(I havn’t use the (:any) placeholder because I wanted to get this thing working first.)

I tried several days now to understand the docs and other posts in the forum but I can’t solve this issue.

Your route doesn’t have an argument and shouldn’t start with a slash. If you want to use valorant as a value in $categories, it should look like this:

'pattern' => '(valorant)',

However, such a hardcoded value is not very useful.

Yea, but it does not work with (valorant) or (:any).

I assume the error maybe here?

return page('home')->render([
          'categories' => $categories
        ]);

Well, you return the home page, but for which page is the controller?

also home.php

Ok, categories is a multiselect field, so that stuff is stored as a comma separated list. Therefore the filter method needs a third parameter, the delimiter.

 $videos = $videos->filterBy('categories', $categories, ',');

Nevertheless, valorant needs to be in parenthesis, otherwise using $categories as function parameter will throw an error.

Ok I tried your suggestions. But there is still something wrong. (valorant) or (:any) in the config will bring me the error page.

config:

return [
  'routes' => [
    [
      'pattern' => '(:any)',
      'action' => function ($categories) {
        return page('home')->render([
          'categories' => $categories
        ]);
      }
    ]
  ]
];

controller home.php

return function ($site, $categories) {

    $videos = $site
    ->find('home')
    ->children()
    ->listed();

    if ($categories) {
        $videos = $videos->filterBy('categories', $categories, ',');
    }

    return [
        'videos' => $videos
    ];
};

Using any doesn’t make sense, because that will catch all first level pages, so if you don’t catch these cases, you’ll be in trouble.

I don’t understand why '(valorant)` doesn’t work.Do you have a multi-language site?

No. Hmm. Maybe I show my content structure:

– 1_home
– – videosubpage
– – videosubpage
– – videosubpage
– error
– games
– – valorant
– – among-us
– player
– – nickname1
– – nickname2

Is there any other information missing?

What is in those videosubpages, these are the ones you are filtering and do they have a categories field?

Yes, I want to filter these subpages and yes, they have a categories field as shown in my first post. The blueprint I posted there is from the video subpage.