Jump to content
Violet

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

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!

Share this post


Link to post
Share on other sites

There is something similar posted over here if I'm not mistaken:

Does this help?

  • Like 3
  • Thanks 1

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites
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 3
  • Thanks 1

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.

  • Similar Content

    • By sww
      Hey there,
      i am trying to add a kind of "intelligent" search.
      Is there any way to ignore punctuation and extra chars.
      e.g.
      When I type "somebody elses" that I still get the result "SOMEBODY ELSE´S CAR, 2005"
      The problem is the extra ´ … if I don't type it I don't get the result.
      So far I am using %=query (which isn't enough, I know)
      So the idea would be something like that:
      $selector = "sanitize(title|text)%=$q, limit=50";
      I know, it's not gonna work like that … just to illustrate.
      Best,
      Stefan
    • By dandeckr
      Hello!
      I'm making my way through my first encounter with ProcessWire, and I'm very near the end of my tasks! I've searched Google, these forums, and for add-ons, but I haven't found any documentation or reference work for implementing boolean searching in the native CMS? Am I missing a thread, add-on, or docs that can point the way? I'm sure I'm not the first to have a need like this? Thanks in advance! 
    • By MateThemes
      Hello everyone!
      I am trying to add my repeater matrix fields to the search selector, but unfortunately nothing seems to work for me.
      I have following search code in my search.php:
      <?php namespace ProcessWire; // look for a GET variable named 'q' and sanitize it $q = input()->get('q'); // sanitize to text, which removes markup, newlines, too long, etc. $q = sanitizer()->text($q); // did $q have anything in it after sanitizing to text? if($q) { // Make the search query appear in the top-right search box. // Always entity encode any user input that also gets output echo '<input id="search-query" value="' . sanitizer()->entities($q) . '">'; // Sanitize for placement within a selector string. This is important for any // values that you plan to bundle in a selector string like we are doing here. // It quotes them when necessary, and removes characters that might cause issues. $q = sanitizer()->selectorValue($q); // Search the title and body fields for our query text. // Limit the results to 50 pages. The has_parent!=2 excludes irrelevant admin // pages from the search, for when an admin user performs a search. $selector = "title|body~=$q, limit=50, has_parent!=2"; // Find pages that match the selector $matches = pages()->find($selector); } else { $matches = array(); } // unset the variable that we no longer need, since it can contain user input unset($q); ?> <main pw-replace='main'> <?php include('./includes/_pageheadersearch.php'); ?> <div id='content-body' class='uk-section uk-section-large uk-section-large'> <div class='uk-container uk-container-small'> <?php // did we find any matches? if(count($matches)) { // yes we did, render them echo ukAlert(sprintf(_n('Found %d page', 'Found %d pages', $matches->count), $matches->count), "default", "check"); echo ukDescriptionListPages($matches); } else { // we didn't find any echo ukAlert(__('Sorry, no results were found'), "danger", "warning"); } ?> </div> </div> </main> I have tried to add my fields to the selector code (repeater_matrix.aboutsblock_repeaters.mytextfield) . But I didn't get any results.
      What I am doing wrong?
      Thanks for your help!
    • By BFD Calendar
      I'm getting an error from sending a search in the search box:
      "Notice: Trying to get property of non-object in /home/mekanoinsa/www/site/assets/cache/FileCompiler/site/templates/_func.php on line 45

      Fatal error: Uncaught Error: Call to a member function each() on null in /home/mekanoinsa/www/site/assets/cache/FileCompiler/site/templates/_func.php:49 Stack trace: #0 /home/mekanoinsa/www/site/assets/cache/FileCompiler/site/templates/search.php(42): renderNav(Object(ProcessWire\PageArray)) #1 /home/mekanoinsa/www/wire/core/TemplateFile.php(287): require('/home/mekanoins...') #2 /home/mekanoinsa/www/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render() #3 /home/mekanoinsa/www/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___render', Array) #4 /home/mekanoinsa/www/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array) #5 /home/mekanoinsa/www/wire/modules/PageRender.module(514): ProcessWire\Wire->__call('render', Array) #6 /home/mekanoinsa/www/wire/core/Wire.php(383): ProcessWire\PageRender->___renderPage(Object(ProcessWire\HookEvent)) #7 /home/mekanoinsa/www/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___renderPage', Array) #8 /h in /home/mekanoinsa/www/site/assets/cache/FileCompiler/site/templates/_func.php on line 49
      This is the code part in _func.php
      // markup for the text $programme = "{$item->stu_programme->title}"; $out .= "<div class='list'><div class='listtext'><span class='verdana_18_bold'><a href='$item->url'>$item->title</a></span><br><br><span class='verdana'><b>$programme</b><br>"; $out .= $item->workshops_list->each( "<font color='green'>| {title}</font>" ); // if the item has summary text, include that too if($item->summary) $out .= "<br><br>$item->summary"; // end markup for the text $out .= "</div>"; Weird, it doesn't happen all the time and I can't figure out what makes the difference....
    • By joe_ma
      Hello
      I tryed to modify the search template so as to search also descriptions of an upload field.
      $selector = "title|body|upload->description~=$q, include=hidden, limit=50"; That throws the following exception:
      Exception: Unknown Selector operator: '' -- was your selector value properly escaped?
      So how is this correctly done?
      Thanks.
×
×
  • Create New...