62

I would like to know what would be the best way to display a default value if the given value is not set. I have the following in a blade file (I can not guaranty that the key is set, it depends on a multitude of factors).

{{ $foo['bar'] }}

I would know if the following is the best way to go about it,

{{ (isset($foo['bar']) ? $foo['bar'] : 'baz' }}

or is there a better way to do this?

Thanks :)

Jazerix
  • 4,729
  • 10
  • 39
  • 71
paquettg
  • 1,364
  • 1
  • 9
  • 16

6 Answers6

159

Use php's null coalesce operator:

{{ $variable ?? "Default Message" }}

Removed as of Laravel 5.7

With Laravel 4.1-5.6 you could simply do it like this:

{{ $variable or "Default Message" }}

It's the same as:

echo isset($variable) ? $variable : 'Default Message'; 
Jazerix
  • 4,729
  • 10
  • 39
  • 71
  • Wow that's nice, but don't you think logic like this should be kept out of the view? – Chris Bier Jan 20 '14 at 19:52
  • Good point. In general yes, but I see times where this can come in handy. As an example, I use this on my own site on my default template. If a title isn't sent to the view, it will echo my sites title, using the code above :). – Jazerix Jan 20 '14 at 20:59
  • But what about an error box on a login page, I need an actual if(isset($error)){
    $error
    } , not just the value contained in $error. (ps.: this was just pseudo code )
    – FMaz008 Jan 31 '14 at 20:04
  • yeah, I've also been looking a solution for that. Above code will not work that way unfortunately, it will only echo the default output – Jazerix Jan 31 '14 at 20:16
  • 1
    If the "default " is an expression (function call, ...) and not a string, then you have to use PHP's way (see @joemaller 's post) – Cedric Sep 10 '15 at 11:10
  • Using Template Variables is NOT the same as using echo. – Adam Fowler Oct 26 '15 at 18:40
  • Care to clarify? :) @AdamF If you look in your views under storage, you can seem them being translated into – Jazerix Oct 27 '15 at 00:09
  • Exactly, it's ran through the e() function first, which converts the contents to HTML Entities. – Adam Fowler Oct 27 '15 at 02:17
  • 2
    ``{{$Variable ?? "Default Message"}}` See @Edmund answer for Laravel 5.7 – Yako Nov 08 '18 at 15:56
  • 1
    Jazerix please update your answer to include Edmund Sulzanok answer for laravel 5.7 and above – Bobby Axe Mar 22 '19 at 19:59
  • @BobbyAxe Thank you, I just did that :) – Jazerix Mar 23 '19 at 23:09
21

PHP 5.3's ternary shortcut syntax works in Blade templates:

{{ $foo->bar ?: 'baz' }}

It won't work with undefined top-level variables, but it's great for handling missing values in arrays and objects.

Also, for instance, if we want to show up the date an organization was created, which might not exist (for example, if we create it manually from the DB and don't link to it any records for that field), then do something like

{{ $organization->created_at ? $organization->created_at->format('d/m/Y H:i') : "NULL" }}
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
joemaller
  • 19,579
  • 7
  • 67
  • 84
  • yes, this does. But why Laravel's shortcut doesn't work? – ssi-anik Jul 09 '15 at 14:02
  • 3
    {{ @$foo->bar ?: 'baz' }} // avoids echoing errors, when bar is not set – Cedric Sep 10 '15 at 11:11
  • 3
    this is not a good way of doing this. it might break your code if 'bar' property's value is set to zero, null or false.. it's going to print out "baz" if "bar" is one of those. – spetsnaz Nov 01 '16 at 14:38
12

Since Laravel 5.7 {{$Variable or "Default Message"}} throws $Variable is not defined. This {{$Variable ?? "Default Message"}} works though.

Edmund Sulzanok
  • 1,883
  • 3
  • 20
  • 39
  • 1
    In addition `{{$variable or 'Default Message'}}` compiles to `` instead of `echo isset($variable) ? $variable : 'Default Message';` – R. Wang Sep 24 '18 at 17:08
5

I recommend setting the default value in your controller instead of making a work-around in your view.

This is the best way because it keeps logic out of your view, and keeps the view's markup clean.

For example in your controller, before passing data to the view:

if(!isset($foo['bar'])){
     $foo['bar'] = 'baz';
}
Chris Bier
  • 14,183
  • 17
  • 67
  • 103
  • 1
    I was hopping for a template solution, maybe something like {{ $foo['bar'] | 'baz' }} but I am coming to the conclusion that this is not a feature. – paquettg Aug 02 '13 at 18:27
  • 2
    Yeah, I don't think it is, simply because that is not the purpose of the view. The view is supposed to simply display the data that is prepared beforehand in the controller. It's best to keep logic out of your view as much as possible. This keeps the concerns separated and follows MVC guidelines nicely. – Chris Bier Aug 02 '13 at 18:28
  • If you want to put it in the view, the way that you suggested looks like the best way to do it. – Chris Bier Aug 02 '13 at 19:05
2

Usually I use the null coalescing operator (introduced in PHP 7.0):

{{ $foo['bar'] ?? 'baz' }}

However, if 'baz' is actually a long expression (such as several lines of HTML, possibly with some PHP variables), then I use Blade‘s @isset (@else is optional but works):

@isset($foo['bar'])
    {{ $foo['bar'] }}
@else
    {{ $b }}
    <br>
    {{ $a }}
    <br>
    {{ $z }}
@endisset

(Taking a little liberty with the example, obviously.)

There’s also @empty($expr) which has similar syntax but works the same as the PHP function of the same name. This may be helpful: In where shall I use isset() and !empty()

Laurel
  • 5,965
  • 14
  • 31
  • 57
0

While Chris B's answer is perfectly valid; I felt perhaps this is a question that can have an alternative answer. Some would prefer not to make their controllers "fat" and in this case at least, the use of a Presenter could be the answer you seek for allowing a great deal of flexibility in your application views.

Take a look at the following project/package on Github. The readme is pretty robust with a number of examples to get you going.

It will allow you to do just what you asked and simply call

{{ $foo['bar'] }}

in your view.

twmbx
  • 105
  • 2
  • 9