I find myself pretty often adding $i = 0; above my @foreach loops then incrementing on each iteration. It would be nice if we could reference {{ index }} to return the current step of where we're at in the loop. It seems appropriate for a templating language. I understand this may open the door to other arbitrary indexing methods like {{ first }} and {{ last }}, in which case using https://packagist.org/packages/smarty/smarty may be a better choice anyways.
Sweet idea! Though, I'm not sure that's within the scope of how Blade was written to be honest.
Blade, when it compiles, simply replaces your openings, such as foreach with the PHP equivilent, e.g., @foreach ($foo as $bar)
is simply preg_replace'd
to be <?php foreach ($foo as $bar): ?>
.
There's no object holding each iteration of the loop in the context of compilation, unfortunately :(. If you want that, I'd be jumping ship to a full templating engine such as, as you said, smarty, or twig or something. You can easily integrate these with L4.
I highly doubt this will happen. Blade is a simple templating language which basically just makes stuff you use in PHP shorter.
To get your index like you want with {{ index }}
you just do {{ key($theArrayYouAreLoopingThrough) }}
.
As @bencorlett noted, this would be quite difficult to do in Blade. Going to defer it for now.
+1. http://twig.sensiolabs.org/doc/tags/for.html#the-loop-variable
I know this is old, but just for reference, why not just use @foreach ($array as $index => $value)
?
Hahaha so true.
@franzliedke, @robclancy : That wouldn't work with an associative array like "loop" does in twig. loop always returns the numeric index even in an associative array, whereas key() or foreach will actually return the name of the key.
Welcome to PHP.
Useful workaround example while wait for solution
/* UsersController */
$data = [
'users' => [
[
'name' => 'Juninho',
'family' => 'De Luca',
],
[
'name' => 'Homer',
'family' => 'Simpson',
],
[
'name' => 'Bart',
'family' => 'Simpson',
],
],
'i' => 0,
];
return view('users.index', $data);
/* users/index.php */
@foreach ($users as $user)
{{ $i ++ }}
@endforeach
@juninhodeluca
lol like I said: workaround ;)
@juninhodeluca a better workaround is simply put it in the view. It's view logic, afterall.
You can do it this way:
@foreach ($collection as $index => $element)
{{$index}} - {{$element['name']}}
@endforeach
For anyone waiting for a solution, implement this in your AppServiceProvider:
<?php
namespace Stori\Providers;
use Auth;
use Blade;
use Hash;
use Illuminate\Support\ServiceProvider;
use Validator;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
/**
* Does not support nesting
*/
Blade::directive('index', function($expression) {
return '<?php echo $index; ?>';
});
Blade::directive('foreachIndexed', function($expression) {
return '<?php $index = 1; foreach' . $expression . ': ?>';
});
Blade::directive('endforeachIndexed', function($expression) {
return '<?php $index++; endforeach; ?>';
});
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
@foreachIndexed($array as $key)
@index
@endforeachIndexed
@foreach ($fields as $field)
{{ array_search($field, array_keys($fields)) + 1 }}
@endforeach
@CzajekDC That will break once you nest these loops, though.
Yeah, you are right.
In a doc block should be "Do not nest!". Haha
EDIT: Updated the code with Solution #2. Added a DocBlock.
I am creating Blade directive in my service provider
\Blade::directive('var', function($expression) {
$regex = "/\((['\"])([\w_]+)\\1,\s*([^\)]+)\)/";
return preg_replace($regex, '<?php $$2 = $3; ?>', $expression);
});
Then you can easily use it in your views
@var('i', 0)
@foreach (...)
{{{ $i++ }}}
@endforeach
Sorry for bringing this once again, but thought it either could be useful for someone or someone will prove me why this is bad
This also works but looks very ugly:
{{{ '' != $i = 0 }}}
@foreach (...)
{{{ $i++ }}}
@endforeach
I find something like this to work (laravel 5.2), unless that isn't what the op is looking for
@foreach($something as $key=>$value)
{{ $key }} then {{ $value }}
@endforeach
where the $something is something like this:
[{
"id": 1,
"foo_id": "1",
"title": "Duh",
}]
It's been closed - it's already coming in 5.3 I believe.
Old thread but just to add it here as a reference for someone who found this post and looking for the answer as I did. This is now implemented in Laravel 5.3
The index can be accessed by using $loop
variable.
Refer: https://laravel.com/docs/5.3/blade#the-loop-variable
Most helpful comment
@juninhodeluca
