Detect if currently on "search" page

Hey there,
quick question: How can I check if search results are returned in my template, would it be safe to check for something like param('q') or how would I go about this?

thx!

I am guessing you want to display a “Sorry, nothing found message”? or something similar. You can check if the results are empty. I did this in a theme i wrote ages ago, see here.

I would check for that in a controller. There is a cookbook recipe for Kirby Search too.

Sure there is, sadly that’s not my point, neither is serving a “Sorry, nothing found.” message.

I got a template that’s handling param('tag') output and normal $articles output. I want to use it for search results, too. So everytime the template is called for returning search $results, it should output eg a small search input element.

Question is, how do I check (similar to <?php if(param('tag')): ?>) if there’s the search parameter (eg ?q=) present?

I think my template will still work for you…

<?php $query = isset($_GET['q']) ? $_GET['q'] : null; // or use param('...') ?>

<?php if($query): ?>
  <!-- your search input -->
<?php endif ?>

1 Like

$_GET['q'], totally forgot about that one, thank you, Sir!

You can do $query = get('q') in Kirby as well. No need for the isset check:

$query = get('q');
if($query):
  // your code here 
else:
  // whatever you want 
endif;

Edit: Note that param('q') only works with parameters like this: example.com/q:searchword whereas get('q')works with a query string like this: example.com/?q=searchword.

Well, to be fair, I made that theme 3 years ago whilst learning Kirby for the first time. I would have followed wisdom on the forum at the time regarding the use of isset.

Might be fun to modernise that theme, i had forgotten i had made it until today. I have learnt a lot in three years, largely thanks to the efforts of @texnixe to impart wisdom. Thanks Sonja.

You are welcome :slightly_smiling_face:. Unfortunatlly, I can’t let it go uncommented if you post three year old code :wink:

And since I’m at it, there is of course an even shorter way to write the above:

if($query = get('q')):
  // your code here 
else:
  // whatever you want 
endif;

works like a charm, except one thing doesn’t:

when I’m on the second page of paginated results, eg page:2?q=example seems to fail …

my search term ($query) still gets displayed correctly, but my body class doesn’t:

<?php
if($query && $results->count() !== 0) {
  echo ' search-no-results';
} elseif($query) {
  echo ' search-results';
}

I get search-no-results, but should be search-results

// Update:

My bad, should look like this:

<?php
if($query && $results->count() == 0) {
  echo ' search-no-results';
} elseif($query) {
  echo ' search-results';
}

Offtopic:
Is there a (convenient) way to store variables globally, like in a global controller, being overridden if a specific controller defines it again?

1 Like

@daybugging You can store values in your config.php with c::set(). These values can then be retrieved using c::get(). An alternative would be a function in your plugins folders that returns a particular value and which you can call from anywhere. There is no such thing as a global controller.

Depending on your use case, you can use a default controller, but its use is pretty restricted, i.e. the default controller only works for pages with no page specific controller.

1 Like

Well, in my header, footer, some other snippets, where I don’t know / control if the respective template controller stored eg $query = get('s');, I don’t want to write this everywhere again and again, that’s simply not dry.

If that’s possible with config.php (does it have access to $page / page(), $site / site() and so on?), then that’be acceptable, using a plugin file.php sounds good, too (same question there).

Well, the problem is if you use a variable/function in your template and it is already defined in a page controller, that does not seem wise, unless you want the template/snippet to overwrite what is in the controller.

But apart from that, you can define the logic in a function, so less stuff to repeat in each controller. Yes, the Kirby and site objects are available in a plugin, it does not know anything about the page, though. So you would have to pass the page object as a parameter to the function when calling the function in a controller.