The new $loop variable in Laravel 5.3

(This is part of a series of posts on New Features in Laravel 5.3.)

  1. Introducing Laravel Echo: An In-Depth Walk-Through
  2. The new $loop variable in Laravel 5.3
  3. Customizing additional parameters in FirstOrCreate in Laravel 5.3
  4. The new cache() global helper in Laravel 5.3
  5. New JSON-column where() and update() syntax in Laravel 5.3
  6. Advanced operations with Collection::where in Laravel 5.3
  7. Image dimension validation rules in Laravel 5.3
  8. Customizing pagination templates in Laravel 5.3
  9. 5.3 feature announcement notes from Laracon
  10. Routing changes in Laravel 5.3
  11. Introducing Laravel Scout
  12. Introducing Laravel Passport
  13. Introducing Mailables in Laravel 5.3
  14. Directory structure changes in Laravel 5.3
  15. The new Notification system in Laravel 5.3
  16. Update to queue workers in Laravel 5.3
  17. Using Vue in Laravel 5.3, with the Vue bootstrap and sample component
  18. Defining console commands via closure in Laravel 5.3 (coming soon)

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:

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

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:

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

That's it!

Comments? I'm @stauffermatt on Twitter

Tags: laravel | laravel 5.3

Matt Stauffer headshot

Hi, I'm Matt Stauffer.

I'm partner & technical director at Tighten Co.

You can find me on Twitter at @stauffermatt

Like what you're reading?

I wrote an entire 450+ page book for O'Reilly: Laravel: Up and Running.

You can order the eBook or print book today.