Filtering multiple tags

Hey all,

next issue :smile: . I have two tag fileds in my blueprint which apply separate kids of tags to the posts.

I output the tags (named “services”) from the first field like this:

  <?php if(param('tag')): // show service tag results ?>
<?php $tag = urldecode(param('tag'));
      $projects = $pages->find('work')
                        ->grandChildren()
                        ->visible()
                        ->filterBy('services', $tag, ',')
                        ->flip()
                        ->paginate(10);
?>

<?php foreach($projects as $project): ?>

which works nice. But can I use the same function to display the post with tags from the other field (named “client”) to? the filterBy gives me no option for this somehow…

<?php if(param('tag')): // show service tag results ?>
<?php $tag = urldecode(param('tag'));
  $projects = $pages->find('work')
                    ->grandChildren()
                    ->visible()
                    ->filterBy('services', $tag, ',')
                    ->flip()
                    ->paginate(10);
if(....) {
    $projects = $projects->filterBy('client', ...., ',');
}
?>

<?php foreach($projects as $project): ?>

Filter again like that I think or in your code:

<?php
->visible()
->filterBy('services', $tag, ',')
->filterBy('clients', $tag, ',')
->flip()

I think if you apply two consecutive filters like @ik_arno suggested in the second option , then Kirby will apply the first filter and then the second one on the filtered collection which might not be what you want to achieve, or do you?

What exactly do you want to do? Do you want a user to click on a button to display different filtered page collections? Or do you want to display one or the other on certain conditions, like in @ik_arno first example?

I’d like to filter both separately. If the user clicks tags in one tagcloud it sorts projects only after tags that exist in that cloud. and the same for the other.

none of the above solutions seem to work, but maybe i have an error in my syntax.

  <?php if(param('tag')): // show service tag results ?>
<?php $tag = urldecode(param('tag'));
      $projects = $pages->find('work')
                        ->grandChildren()
                        ->visible()
                        ->filterBy('services', $tag, ',')
                        ->flip()
                        ->paginate(10);
    if(param('tag')){ // show service tag results
$tag = urldecode(param('tag'));
      $projects = $pages->find('work')
                        ->grandChildren()
                        ->visible()
                        ->filterBy('clients', $tag, ',')
                        ->flip()
                        ->paginate(10);
                    }
?>

putting ->filterBy(…) in there twice didn’t work out at all.

You’d need to remember the tags in some way.

/page/services:design

/page/clients:google

or

/page/services:design/clients:google

Where each selected argument is added to the current url so you can get it in your controller or template and use it to filter your content.

$projects = $pages->.....

if(param('services')) {
    $projects = $projects->filterBy('services', param('services'), ',');
}
if(param('clients')) {
    $projects = $projects->filterBy('clients', param('clients'), ',');
}

mhh can’t seem to get it to work

tried it the way you suggested but it won’t work.

<?php $projects = $pages->find('work')
                        ->grandChildren()
                        ->visible()
                        ->flip()
                        ->paginate(10);

if(param('services')) {
$projects = $projects->filterBy('services', param('services'), ',');
}
if(param('recognition')) {
$projects = $projects->filterBy('clients', param('clients'), ',');
}
?>
if(param('recognition')) {
    $projects = $projects->filterBy('clients', param('recognition'), ',');
}

?

Your urls must be like /page/services:…/recognition:… :slight_smile:

but i’d like to keep the URLS clean and untouched as they are. The code i put in my first post works perfectly fine. Is there really no way to dublicate this in a way so it does the exact same thing just with “clients” instead of “services”?

Yeah, but where do get the multiple params to filter by from?

  • from the url?
  • from a form?
  • from cookies?

If you want to filter on more than one tag you’d need to store the first tag somewhere and add the next tag to filter on. Chaining filters.

I’m not sure I understand what you want after these posts :smiley:

sorry for being so unprecise. Maybe if I was a better programmer I’d be more clear :smiley:

I don’t need to sort both at the same time! Both tag clouds have no relation to each other. I just need to sort by either one of them.

scenario 1:
User opens project page -> clicks service tag “design” -> all projects, that are tagged with “design” show up

scenario 2:
User opens project page -> clicks client tag “Mercedes-Benz” -> all projects, that are tagged with “Mercedes-Benz” show up

does that help to clarify?

I think that if you change recognition to clients in that bit you should get there:

<?php $projects = $pages->find('work')
                        ->grandChildren()
                        ->visible()
                        ->flip()
                        ->paginate(10);

if($services = param('services')) {
$projects = $projects->filterBy('services', $services, ',');
}
if($clients = param('clients')) {
$projects = $projects->filterBy('clients', $clients, ',');
}
?>

What do your urls look like?

/page/tag:design and /page/tag:Mercedes-Benz?

In that case it’s pretty hard to know if you should filterby on field services or on field clients.

<?php $tag = urldecode(param('tag'));
  $projects = $pages->find('work')
                    ->grandChildren()
                    ->visible()
                    ->filterBy('services', $tag, ',')
                    ->flip()
                    ->paginate(10);
if(param('tag')) {
    $projects = $projects->filterBy('clients', $tag, ',')
}
?>

Might work? If there are no results for on services field for Mercedes-Benz it tries again on the clients field. But it might be that the first filter creates an empty $projects because no matches are found.

else

I would make two different fields from type tags in my blueprint:
services: which produces /page/services:design urls

and one:
clients: which produces /page/client:Mercedes-Benz urls

That way you can filter on param(‘services’) and/or param(‘clients’)

mh, just gives me a blank page :confused:

The first filter probably returns empty so there is nothing to filter on for the second :slight_smile:

my urls after clicking a tag are: http://localhost:8888/kirby/tag:Design

in my blueprint i have

services:
    label: Services
    type: tags
    width: 1/2
client:
    label: Client
    type: tags
    width: 1/2

no it doesn’t show anything. like if there’s an error in the code.

$projects = $projects->filterBy('clients', $tag, ',') add ; after

Else, check out https://github.com/getkirby/plugins/tree/master/tagcloud the param setting

<?php $tagcloud = tagcloud(page('blog'), array('limit' => 20, 'param' => 'services')) ?>

That should create urls like /page/services:design instead of /page/tag:design

Your urls in your links are wrong: for the services, it should be http://localhost:8888/kirby/services:Design

and for the clients (or client?)

http://localhost:8888/kirby/clients:Mercedes-Benz

Otherwise it can’t get the right parameter, so you have to adjust the links in your tag cloud snippet …

[Edit] Let me clarify why:

param('services')

analyzes the url and checks if the parameter is there … so that would be true for a URL like

http://localhost:8888/kirby/services:Design

but not for

http://localhost:8888/kirby/tag:Design or
http://localhost:8888/kirby/

so if the href attribute in the link that you click when you want to filter, contains “tag” instead of “services”, the whole thing will return nothing.

1 Like

Okay I got it. atl lieast that URL thing.

I display my tags with this code:

<?php foreach(str::split($page->services()) as $tag): ?>
<a href="<?php echo url('services:' . urlencode($tag)) ?>"><?php echo $tag; ?></a>, 
 <?php endforeach ?>

but for your code texnixe, my home page still shows up blank. it doesnt even load the other site elements.

@bogus was this ever resolved? I’m having a similar issue. I tried to “duplicate” the existing tag field and insert my new tag field with a different name and could not figure it out. My end goal is to have 6 different filters. @texnixe it doesn’t seem like your solution worked here. Did you two resolve this problem in a pm?