The new $loop variable in Laravel 5.3

Posted on June 27, 2016 | By Matt Stauffer


Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

Let's take a look at another new feature that's coming in Laravel 5.3.

What are Blade directives?

Laravel's Blade templating language provides something called "directives", which are custom tags—often control structures—that are prefaced with @. If you've ever written templates with Blade, you're likely familiar with @if, @foreach, and so on.

In general, these control structure directive simply emulate their PHP analogs; for example, @if(condition) is exactly the same as <?php if (condition):.

Introducing the $loop variable

In 5.3, the @foreach directive is getting a bit of a superpower, in the form of a new $loop variable that will be available inside every @foreach loop.

The $loop variable is a stdClass object that provides meta information about the loop you're currently inside. Take a look at the properties it exposes:

  • index: the 0-based index of the current item in the loop; 0 would mean "first item"
  • iteration: the 1-based index of the current item in the loop; 1 would mean "first item"
  • remaining: how many items remain in the loop; if current item is first of three, would return 2
  • count: the count of items in the loop
  • first: boolean; whether this is the first item in the loop
  • last: boolean; whether this is the last item in the loop
  • depth: integer; how many "levels" deep this loop is; returns 1 for a loop, 2 for a loop within a loop, etc.
  • parent: if this loop is within another @foreach loop, returns a reference to the $loop variable for the parent loop item; otherwise returns null

Most of this is pretty self-explanatory; it means you can do something like this:

<ul>
@foreach ($pages as $page)
   <li>{{ $page->title }} ({{ $loop->iteration }} / {{ $loop->count }})</li>
@endforeach
</ul>

But you also get a reference to parent $loop variables when you have a loop-within-a-loop. You can use depth to determine whether this is a loop-within-a-loop, and parent to grab the $loop variable of its parent. That opens up templating options like this:

<ul>
@foreach ($pages as $page)
    <li>{{ $loop->iteration }}: {{ $page->title }}
        @if ($page->hasChildren())
        <ul>
        @foreach ($page->children() as $child)
            <li>{{ $loop->parent->iteration }}.{{ $loop->iteration }}:
                {{ $child->title }}</li>
        @endforeach
        </ul>
        @endif
    </li>
@endforeach
</ul>

That's it!


Comments? I'm @stauffermatt on Twitter


Tags: laravel  •  laravel 5.3