Jump to content

Find pages with multiple category/tags?


Lars282
 Share

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

Link to comment
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/

Link to comment
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
Link to comment
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
Link to comment
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
Link to comment
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.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...