Jump to content
Lars282

Find pages with multiple category/tags?

Recommended Posts

Hey.

I have a number of pages and a number of categories (children of the search page) assigned to them via a page field. Multiple categories can be selected.

Now I have a search page, where a list of all categories with checkboxes is displayed:

foreach ($page->children() as $category) {
   echo '<input type="checkbox" name="' . $category->name . '" value="1"> ' . $category->title;
  }

How can I now find all the pages that have at least all the selected categories? I found this:

$david = $pages->get("/architects/david-childs/");
$renzo = $pages->get("/architects/renzo-piano/");
$pages->find("architect=$david|$renzo");

But as the number of selected categories is unknown, I would start by making an array? But how do I then use the array in find()?

Thanks for the help!

Lars

Share this post


Link to post
Share on other sites

You can simply use the pipe character to separate them. I would do something like this:

echo '<form action="./" method="post">'; // Change the action to the results page
 foreach ($page->children() as $category) {
     echo '<input type="checkbox" name="categorylist[' . $category . ']" value="' . $category . '"> ' . $category->title; // $category is the same as $category->id by the way
 }
 echo '<input type="submit" value="Submit" />';
echo '</form>';

Then your selector would be something like:

$categories = implode('|', $_POST['categorylist']); // This is an array of the checkboxes that are ticked from the previous page
$pages->find("id=$categories");

It's as simple as that - you can just use the pipe character: | to separate values you want to match against. More details are under OR selectors: matching one value or another about halfway down this page: http://processwire.com/api/selectors/

Share this post


Link to post
Share on other sites

For safety, good to sanitize the categories before putting them in the selector too:

$selector = "id=";
foreach($input->post->categorylist as $value) {
 $selector .= ((int) $value) . '|';
}
$pages->find(rtrim($selector, '|'));
  • Like 1

Share this post


Link to post
Share on other sites

Ryan, not so long ago I was searching for a method to typecast array items into integers. Want to share it as it applies here nicely:

$selector = 'id='.implode(array_map('intval', $input->post->categorylist),'|');
$pages->find($selector);

But I'm sure you knew it already :)

  • Like 3

Share this post


Link to post
Share on other sites

Thanks, guys!

I am confused about using id= though. I would have thought that this makes sure that the found page has this id?

I have a page field on those pages holding the categories (multiple possible), call it cats. So wouldn't I have to do something like

$selector = 'cats='.implode(array_map('intval', $input->post->categorylist),'|');
$pages->find($selector);

Also, if I now select two categories, it will return pages that are in either of the two or in both. What I want is to return pages that match all the categories (they are more like tags). Is this the way to go or is there something nicer like slkwrm's post above?

$selector = '';
foreach($input->post->categorylist as $value) {
$selector .= 'cats=' . ((int) $value) . ', ';
}
[...] // append limit etc to the selector, so last comma above ok.
$pages->find($selector);
Edited by Lars282

Share this post


Link to post
Share on other sites
I have a page field on those pages holding the categories (multiple possible), call it cats. So wouldn't I have to do something like

That's correct, if you want to find pages by a field called cats, then you'd use "cats=" instead of "id=".

Also, if I now select two categories, it will return pages that are in either of the two or in both. What I want is to return pages that match all the categories (they are more like tags). Is this the way to go or is there something nicer like slkwrm's post above?

To find pages matching all the categories, specify multiple "cats=" statements (rather than 1 split by "|" OR bars). So the code example you posted is correct.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...