Jump to content

[SOLVED] Selector for search template results when wanting to sort the list of pages two ways?


Violet
 Share

Recommended Posts

I've been trying to figure this out... It seems like I'm probably missing something really simple, but I'm still puzzled as to how to move forward with this. I'd appreciate any help or suggestions anyone can give.

Aim: I'm trying to modify the default search template so that my search results come out sorted firstly with those which contain the search term in the title and secondly with those that contain it in the body.

The basic code where I made sure everything was working first was:

 

	$selector = "title|body~=$q, template=BN-article|BN-infopage, sort=-published, limit=15"; 
	// Find pages that match the selector
$matches = $pages->find($selector);
	// did we find any matches?
	if($matches->count) {
		// yes we did
$entries = $matches;
	include("./INC-main-blogroll-panels.html");
}

It gave me the search results sorted by publication date, as I expected.

Next I modified the first portion of the code by using the following to generate the matches as follows:

$matchest = $pages->find("title~=$q, template=BN-article|BN-infopage");
$matchesb = $pages->find("body~=$q, template=BN-article|BN-infopage");
$entries = $matchest->and($matchesb);

However, the problem is that $entries in my resultant displayed list did NOT start with those matches that were in the title first from $matchest. It seemed like $matchest->and($matchesb) sorted the resultant list its own way. This is even without the added complication of trying to use unique() afterward to remove duplicates - which appears to have its own default sort.

Would anyone please point me in the right direction for what what I'm seeking to do? Thank you so much!

Link to comment
Share on other sites

The key thing is to make sure $matchesb does not contain any of the pages in $matchest - otherwise the order will not be what you expect when you join the PageArrays together.

So you could use removeItems() as per my reply in the thread @szabesz linked to, or you could exclude the $matchest items in the selector for $matchesb:

$matchest = $pages->find("title~=$q, template=BN-article|BN-infopage");
$matchesb = $pages->find("body~=$q, template=BN-article|BN-infopage, id!=$matchest");
$entries = $matchest->and($matchesb);

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

Thank you @szabesz - the thread you linked to was perfect, I don't know how I missed it in my search of the Processwire forums for the word "search" ? . Oops. Yes, my situation is a simple case of the one you linked to - just what I needed. Thank you @Robin S for the response here and in that thread - the info was very valuable.

I've tried it out on my site and it's working perfectly!! ? Thank you both.?

Now I'm just trying to figure out how to use the Limit selector on the resultant array (for pagination). But thankfully the main thing is that now it's giving the results I want in the correct order.

  • Like 2
Link to comment
Share on other sites

  • Violet changed the title to [SOLVED] Selector for search template results when wanting to sort the list of pages two ways?
5 hours ago, Violet said:

Now I'm just trying to figure out how to use the Limit selector on the resultant array (for pagination).

Here are links for a few different approaches to the general question:

https://github.com/LostKobrakai/Paginator

https://gist.github.com/somatonic/5420536

https://processwire.com/talk/topic/5558-adding-pagination-after-merging-two-pagearrays/?do=findComment&comment=54122

 

And my own suggestion:

// Find all the matches, but only find the IDs to reduce memory overhead
$matchest = $pages->findIDs("title~=$q, template=BN-article|BN-infopage");
$matchest_str = implode('|', $matchest);
$matchesb = $pages->findIDs("body~=$q, template=BN-article|BN-infopage, id!=$matchest_str");
$match_ids = array_merge($matchest, $matchesb);

// Define some pagination settings
$items_per_page = 10;
$start = ($input->pageNum - 1) * $items_per_page;
$total = count($match_ids);

// Get the IDs for this page of the pagination
$item_ids = array_slice($match_ids, $start, $items_per_page);
// Get the pages using the IDs
$items = $pages->getById($item_ids);

// Apply the pagination settings to the pager
$items->setTotal($total);
$items->setLimit($items_per_page);
$items->setStart($start);

// Output the items as needed
foreach($items as $item) {
	echo "{$item->title}<br>";
}

// Output the pager
echo $items->renderPager();

 

  • Like 5
  • Thanks 1
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

×
×
  • Create New...