Find page with helper e()

Hi all,
I have a question about the helper e()

I try to echo a page title by doing a page validation (with $id being the page id):
<?php e($site->find($id), $site->find($id)->title(), "No title") ?>

Expected behaviour :
I am checking if the page exists. If it exists then echo the page title. If not echo “No title”.

Current behaviour:
If the page does not exist the kirby debugger throws:
Call to a member function title() on null

If I do the page validation with a classic if-else condition I get the expected behaviour.
Can anyone explain why?

Many thanks

The reason why this is happening it’s because (I think) Kirby tries to execute this part of the code $site->find($id)->title() no matter what the initial condition ($site->find($id)) returns.

In a traditional if/else situation that part is skipped entirely which is why you get your intended behaviour.

You can probably replace it with a ternary statement like this one (untested but you get the overall idea)

<?= ($yourPage = $site->find($id)) ? $yourPage->title() : "No title" ?>

1 Like

Yes, that is true, because this bit is passed as a function parameter, so the parameter is actually executed, independently of the condition, because the condition itself is only evaluated inside the function. That means you have to pass valid parameters.

Isn’t this a syntax issue? I’m no PHP programmer, but using <?php instead of <?= when “evaluating & spitting-out” has caused similar issues for me in the past. Using the latter may solve part of this. I hope this is helpful.

No, that’s not the issue here. The e() helper actually echos something, so you would use <?php e() ?>, not <?= e()?>, because <?= is short for <?php echo`.

1 Like

thanks everyone for your input — this helped!

the developer inside me goes: “yeah, this makes sense.”
the designer inside me goes like: “hmmm, feels a little bit unintuitive” :smiley:

I hardly ever use the e() helper and use a ternary statement instead. The helper does the same internally.

1 Like

Interesting thread, thank you!

When I first encountered the e() helper and its description as a “Smart version of echo with an if condition as first argument”, I had the same intuition: I imagined some added functionality beyond being a ternary statement wrapper.

I think there would be value in having a “smart version of echo” that specifically catches the case of an invalid parameter in the function and treats it as a “false”; it would simplify working with such if-conditions in templates. The e()-helper could internally check that the parameter is valid before handing it on to r() (which is a ternary statement) and “fail silently” if it is not.

Is this something worth suggesting on the ideas repo, or am I overseeing some technical or dogmatic (the helper would essentially have to contain a catch for the error condition) limitation here?

That’s not possible, you cannot call a method on a non existing object.

For me there would be definitely value of having a real “smart version of echo”.
When I look at my code right now, the el-classico if-else-statements and ternary statements (where possible) are the main chunk of my php-code.

By the way: the r() helper fails with my example either.

The e()helper uses the r() helper internally, the only difference is that r() returns som.eting, hence r()while e() echos something

You can write your own helpers, btw.

@Mattrushka when you say

What do you have in mind? Because echo-ing something it’s a pretty “dumb” operation so I’m not sure what could you add to it to make it smart :slight_smile:

But maybe you have something in mind and I’d be happy to code something if it’s something that can be coded.

Yes, I played around with that idea I outlined above (tried to write my own e2() helper), and eventually finally understood what you had said earlier about PHP functions in general:

Please disregard my brainstorming above, I had something in mind that is indeed technically impossible :see_no_evil: Ternary operators it is… (but this helped me to finally understand why sometimes e() fails while if-else works!)

What you can do, is create a function like this, that echos a given field if the page exists:

function echoIf($page, $field = 'title') {
  echo $page ? $page->$field() : ''; // or some fallback value


<?php echoIf(page('somepage')); ?>

Will echo the title if the page exists.

<?php echoIf(page('somepage'), 'headline'); ?>

Will echo the headline if the page exists etc.

Or add a fallback param or whatever.

I would have expected the behaviour I described on my initial question: the e() helper only runs into the true value when the condition is true, without testing the true value itself. But I get your and @texnixe point that this is technically not possible.

So for me this issue is closed with the words “Hooray ternary statements!”

I don’t think there’s a holy grail function we can use here (unfortunately)
I personally use a bunch of different methods depending on what I’m doing.

There’s the or() method that is sometimes useful $page->somefield()->or($page->fallback())

There’s also the ?? operator that is also useful in some cases <?= $page->somefield() ?? $page->fallback()

Another option is to check if the page I need to use exists before I do anything else (useful depending on how the template is structured). For example, if I’m in a snippet and I’m printing content that’s tied to a specific page I usually check if the page exists at the beginning of the snippet and return if the page is not there.

Anyway, useful discussion and glad @Mattrushka got an answer :slight_smile: