Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Twig List Loop Laravel Package

aaronadal/twig-list-loop

Twig extension that adds a “list” tag to build reusable list/table/grid skeletons. Render items into a shared template via “using”, with access to loop plus list/else variables and optional inline if filters, similar to Twig’s for loop.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation:

    composer require aaronadal/twig-list-loop
    

    Register the Twig extension in your Laravel app’s config/app.php under providers:

    Aaronadal\TwigListLoop\TwigListLoopServiceProvider::class,
    
  2. First Use Case: Create a reusable template (table.tpl.twig) in resources/views/partials/:

    {# table.tpl.twig #}
    <table class="table">
        <tbody>
        {% for item in list %}
            {{ item | raw }}
        {% endfor %}
        </tbody>
    </table>
    

    Use it in a blade template:

    {% list user in users using 'partials/table.tpl.twig' %}
        <tr>
            <td>{{ user.id }}</td>
            <td>{{ user.name }}</td>
        </tr>
    {% endlist %}
    

Implementation Patterns

Workflows

  1. Reusable Scaffolding:

    • Define a single skeleton template (e.g., table.tpl.twig, grid.tpl.twig) for consistent layouts.
    • Pass dynamic content via the list tag, keeping markup logic in the skeleton.
  2. Dynamic Headers/Footers:

    • Use with args to inject metadata (e.g., headers, pagination links) into the skeleton:
      {% set args = { headers: ['ID', 'Name'], footer: 'Total: {{ total }}' } %}
      {% list item in items using 'skeleton.tpl.twig' with args %}
          {# row content #}
      {% endlist %}
      
  3. Conditional Rendering:

    • Leverage the else clause for empty states:
      {% list item in items using 'skeleton.tpl.twig' %}
          {# row #}
      {% else %}
          <p>No items found.</p>
      {% endlist %}
      
  4. Nested Loops:

    • Combine with Twig’s for loops for hierarchical data (e.g., nested tables):
      {# skeleton.tpl.twig #}
      {% for category in list %}
          <div class="category">
              <h3>{{ category.name }}</h3>
              <table>
                  {% for item in category.items %}
                      <tr>{{ item }}</tr>
                  {% endfor %}
              </table>
          </div>
      {% endfor %}
      

Integration Tips

  • Laravel Blade Compatibility: Prefix templates with @include if using Blade:
    {% list item in items using '@include("partials.table")' %}
    
  • Dynamic Template Paths: Store skeleton paths in a config file (e.g., config/twig-list-loop.php) for easy updates:
    'skeletons' => [
        'default' => 'partials/table.tpl.twig',
    ],
    
    Then reference via:
    {% list item in items using config('twig-list-loop.skeletons.default') %}
    

Gotchas and Tips

Pitfalls

  1. Template Caching:

    • Skeletons must be cached manually if using Laravel’s Blade cache:
      php artisan view:clear
      
    • Avoid hardcoding absolute paths in using; prefer relative paths (e.g., partials/table.tpl.twig).
  2. Variable Scope:

    • The list and else variables are only available inside the skeleton. Access them directly in the skeleton template:
      {# skeleton.tpl.twig #}
      {% if list|length > 5 %}
          <p>Showing {{ list|length }} items.</p>
      {% endif %}
      
  3. Raw Output:

    • Use | raw sparingly in skeletons to avoid XSS risks. Sanitize dynamic content (e.g., {{ header|e('html') }}).
  4. Performance:

    • Avoid complex logic in skeletons. Offload heavy processing to Laravel controllers.

Debugging

  • Check Template Paths: Use {{ dump(using_template) }} inside the list tag to verify the skeleton path is correct.
  • Empty Lists: Ensure the else clause is handled in the skeleton (not just the list tag). The else variable is always populated but may be ignored.

Extension Points

  1. Custom Tags: Extend the package by creating a custom Twig extension:

    // app/Providers/TwigServiceProvider.php
    public function boot()
    {
        $this->twig->addExtension(new class extends \Twig\Extension\AbstractExtension {
            public function getFunctions()
            {
                return [
                    new \Twig\TwigFunction('custom_list', [$this, 'renderCustomList']),
                ];
            }
        });
    }
    

    Then use in Twig:

    {{ custom_list(items, 'custom-skeleton.tpl.twig') }}
    
  2. Dynamic Arguments: Override the with behavior by extending the ListLoopNode class (advanced):

    // app/Extensions/CustomListLoopExtension.php
    class CustomListLoopExtension extends \Aaronadal\TwigListLoop\ListLoopExtension {
        public function getTokenParsers()
        {
            return [new CustomListLoopTokenParser()];
        }
    }
    
  3. Laravel Blade Directives: Create a Blade directive to bridge the gap:

    // app/Providers/BladeServiceProvider.php
    Blade::directive('list', function ($expression) {
        return "<?php echo \$__env->make('{$expression}', ['items' => $items])->render(); ?>";
    });
    

    Usage:

    @list('partials.table', ['items' => $users])
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky