PHPackages                             aaronadal/twig-list-loop - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. aaronadal/twig-list-loop

ActiveLibrary[Templating &amp; Views](/categories/templating)

aaronadal/twig-list-loop
========================

A different way to display lists, grids and tables in Twig: the list loop.

v1.1(6y ago)17.1k↓50%2MITPHPCI failing

Since May 7Pushed 6y agoCompare

[ Source](https://github.com/aaronadal/twig-list-loop)[ Packagist](https://packagist.org/packages/aaronadal/twig-list-loop)[ RSS](/packages/aaronadal-twig-list-loop/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (2)

The Twig List Loop
==================

[](#the-twig-list-loop)

A different way to display lists, grids and tables in [Twig](https://twig.sensiolabs.org/).

Suppose you want to create several similar tables along your web application. It would be fabulous to be able to define one single template skeleton and reuse it in a flexible way, right? So, that is exactly what this Twig tag does. Let's see it in action.

Creating your first list skeleton
---------------------------------

[](#creating-your-first-list-skeleton)

Suppose you have two tables in your application: a teachers table and a students table. You probably want to create some list skeleton like this:

```
{# table.tpl.twig #}

    {% for item in list %}
        {{ item | raw }}
    {% endfor %}

```

You can now use the list loop like follows:

```
{% list teacher in teachers using 'table.tpl.twig' %}

        {{ teacher.id }}
        {{ teacher.name }}
        {{ teacher.subject }}

{% endlist %}

{% list student in students using 'table.tpl.twig' %}

        {{ student.id }}
        {{ student.name }}
        {{ student.teacher.name }}

{% endlist %}

```

As you can see, the syntax is practically the same than the for loop's one. The only difference is the `using`keyword, followed by the template used as skeleton.

Like in the for loop, you also have access to the `loop` variable and you also can specify an inline `if` expression:

```
{% list teacher in teachers if teacher.alive using 'table.tpl.twig' %}

        {{ loop.index }}
        {{ teacher.id }}
        {{ teacher.name }}
        {{ teacher.subject }}

{% endlist %}

```

`list` and `else` variables
---------------------------

[](#list-and-else-variables)

When you define a new skeleton you have access to two special variables: `list` and `else`. The former is an array containing the rendered items of the list and the later contains the rendered else statement.

Wait! The else statement? Yes, like in for loops, in list loops you can also define an else statement and display it when the list is empty:

```
{# table.tpl.twig #}
{% if list %}

        {% for item in list %}
            {{ item | raw }}
        {% endfor %}

{% else %}
    {{- else | raw -}}
{% endif %}

```

---

```
{% list teacher in teachers using 'table.tpl.twig' %}

        {{ teacher.id }}
        {{ teacher.name }}
        {{ teacher.subject }}

{% else %}
    Oops! There are no teachers.
{% endlist %}

```

**NOTE:** If an else statement is defined, the `else` variable will always contain it. It is the skeleton's job to determine whether it has to be shown or not. In the example above, it is done with a simple condition: if the list is not empty then the table is displayed, otherwise the else message is displayed.

Passing arguments to the skeleton
---------------------------------

[](#passing-arguments-to-the-skeleton)

Ok, this sounds pretty good, but... what happens if I want to add headers to the table? I can't hardcode it in my skeleton because they can vary along the different tables.

Well, I have a solution for you. In this case you can pass the table headers as an argument for the skeleton. Look at this snippet:

```
{# table.tpl.twig #}
{% if list %}
    {% if headers | default(false) %}

                {% for header in headers %}
                    {{- header -}}
                {% endfor %}

    {% endif %}

        {% for item in list %}
            {{ item | raw }}
        {% endfor %}

{% else %}
    {{- else | raw -}}
{% endif %}

```

---

```
{% set args = {
    headers: ['ID', 'Name', 'Subject']
} %}
{% list teacher in teachers using 'table.tpl.twig' with args %}

        {{ teacher.id }}
        {{ teacher.name }}
        {{ teacher.subject }}

{% else %}
    Oops! There are no teachers.
{% endlist %}

```

Pretty simple, right?

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity22

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~949 days

Total

2

Last Release

2350d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f5d7c984fc75569bfd2b6ac18e83926de2cc1a773d09b6332757563b94fe322?d=identicon)[aaronadal](/maintainers/aaronadal)

---

Top Contributors

[![aaronadal](https://avatars.githubusercontent.com/u/23636214?v=4)](https://github.com/aaronadal "aaronadal (7 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/aaronadal-twig-list-loop/health.svg)

```
[![Health](https://phpackages.com/badges/aaronadal-twig-list-loop/health.svg)](https://phpackages.com/packages/aaronadal-twig-list-loop)
```

###  Alternatives

[twig/extra-bundle

A Symfony bundle for extra Twig extensions

91492.0M315](/packages/twig-extra-bundle)[twig/intl-extra

A Twig extension for Intl

36763.2M221](/packages/twig-intl-extra)[rcrowe/twigbridge

Adds the power of Twig to Laravel

9105.9M50](/packages/rcrowe-twigbridge)[twig/string-extra

A Twig extension for Symfony String

22046.0M133](/packages/twig-string-extra)[twig/cssinliner-extra

A Twig extension to allow inlining CSS

22918.5M55](/packages/twig-cssinliner-extra)[symfony/ux-twig-component

Twig components for Symfony

21914.8M162](/packages/symfony-ux-twig-component)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
