Change filter like in the cookbook

Hi,

i am a php newbie and only need php to understand kirby a little bit.
I want to filter and display elements depending on a page without going to another url.
In fact i want to recreate parts of the cookbook.

my idea:
simply changing the filter on buttonclick and display different results.
but how can i change the filter via clicking an url?

 <?php
            foreach (page()->children()->filterBy('tag', $changingFilterOnButtonClick) as $subpage) : ?>
                <?= $subpage->title() ?>
            <?php endforeach ?>

I looked up some party of the cookbook to get the idea but dont understand all of it.
can someone explain this to me?
I know how to foreach works, but:
where are the $categories defined?
what is e()

From cookbook.php:

<?php foreach ($categories as $cat): ?>
        <li<?php e($category === $cat->slug(), ' aria-current') ?>>
          <a href="?category=<?= $cat->slug() ?>"></span> <?= $cat->title() ?></a>
        </li>
<?php endforeach ?>

and further.

From recipe.php:

 <?php foreach ($categories as $category) : ?>
              <li class="sidebar-item">
                <span class="sidebar-item-link">
                  More <a href="<?= url('docs/cookbook') ?>?category=<?= $category['slug'] ?>"><strong><?= $category['title'] ?></strong></a> recipes:
                </span>

                <div class="sidebar-submenu">
                  <ul class="sidebar-subpages">
                  <?php foreach($category['items'] as $related): ?>
                    <li class="sidebar-subpage">
                      <?= $related->title()->link(['class' => 'sidebar-subpage-link']) ?>
                    </li>
                  <?php endforeach ?>
                  </ul>
                </div>
              </li>
     <?php endforeach ?>

Best
Marvin

Which cookbook recipe are you referring to?

the kirby cookbook: https://getkirby.com/docs/cookbook
Sorry…

Well, I know the cookbook, but my question was: which recipe in this cookbook are you referring to?

its not one single recipe. It is the code from the cookbook.
I cloned getkirby.com from github -> and looked up the cookbook.php and the relating components

Ah, that’s a different story then.

You can get the query string like this: get('category') in this example, then you can filter your stuff using this value.

Basically, it works like using a parameter, but this is query string style instead of parameter style.

to what codeexample are u referring?

so my idea is sth like this:

<button> get everything from Category1</button>
<button> get everything from Category2</button>

 <?php
            foreach (page()->children()->filterBy('tag', $changingFilterOnButtonClick) as $subpage) : ?>
                <?= $subpage->title() ?>
            <?php endforeach ?>

So depending on wich button i click i want to change the filter.

how to i get the parameter from a button?
It would be ok if i have to do it hardcoded

You don’t. A button doesn’t change your url, you either need a link here like on the getkirby website or you have to change the url via JS if you use a button.

Bildschirmfoto von 2020-11-11 15-31-39

okey got the idea.

so my idea of filtering is like get the url <?= $page->url() ?> and check if the urls ends with category1

So:

<a class="overview__link" href="?category=content">content</a>
$category =$page->url()

    <?php foreach (page()->children()->filterBy('tag', $category) as $subpage) : ?>
                    <?= $subpage->title() ?>
                <?php endforeach ?>

it seems a little wrong to set the url as category.
can i split that in a way?

No, like a said above:

$category = get('category');

iam sorry and i am feeling so freaking dumb… got it…

I think it would work that way for me. But i am curoius.
why has the kirby cookbook this in ne cookbook-category.php?

<?php go($page->parent()->url() . '?category=' . $page->slug()) ?>

couldnt i just throw all my subpages direclty under the page with the foreach?

Because the cookbook content is divided into subfolders as categories (instead of assigning the categories to a subpage via a field). So this is a redirect, because the subfolders should not be accessible.

1 Like

Hey pixeljin,

because of your help I was able to almost finish all what I need.
the filtering via tags, the search,… and the ui + blueprints are ready too.

but I have one more problem.

I cant filter for more than one tag.
So. If i added two tags to a subpage. They wont be listed because only one tag is true…

<?php $category = get('category') ?>
  <?php foreach (page()->children()->filterBy('tags', $category) as $subpage) : ?>
                        <a href="<?= $subpage->url() ?>">
 <?php endforeach ?>

So if the category is nature, and a subpage has ONLY the tag nature, it will be shown.
If the category is nature and a subpage hast the tag nature AND the tag sport, it wont be shown…

How can i change that?

You have to put in the separator

filterBy('tags', $category, ',')

So i just finished creating the blueprints and designing the site.
I added a breadcrumb with “help” as start.
Now i want to add a href to the help, with gets back to the category choosen on the page before.

To make it simple, the first tag of the page iam on should define the category.

so i tried this

<a class="header__center__breadcrumb" href="<?= page('help')->url() ?>?category=<?= page()->tags()->split(',') ?>"> Help</a>

Since i have to two tags added to every page and i only want to use the first, i tried split. but it doesnt work…
What am i doing wrong? any idea?

if i “print” tags() it says “account, subtitles” and i only want to get the first (e.g account).

This code returns an array with all tags. Trying to echo an array will result in an error, because an array is something you have to loop through or implode before you can echo it.

To get only the first part of your array, you can access the first element by its index:

$firstTag = page()->tags()->split(',')[0];

But because we can never be sure that our array is not empty and that the index actually exists, we better do it like this:

<?= page()->tags()->split(',')[0] ?? null ?>

If the index exists, the first element will be printed, otherwise nothing.

1 Like