Is there a Twig shorthand syntax for outputting conditional text - php

Is there a shorter syntax in Twig to output a conditional string of text?
<h1>{% if not info.id %}create{% else %}edit{% endif %}</h1>
Traditional php is even easier than this:
<h1><?php info['id']? 'create' : 'edit' ?></h1>

This should work:
{{ not info.id ? 'create' : 'edit' }}
Also, this is called the ternary operator. It's kind of hidden in the documenation: twig docs: operators
From their documentation the basic structure is:
{{ foo ? 'yes' : 'no' }}

If you need to compare the value is equal to something you can do :
{{ user.role == 'admin' ? 'is-admin' : 'not-admin' }}
You can use the Elvis Operator inside twig :
{{ user ? 'is-user' }}
{{ user ?: 'not-user' }} // note that it evaluates to the left operand if true ( returns the user ) and right if not

The null-coalescing operator also working, like:
{% set avatar = blog.avatar ?? 'https://example.dev/brand/avatar.jpg' %}

Related

Laravel 6 null coalescing operator gives Undefined variable: user when calling a method on it?

I'm trying to get this working.
<option value="{{$role->id}}" {{ (collect(old('userrole') ?? $user->roles()->pluck('id')->implode(", ") ?? '')->contains($role->id)) ? 'selected':'' }}>{{$role->name}}</option>
For some reason it won't work. It gives back the error: Undefined variable: user.
Any help?
The null-coalescing operator ?? will check if the final result is null or not - it will not take into consideration any variables that may be undeclared to obtain that result.
You can therefor use a ternary operator to see if the $roles value is set or not for that expression.
{{ (collect(
old('userrole')
?? (isset($user)
? $user->roles()->pluck('id')->implode(", ")
: ''
)
)->contains($role->id))
? 'selected'
: '' }}
The old() helper also takes a second parameter, as "default" should the value not exist, which you can use. And since you're looking for a single value, the usage of a ternary operator to output selected can be replaced by a blade #if block.
<option value="{{$role->id}}"
#if (collect(old('userrole', (isset($user) ? $user->roles()->pluck('id')->implode(", ") : ''))->contains($role->id)))
selected
#endif
>{{$role->name}}</option>
You can also reduce som cluttering in the code by using contains() on the object itself (without having to pluck() the id`).
<option value="{{ $role->id }}"
#if (collect(old('userrole', (isset($user) ? $user->roles())->contains($role->id)))
selected
#endif
>{{ $role->name }}</option>

How to use a variable in .twig syntax

I am to DRY in a twig template. I am wondering is you can access a variable in the {{ notation }} of twig.
For example:
{% if page.lang == 'en' %}
// do something
{{ content_en }}
{% endif %}
{% if page.lang == 'es' %}
// hacer algo
{{ content_es }}
{% endif %}
I tried some other approaches. But is it possible to (somehow) combine variables and do something like this:
// Php example
$var = 'content_';
$var .= page.lang;
// Output would be 'content_en';
But then for Twig?
// Something like
{{ content_ + page.lang }}
To make it more clear. I would like to access to correct variable.
$content_en = 'this is just some content';
$content_es ='Alguna informaciĆ³n';
$var = 'content_';
$var .= 'en';
$key = ${$var};
// Output is 'this is just some content'
echo $key;
If you want to concatenate the output you need to use ~
{{ 'content_' ~ page.lang }}
If you want to call a dynamic variable you need to use attribute
{{ attribute(_context, 'content_' ~ page.lang) }}
_context is a special variable in twig which containts all variables you passed towards the template
#Darabee.
You are correct, the syntax would be:
{{ attribute(_context, 'content_' ~ page.lang) }}
But how ever I noticed that if there is a array and u use '.' instead of a underscore '_' it will not work.
In my case I have a multi-array. That is the issue.
page['city']['content_en'].
or page.city.content_en

Laravel 4.2 blade: check if empty

In Laravel blade you can do:
{{ $variable or 'default' }}
This will check if a variable is set or not. I get some data from the database, and those variables are always set, so I can not use this method.
I am searching for a shorthand 'blade' function for doing this:
{{ ($variable != '' ? $variable : '') }}
It is hard to use this piece or code for doing this beacuse of, I do not know how to do it with a link or something like this:
{{ $school->website }}
I tried:
{{ ($school->website != '' ? '{{ $school->website }}' : '') }}
But, it does not work. And, I would like to keep my code as short as possible ;)
Can someone explain it to me?
UPDATE
I do not use a foreach because of, I get a single object (one school) from the database. I passed it from my controller to my view with:
$school = School::find($id);
return View::make('school.show')->with('school', $school);
So, I do not want to make an #if($value != ''){} around each $variable (like $school->name).
try this:
#if ($value !== '')
{{ HTML::link($value,'some text') }}
#endif
I prefer the #unless directive for readability in this circumstance.
#unless ( empty($school->website) )
{{ $school->website }}
#endunless
With php 7, you can use null coalescing operator. This is a shorthand for #m0z4rt's answer.
{{ $variable ?? 'default' }}
{{ ($school->website != '' ? '{{ $school->website }}' : '') }}
change to
{{ ($school->website != '') ? '' . $school->website . '' : '' }}
or the same code
{{ ($school->website != '') ? "<a href='$school->website' target='_blank'>$school->website</a>" : '' }}
{{ isset($variable) ? $variable : 'default' }}
I wonder why nobody talked about $variable->isEmpty() it looks more better than other. Can be used like:
#if($var->isEmpty())
Do this
#else
Do that
#endif
From Laravel 5.4, you can also use the #isset directive.
#isset($variable)
{{-- your code --}}
#endisset
https://laravel.com/docs/9.x/blade#if-statements

preg_match in twig

First of all, I know that the logic should be in the controller and not in the view and I keep it that way.
But in this particular situation I need to use preg_match within a ternary operation to set the css class of a div.
Example:
{% for list in lists %}
<div class="{{ (preg_match(list.a, b))>0 ? something : else }}"...>...</div>
{% endfor %}
How can I achieve the (preg_match(list.a,b))>0 condition in twig?
Thanks in advance
For those who came here from Google search results (like me).
There's containment operator that allows you to do something like this:
{{ 'cd' in 'abcde' }} {# returns true #}
You can't use preg_match() directly but there are ways to accomplish it:
if your list is an entity, add a method matches(): {{ (list.matches(b)) ? something : else }}
you could create a custom Twig extension function that uses preg_match() internally http://symfony.com/doc/master/cookbook/templating/twig_extension.html
Expanding from Serge's comment and is the correct answer.
In my example my string is "Message Taken - 12456756". I can then use |split to convert it into an array and use |replace to get ride of white space.
{% set mt = 'Message Taken' in d.note %}
{% if mt == true %}
{#.. you can then do something that is true#}
{% set mt_array = d.note|split('-') %}
{{ mt_array[0] }} | {{ mt_array[1]|replace({' ' : ''}) }}
{% endif %}
This would output my string but I now control two parts instead of 1.

Twig ternary operator, Shorthand if-then-else

Does Twig support ternary (shorthand if-else) operator?
I need some conditional logic like:
{%if ability.id in company_abilities %}
<tr class="selected">
{%else%}
<tr>
{%endif%}
but using shorthand in Twig.
{{ (ability.id in company_abilities) ? 'selected' : '' }}
The ternary operator is documented under 'other operators'
You can use shorthand syntax as of Twig 1.12.0
{{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
Support for the extended ternary operator was added in Twig 1.12.0.
If foo echo yes else echo no:
{{ foo ? 'yes' : 'no' }}
If foo echo it, else echo no:
{{ foo ?: 'no' }}
or
{{ foo ? foo : 'no' }}
If foo echo yes else echo nothing:
{{ foo ? 'yes' }}
or
{{ foo ? 'yes' : '' }}
Returns the value of foo if it is defined and not null, no otherwise:
{{ foo ?? 'no' }}
Returns the value of foo if it is defined (empty values also count), no otherwise:
{{ foo|default('no') }}
If the price exists from the database for example then print (Price is $$$) else print (Not Available) and ~ for the concatenation in Twig.
{{ Price is defined ? 'Price is '~Price : 'Not Available' }}
I just used a as a general variable name. You can also use endless if else like this:
{{ a == 1 ? 'first' : a == 2 ? 'second' : 'third' }}

Categories