How to Set Variables in a Laravel Blade Template
Asked Answered
O

31

345

I'm reading the Laravel Blade documentation and I can't figure out how to assign variables inside a template for use later. I can't do {{ $old_section = "whatever" }} because that will echo "whatever" and I don't want that.

I understand that I can do <?php $old_section = "whatever"; ?>, but that's not elegant.

Is there a better, elegant way to do that in a Blade template?

Onofredo answered 21/10, 2012 at 22:2 Comment(5)
Check this pull : github.com/laravel/laravel/pull/866Russell
This is often useful for testing, especially if you are working on the template but someone else works on the PHP part. Just be careful to remove the declaration when you are done testing.Puree
What's is wrong with simply doing <?php $old_section = "whatever"; ?>. I find it quite readable.Disfrock
@JaimeHablutzel the answer, in my opinion, is in the question: it's not elegant.Onofredo
@Onofredo Using a hack is always going to be inelegant, don't look for elegance if you want to use hacks.Fomentation
F
137

It is discouraged to do in a view so there is no blade tag for it. If you do want to do this in your blade view, you can either just open a php tag as you wrote it or register a new blade tag. Just an example:

<?php
/**
 * <code>
 * {? $old_section = "whatever" ?}
 * </code>
 */
Blade::extend(function($value) {
    return preg_replace('/\{\?(.+)\?\}/', '<?php ${1} ?>', $value);
});
Fraud answered 22/10, 2012 at 20:32 Comment(8)
Variables in views have some uses. This looks great! Where would be a good place to put this code?Onofredo
You can put it in your application/start.php or if you will have more things like this put it in a separate file and include it there. Laravel is very loose in this way, you could even put thin a controller. The only thing you have to do these extends before the view is rendered.Fraud
For LARAVEL 4 add this code to the end of the global.php file in the app/startAngleworm
What is the reasoning for adding this extra code just to use {? instead of just using the native <? ?Four
If it is discouraged to do, is there a more "proper" way to do the following? I have a site where the title is rendered in the main app view as {{ $title }}, which contains a subsystem who needs to append the page number to the title ("Application Form Page {{ $page }}") and I am passing $page to the view (which is used otherwise within the view). I don't want to build the title in each controller call, I just want to send the view the page number - just in case some day I want to change the base title. I'm using <?php $title = ... ?> now, but is there a more correct way?Brennan
Variables should be passed from the controller, not declared inline in your view. If a global template needs a variable, you can set it in a service provider https://mcmap.net/q/93083/-how-to-set-variables-in-a-laravel-blade-template. If a page specific template needs a variable, use @yield and pass it from the child view that has a controller. laravel.com/docs/5.1/blade#template-inheritanceFour
Laravel's manual points out that you can use PHP in blade templates as one of blade's strenghts. "Unlike other popular PHP templating engines, Blade does not restrict you from using plain PHP code in your views." - second sentence in the docs. I go for PHP tags. Pretty enough and absolutely easy to understand for everyone.Floater
Use @php and @endphp tags built into blade. Using this answer does not leave the variable set in the blade template in laravel 5.3+Glycerol
E
496

EASY WAY

If you want to define multiple variables, use the full form of the blade directive:

@php
   $i = 1;
   $j = 2;
@endphp

If you only want to define one variable, you can also use a single PHP statement:

@php($i = 1)

MORE ADVANCED: ADD A 'DEFINE' TAG

If you want to use custom tags and use a @define instead of @php, extend Blade like this:

/*
|--------------------------------------------------------------------------
| Extend blade so we can define a variable
| <code>
| @define $variable = "whatever"
| </code>
|--------------------------------------------------------------------------
*/

\Blade::extend(function($value) {
    return preg_replace('/\@define(.+)/', '<?php ${1}; ?>', $value);
});

Then do one of the following:

Quick solution: If you are lazy, just put the code in the boot() function of the AppServiceProvider.php.

Nicer solution: Create an own service provider. See https://mcmap.net/q/94260/-where-to-place-blade-extend on how to extend blade in Laravel 5. It's a bit more work this way, but a good exercise on how to use Providers :)

After the above changes, you can use:

@define $i = 1

to define a variable.

Emperor answered 2/9, 2014 at 8:19 Comment(10)
Nice! Please note that you can execute any php statement with your implementation. I would rename it to soemething like @php. Very handy...Nabila
Very true, igaster. You can rename 'define' to 'php' if you want, but that opens the pitfall to over-using php in your templates :)Emperor
I'm currently running the LTS (5.1) version. I had to add \ before Blade::extend... That is explained in the given link tho. But I thought it's worth to mention. Absolute elegant solution btw. +1 !Contraposition
Thanks @C.delaFonteijne, if you are using namespacing (and you should), the \ is indeed needed. I've added the \ in the code above.Emperor
Please note that almost your exact implementation is standard since Laravel 5.2. You can use @php(@i = 1) or use it in a block statement (close with @endphp)Alienation
Awsome {{-- /$i=0;/ --}} use to work with laravel 5.2 does not in 5.3 @php ($i = 1) works perfectly in 5.3Gowon
I don't see how "@php" "@endphp" is "more elegant" than "<?php" "?>". It's even a few characters longer! Is it just because it starts with a "@" like other Blade directives? We developers are some obsessive-compulsive bunch! ;-)Carmelocarmen
What is meant with your first sentence: The @php blade directive no longer accepts inline tags. Instead, use the full form of the directive ... Does that meant that @php ($i = 1) isn't valid anymore or am I misinterpreting this?Beta
@Beta indeed @php ($i = 1) should not be working anymore, although I have not tested this in the newest versions. You should now use: @php $i = 1 @endphpEmperor
@Emperor Ok thanks for confirming! I just tried it and the old syntax does still work (Laravel 8.33.1). Anyway, it's more future proof to use the new one.Beta
F
137

