Search results not allowing anything with “url(…)” as part of their code

Hi there, I am building a blog, and am using the built-in core “search” feature that’s part of Kirby. I am calling a snippet (result.php) to render each search result. I reuse this results.php snippet elsewhere in site, such as an Archive page where I list every blog post, and to show collections of tagged posts that all have the same tag. This means each result module (rendered via result.php) is identical, whether it appears as a search result, an archived post, or a tag result.

I tried to dynamically call an image per result within the code in result.php, like this:

<img src="<?php echo $result->postillustration()->image()->toFile()->url() ?>" alt="">

postillustration is the name of the field in my panel/blueprints that holds the illustration for that blog post.

I like this approach because it allows the <img> tag to hold an alt attribute and ids, classes, etc.

The results render perfectly when I bring up the archive page, or select any tag to see tag results. However I get a breaking error when I search for anything that would return results. If I search for something that doesn’t exist in any content, and therefore returns no results, the page loads fine with the “no results” message I designed.

The breaking message I get is “Call to a member function url() on null”, and the de-bugger specifies the line of code I shared above.

So to fix this problem I changed the code to

<?php echo $result->postillustration()->image()->toFile() ?>

which has no url(...) in it. I don’t like this nearly as much, due to no alt tag attached to the image. At first I was alright with using this method as a last resort. However, I changed the design (it wasn’t finalized before) and would like the results to have background image (they will still have a regular image that will be an SVG that acts as a mask over part of the background image). It needs to be a background image because I am applying a transition affect to the background image (size change) on hover via CSS.

When I tried to use this code I got the same breaking error when searching would have returned results (but fine still with results elsewhere, like archives, etc):

<img src="<?php echo url('assets/images/mask.svg') ?>" alt="" style="background-image: url(<?php echo $result->postillustration()->image()->toFile()->url() ?>)" class="postillustration">

…because background images require url(...) to be used to call the image.

What can I do to do to get the core Kirby search functionality to accept url(...) ??? Or are there any not too hacky workarounds? Thanks!!! (Sorry for the long post, I just prefer to be thorough!)

The important thing here is to never ever call a method on an object that might not exist. Instead, always, always, always check for the object first:

$image = $result->postillustration()->toFile();
if($image) {
  echo $image->url();
}

If the field is empty or the file does not exist, $image will return false and the rest of the code will not be executed. All fine :slight_smile:.

Thanks, Texnixe,

However, I cannot get that code to render any image either (although it is stopping the breaking error). Instead the image’s url is being displayed as text on the screen, but I cannot figure out why.

Furthermore, I don’t see how that method will allow me to add a background image, like I’d mentioned above, adding to the <img> tag.

Could you please help me? Thank you so so much!

With the code example above, @texnixe just wanted to illustrate how to check properly if an image exists, before using the image object.

To display the image instead of the url:

<?php $image = $result->postillustration()->toFile(); ?>
<?php if($image): ?>
  <img src="<?php echo $image->url(); ?>" alt="">
<?php endif; ?>

… or even shorter …

<?php if($image = $result->postillustration()->toFile()): ?>
  <img src="<?php echo $image->url(); ?>" alt="">
<?php endif; ?>

Or in your case:

<?php if($image = $result->postillustration()->toFile()): ?>
  <img src="<?= url('assets/images/mask.svg') ?>" style="background-image: url(<?= $image->url() ?>)" alt="">
<?php endif; ?>

I see; thanks so much! It is working just as expected now. :smile: