Set Search to show all content when search field is empty

Hello,
I followed the search tutorial to set up a basic implementation of the search tool.

I’d like to ask how would you set it that, as a default value, the search result would show all content when nothing is written in the search bar.

I think that there’s something to do with the $results variable in the search.php’s controller?

<?php

return function($site, $pages, $page) {

  $query   = get('q');
  $results = page('search')->index()->visible()->search($query, 'title|text');
  $results = $results->paginate(20);

  return array(
    'query'      => $query,
    'results'    => $results,
    'pagination' => $results->pagination()
  );

};

Thanks!


UPDATE:

OK, so I thought doing something like:

  1. check if the url contains this string ?q=
  2. then hide the foreach loop showing all page’s content and show only the foreach loop with the filtered results produced by search.

Otherwise:
hide the foreach loop outputted by search and show only the one with all page’s content.

So I tried to go with an if clauses like this

<?php if($page->url() *= '?q='): ?>

but it throws back the following error

Can't use method return value in write context

How would you do it?

Here is an example.

You first define the result if no query is set, then you check if query is set:

<?php

return function($site, $pages, $page) {

  // return all children if nothing is selected
  $results = $page->children()->visible();
  $query   = get('q');

  if($query) {
    $results = $results->search($query);
  }

  $results = $results->paginate(5);
  $pagination = $results->pagination();

  return compact ('results', 'pagination', 'query');

};
1 Like

Amazing!

I was implementing the if-rule for showing a message when no result is found, and now everything works like a charm.

Thank you!

Wondering about all the search functions’ options and:

I merged search with the filter by tag function on the same page. It works, only that if I first click on a tag, which brings me to a page with this kind of url

site.dev/tags:example

and then I enter a search query, the url is updated to

site.dev/tags:example?q=test

which makes it impossible to get a proper result.

If I invert the action’s order, so first I search for something and then I filter the content by clicking on a tag, when I click on a tag the url is built from a clean base-url.

Is there a way to clear the url also for every new search query? Not only the part after =, but the full thing?

?q=eeaa


Or, alternative approach, would you suggest to:

  • keep a template only for tag-filtering, with a searchbar to insert a new query
  • but when click enter for the search to happen, the button brings to a different template only used for search purposes? Using maybe a route?

Curious to hear which kind of approach you would take!

I can’t reproduce this, I’m afraid.

With a URL like this

http://localhost/kirby/blog/tag:green?q=extending

And a controller like this:

<?php

return function($site, $pages, $page) {

  $perpage  = $page->perpage()->int();
  $query   = get('q');
  $articles = $page->children()
                   ->visible();
  if($query) {
    $articles = $articles
                     ->visible()->search($query);
  }
  if($tag = param('tag')) {
    $articles = $articles
                     ->visible()->filterBy('tags', $tag, ',');
  } 


  return [
    'articles'   => $articles,
  ];

};

I get perfectly valid results.

You are right, the filter function works perfectly when populated with enough, varied, content to search through.

Still, is there a way to reset the url to its basic root value, whenever searching through a query?

I like the options to refine a search function by using both the searchbar and tags, but I might as well try to test how it feels when using either one or the other at any time.

If you set the action attribute to the base URL, there will be no parameters:

<form class="job-form form-inline" method="GET" action="<?= $page->url() ?>">
    <input type="text" class="fsearch" name="q" id="q" placeholder="" value="<?php isset($query)? $query: ""; ?>">
    <button class="search-button" type="button" onclick="this.form.submit()"></button>
</form>
1 Like

Great, thank you once again!

Yes, your search form should have an action attribute that points to the “clean” URL.

<form action="/">
 <label>Search <input name="q"></label>
</form>

I suspect that currently your form has no action attribute, so the action URL defaults to the current URL, and only the query string (the part after ?) is modified.

1 Like