It is discouraged to do in a view so there is no blade tag for it. If you do want to do this in your blade view, you can either just open a php tag as you wrote it or register a new blade tag. Just an example:

<?php
/**
 * <code>
 * {? $old_section = "whatever" ?}
 * </code>
 */
Blade::extend(function($value) {
    return preg_replace('/\{\?(.+)\?\}/', '<?php ${1} ?>', $value);
});
Fraud answered 22/10, 2012 at 20:32 Comment(8)
Variables in views have some uses. This looks great! Where would be a good place to put this code?Onofredo
You can put it in your application/start.php or if you will have more things like this put it in a separate file and include it there. Laravel is very loose in this way, you could even put thin a controller. The only thing you have to do these extends before the view is rendered.Fraud
For LARAVEL 4 add this code to the end of the global.php file in the app/startAngleworm
What is the reasoning for adding this extra code just to use {? instead of just using the native <? ?Four
If it is discouraged to do, is there a more "proper" way to do the following? I have a site where the title is rendered in the main app view as {{ $title }}, which contains a subsystem who needs to append the page number to the title ("Application Form Page {{ $page }}") and I am passing $page to the view (which is used otherwise within the view). I don't want to build the title in each controller call, I just want to send the view the page number - just in case some day I want to change the base title. I'm using <?php $title = ... ?> now, but is there a more correct way?Brennan
Variables should be passed from the controller, not declared inline in your view. If a global template needs a variable, you can set it in a service provider https://mcmap.net/q/93083/-how-to-set-variables-in-a-laravel-blade-template. If a page specific template needs a variable, use @yield and pass it from the child view that has a controller. laravel.com/docs/5.1/blade#template-inheritanceFour
Laravel's manual points out that you can use PHP in blade templates as one of blade's strenghts. "Unlike other popular PHP templating engines, Blade does not restrict you from using plain PHP code in your views." - second sentence in the docs. I go for PHP tags. Pretty enough and absolutely easy to understand for everyone.Floater
Use @php and @endphp tags built into blade. Using this answer does not leave the variable set in the blade template in laravel 5.3+Glycerol
B
119

In , you can use the template comment syntax to define/set variables.

Comment syntax is {{-- anything here is comment --}} and it is rendered by engine as

<?php /* anything here is comment */ ?>

so with little trick we can use it to define variables, for example

{{-- */$i=0;/* --}}

will be rendered by as <?php /* */$i=0;/* */ ?> which sets the variable for us. Without changing any line of code.

Basilius answered 18/6, 2013 at 19:5 Comment(8)
@trying-tobemyself +1 | Not the Best-Practices way, but perfect for quick hacking of code in templates like with inline styles for html.Dubitation
I wouldn't recommend doing this hack as anyone who looks at this code after you is going to hate you.Four
Agree with Justin, comment tags are for comments, to uncomment within the comment and start doing something else is asking for troubleLifeordeath
I find this useful for debugging when stepping through a template in PHPStormBreaststroke
This is not better than plain ol' php <?php $i=0; ?>Ianteen
This could win a code obfuscation contest over on codegolf.stackexchange.comScroop
What's the point of doing this instead of using php tags?? It's not readable (looks like a comment), requires more typing, and may get broken with an update to the parsing system. Even if it has a point, it's not the answer to how to define a variable in a blade template. Don't know what's wrong with the voters, perhaps they found this so 'geeky'? meh...Rightist
this like hack life :)Forlini
E
62

There is a simple workaround that doesn't require you to change any code, and it works in Laravel 4 just as well.

You just use an assignment operator (=) in the expression passed to an @if statement, instead of (for instance) an operator such as ==.

@if ($variable = 'any data, be it string, variable or OOP') @endif

Then you can use it anywhere you can use any other variable

{{ $variable }}

The only downside is your assignment will look like a mistake to someone not aware that you're doing this as a workaround.

Externality answered 30/5, 2013 at 13:6 Comment(0)
A
40

Ya'll are making it too complicated.

Just use plain php

<?php $i = 1; ?>
{{$i}}

donesies.

(or https://github.com/alexdover/blade-set looks pretty straighforward too)

We're all kinda "hacking" the system by setting variables in views, so why make the "hack" more complicated then it needs to be?

Tested in Laravel 4.

Another benefit is that syntax highlighting works properly (I was using comment hack before and it was awful to read)

Anagnos answered 26/5, 2015 at 13:16 Comment(0)
A
28

Since Laravel 5.2.23, you have the @php Blade directive, which you can use inline or as block statement:

@php($old_section = "whatever")

or

@php
    $old_section = "whatever"
@endphp
Alienation answered 21/7, 2016 at 9:21 Comment(0)
S
23

You Can Set Variables In The Blade Templating Engine The Following Ways:

1. General PHP Block
Setting Variable: <?php $hello = "Hello World!"; ?>
Output: {{$hello}}

2. Blade PHP Block
Setting Variable: @php $hello = "Hello World!"; @endphp
Output: {{$hello}}

Streeto answered 13/5, 2018 at 5:59 Comment(0)
A
20

You can set a variable in the view file, but it will be printed just as you set it. Anyway, there is a workaround. You can set the variable inside an unused section. Example:

@section('someSection')
  {{ $yourVar = 'Your value' }}
@endsection

Then {{ $yourVar }} will print Your value anywhere you want it to, but you don't get the output when you save the variable.

EDIT: naming the section is required otherwise an exception will be thrown.

Adamson answered 10/5, 2013 at 16:19 Comment(2)
Doesn't work something else need to be included Undefined property: Illuminate\View\Factory::$startSection (View: /home/vagrant/Code/dompetspy/resources/views/reviews/index.blade.php)Accommodate
Actually that's very smart! Just call your section 'variables' and use it strictly for assigning variables in blade and voila!Lambdacism
Z
19

In laravel document https://laravel.com/docs/5.8/blade#php You can do this way:

@php
     $my_variable = 123;
@endphp
Zarathustra answered 7/3, 2020 at 11:35 Comment(1)
Why do adding already existing answers?Manualmanubrium
F
17

In Laravel 4:

If you wanted the variable accessible in all your views, not just your template, View::share is a great method (more info on this blog).

Just add the following in app/controllers/BaseController.php

class BaseController extends Controller
{
  public function __construct()
  {                   
    // Share a var with all views
    View::share('myvar', 'some value');
  }
}

and now $myvar will be available to all your views -- including your template.

I used this to set environment specific asset URLs for my images.

Four answered 6/2, 2014 at 19:55 Comment(3)
This is what I was looking for: great way to avoid duplicate calls at database!Koblick
This doesn't seem to be an option in Laravel 5?Pyrogen
@Pyrogen You still can. Syntax has changed though: https://mcmap.net/q/93083/-how-to-set-variables-in-a-laravel-blade-templateFour
G
9

Laravel 7 :

{{ $solution = "Laravel 7 is awesome and easy to use !!" }}
Grube answered 2/6, 2021 at 12:36 Comment(2)
When i define the variable like this the website print out the value of $solution, how can i fix this. So that the variable is just defined in the blade.php but is not printed out ?Nitroglycerin
which version of Laravel are you using. @MariusIllmannDorweiler
P
8

And suddenly nothing will appear. From my experience, if you have to do something like this prepare the html in a model's method or do some reorganizing of your code in to arrays or something.

There is never just 1 way.

{{ $x = 1 ? '' : '' }}
Pearman answered 27/3, 2013 at 15:53 Comment(4)
Prepare the HTML in the model? That's the ugliest thing imaginable.Onofredo
@Onofredo You're declaring and changing variables in your view. I said you're probably organizing your code wrong. Lrn 2 architect.Pearman
Sure thing, Michael... Those variables are not variables such as $users = ..., but something along the lines $css_class = ..., so strictly design variables that don't belong to the model or controller, as they are determined by the designer.Onofredo
if you need to go that route, I prefer the more simple and elegant solution: {{ ''; $x = 1 }}Jacobi
F
7

In Laravel 5.1, 5.2:

https://laravel.com/docs/5.2/views#sharing-data-with-all-views

You may need to share a piece of data with all views that are rendered by your application. You may do so using the view factory's share method. Typically, you should place calls to share within a service provider's boot method. You are free to add them to the AppServiceProvider or generate a separate service provider to house them.

Edit file: /app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

class AppServiceProvider extends ServiceProvider
{        
    public function boot()
    {
        view()->share('key', 'value');
    }

    public function register()
    {
        // ...
    }
}
Four answered 21/4, 2016 at 21:2 Comment(0)
D
7

I'm going to extend the answer given by @Pim.

Add this to the boot method of your AppServiceProvider

<?php
/*
|--------------------------------------------------------------------------
| Extend blade so we can define a variable
| <code>
| @set(name, value)
| </code>
|--------------------------------------------------------------------------
*/

Blade::directive('set', function($expression) {
    list($name, $val) = explode(',', $expression);
    return "<?php {$name} = {$val}; ?>";
});

This way you don't expose the ability to write any php expression.

You can use this directive like:

@set($var, 10)
@set($var2, 'some string')
Drisko answered 2/5, 2016 at 11:25 Comment(0)
D
6

You may use the package I have published: https://github.com/sineld/bladeset

Then you easily set your variable:

@set('myVariable', $existing_variable)

// or

@set("myVariable", "Hello, World!")
Donkey answered 11/10, 2016 at 12:29 Comment(0)
H
4

As for my elegant way is like the following

{{ ''; $old_section = "whatever"; }}

And just echo your $old_section variable.

{{ $old_section }}
Hapte answered 17/10, 2014 at 4:30 Comment(0)
D
4

If you have PHP 7.0:

The simple and most effective way is with assignment inside brackets.

The rule is simple: Do you use your variable more than once? Then declare it the first time it's used within brackets, keep calm and carry on.

@if(($users = User::all())->count())
  @foreach($users as $user)
    {{ $user->name }}
  @endforeach
@else
  There are no users.
@endif

And yes, I know about @forelse, this is just a demo.

Since your variables are now declared as and when they are used, there is no need for any blade workarounds.

Dutton answered 15/6, 2016 at 22:38 Comment(0)
J
4

Assign variable to the blade template, Here are the solutions

We can use <?php ?> tag in blade page

<?php $var = 'test'; ?>
{{ $var }

OR

We can use the blade comment with special syntax

{{--*/ $var = 'test' /*--}}
{{ $var }}
Jauregui answered 24/10, 2016 at 12:56 Comment(0)
D
4

I also struggled with this same issue. But I was able to manage this problem by using following code segment. Use this in your blade template.

<input type="hidden" value="{{$old_section = "whatever" }}">

{{$old_section }}
Discrepancy answered 27/9, 2020 at 10:16 Comment(0)
B
2

I don't think that you can - but then again, this kind of logic should probably be handled in your controller and passed into the view already set.

Bascom answered 21/10, 2012 at 22:18 Comment(3)
Some variables are strictly for views. $previous_group_name, $separator_printed, etc.Onofredo
If it is only for views, you should just pass it to the view from the controller. If you want it available to all views, see my answer above using app/controllers/BaseController.php.Four
I'm using multiple arrays to send all my $data to the viewKimon
C
2

I was looking for a way to assign a value to a key and use it many times in my view. For this case, you can use @section{"key", "value"} in the first place and then call @yield{"key"} to output the value in other places in your view or its child.

Coloring answered 22/4, 2016 at 22:15 Comment(0)
N
2

In laravel8

@php

 $name="Abdul mateen";

{{ echo $name; }}
    
@endphp
Nussbaum answered 30/1, 2022 at 5:32 Comment(0)
S
1

Hacking comments is not a very readable way to do it. Also editors will color it as a comment and someone may miss it when looking through the code.

Try something like this:

{{ ''; $hello = 'world' }}

It will compile into:

<?php echo ''; $hello = 'world'; ?>

...and do the assignment and not echo anything.

Sedgemoor answered 11/12, 2014 at 6:46 Comment(0)
H
1

It's better to practice to define variable in Controller and then pass to view using compact() or ->with() method.

Otherwise #TLGreg gave best answer.

Hammers answered 5/7, 2015 at 12:2 Comment(0)
H
1

There is a very good extention for Blade radic/blade-extensions. After you add it you can use @set(variable_name, variable_value)

@set(var, 33)
{{$var}}
Halfandhalf answered 9/12, 2015 at 13:4 Comment(0)
O
0

In my opinion it would be better to keep the logic in the controller and pass it to the view to use. This can be done one of two ways using the 'View::make' method. I am currently using Laravel 3 but I am pretty sure that it is the same way in Laravel 4.

public function action_hello($userName)
{
    return View::make('hello')->with('name', $userName);
}

or

public function action_hello($first, $last)
{
    $data = array(
        'forename'  => $first,
        'surname' => $last
    );
    return View::make('hello', $data);
}

The 'with' method is chainable. You would then use the above like so:

<p>Hello {{$name}}</p>

More information here:

http://three.laravel.com/docs/views

http://codehappy.daylerees.com/using-controllers

Otisotitis answered 15/8, 2013 at 16:37 Comment(1)
Presentation logic is best kept in the view. Sometimes, you need to create a variable from within the view. e.g. to format a date. $format='Y-m-d H:i:s'; that way you can re-use that format within the view. This certainly does not belong in the controller. That said, in response to the question... There is nothing wrong with <?php ?> tags.Mcnully
E
0

I had a similar question and found what I think to be the correct solution with View Composers

View Composers allow you to set variables every time a certain view is called, and they can be specific views, or entire view templates. Anyway, I know it's not a direct answer to the question (and 2 years too late) but it seems like a more graceful solution than setting variables within a view with blade.

View::composer(array('AdminViewPath', 'LoginView/subview'), function($view) {
    $view->with(array('bodyClass' => 'admin'));
});
Essentialism answered 18/8, 2014 at 7:12 Comment(0)
B
0

laravel 5 you can easily do this . see below

{{--*/ @$variable_name = 'value'  /*--}}
Backset answered 12/3, 2016 at 9:19 Comment(0)
S
0

You can extend blade by using the extend method as shown below..

Blade::extend(function($value) {
    return preg_replace('/\@var(.+)/', '<?php ${1}; ?>', $value);
});

after that initialize variables as follows.

@var $var = "var"
Summarize answered 19/4, 2019 at 16:59 Comment(0)
E
0

inside the blade file, you can use this format

@php
  $i++
@endphp
Efta answered 14/9, 2020 at 10:18 Comment(0)
W
-2

works in all versions of blade.

{{--*/  $optionsArray = ['A', 'B', 'C', 'D','E','F','G','H','J','K'] /*--}}
Windpipe answered 6/10, 2016 at 7:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.