📦 Marketplace⭐ GitHub
Templates & Assetsv2.0

Template

MLView is the built‑in, high‑performance template engine for MonkeysLegion, designed for clean, component‑driven views with minimal boilerplate. Inspired by Blade, Twig, Jinja2, and Phoenix LiveView — with multi-tier caching and 0.015 ms/render performance.

monkeyscloud/monkeyslegion-template v2.0
PHP 8.4+ | MIT License
476 tests | 902 assertions | PHPStan Level 8

Table of Contents

  1. Installation
  2. Quick Start
  3. Output & Echoes
  4. Filters (Pipe Syntax)
  5. Control Structures
  6. Loops & The $loop Variable
  7. Components & Slots
  8. Layout Inheritance
  9. Stacks & Asset Management
  10. Template Inclusion
  11. Frontend Helpers
  12. Form Helpers
  13. Framework Utilities
  14. Advanced Directives
  15. Fragment Caching
  16. Template Macros
  17. Element-Level Directives (HEEx-Style)
  18. Namespaces & Theming
  19. View Composers & Events
  20. Streaming & Async
  21. Security
  22. Caching Architecture
  23. Performance
  24. Testing
  25. CLI Tooling
  26. Extensibility

Installation

composer require monkeyscloud/monkeyslegion-template

Optional dependencies:

PackagePurpose
psr/simple-cachePSR-16 cache backend (Redis/Memcached)
monkeyscloud/monkeyslegion-cacheFull-featured caching with tags & locks
monkeyscloud/monkeyslegion-diClass-based component DI
monkeyscloud/monkeyslegion-cliCLI commands (view:compile, lint)

Quick Start

Directory Structure

my-app/
├─ resources/views/
│  ├─ home.ml.php              # Top-level view
│  ├─ posts/
│  │  └─ show.ml.php           # Nested: posts.show
│  ├─ layouts/
│  │  └─ app.ml.php            # Layout template
│  └─ components/
│     ├─ alert.ml.php          # <x-alert> component
│     └─ card.ml.php           # <x-card> component
└─ var/cache/views/             # Compiled PHP (auto-generated)

Hello World

// resources/views/hello.ml.php
<h1>Hello, {{ $name }}!</h1>
use MonkeysLegion\Template\{Loader, Parser, Compiler, Renderer, MLView};

$loader   = new Loader('resources/views', 'var/cache/views');
$parser   = new Parser();
$compiler = new Compiler($parser);
$renderer = new Renderer($parser, $compiler, $loader, true, 'var/cache/views');

$view = new MLView($loader, $compiler, $renderer, 'var/cache/views');

echo $view->render('hello', ['name' => 'Alice']);
// Output: <h1>Hello, Alice!</h1>

First call: parse → compile → cache. Subsequent calls: include cached PHP directly.

Dot-notation resolves paths:

  • homeresources/views/home.ml.php
  • posts.showresources/views/posts/show.ml.php

Output & Echoes

Escaped Output

{{ $name }}                    {{-- HTML-escaped: <script> → &lt;script&gt; --}}
{{ $user->name }}              {{-- Object property --}}
{{ $count > 0 ? 'Yes' : 'No' }}  {{-- Expressions --}}

Raw Output

{!! $trustedHtml !!}           {{-- Unescaped — use responsibly --}}

Comments

{{-- This comment is removed from compiled output --}}

PHP Blocks

@php
    $total = array_sum($prices);
@endphp

Filters (Pipe Syntax)

Inspired by Twig/Jinja2. Apply transformations via |:

{{ $name | upper }}                          {{-- ALICE --}}
{{ $name | lower | capitalize }}             {{-- Alice --}}
{{ $text | truncate(50, '...') }}            {{-- First 50 chars... --}}
{{ $price | number(2, '.', ',') }}           {{-- 1,234.56 --}}
{{ $items | pluck('name') | join(', ') }}    {{-- Item1, Item2, Item3 --}}
{{ $html | raw }}                            {{-- Skip escaping --}}

Built-in Filters (35+)

CategoryFilters
Stringupper, lower, capitalize, title, trim, length, reverse, repeat, replace, split, slug, nl2br, truncate
Numbernumber, abs, max, min
Arrayjoin, first, last, count, sort, keys, values, unique, flatten, chunk, pluck, merge
Datedate — works with DateTime, timestamps, and strings
Encodingjson, e, escape, raw
Utilitydefault, prepend, append, wrap, pad, wordcount, excerpt, batch, map, filter, sum, avg

Examples

{{-- Date formatting --}}
{{ $createdAt | date('M d, Y') }}            {{-- Jan 15, 2026 --}}

{{-- Default values --}}
{{ $nickname | default('Anonymous') }}

{{-- Array manipulation --}}
{{ $users | pluck('email') | unique | count }}

{{-- Chaining --}}
{{ $bio | truncate(100) | nl2br }}

{{-- JSON output --}}
{{ $config | json }}

Custom Filters

$view->addFilter('currency', fn($v) => '$' . number_format($v, 2));
// Usage: {{ $price | currency }}

Control Structures

Conditionals

@if($user->isAdmin())
    <span class="badge">Admin</span>
@elseif($user->isModerator())
    <span class="badge">Mod</span>
@else
    <span class="badge">User</span>
@endif

Conditional Sugar

@unless($isAdmin)
    You are not an admin.
@endunless

@isset($records)
    Found {{ count($records) }} records.
@endisset

@empty($results)
    No results found.
@endempty

Switch

@switch($status)
    @case('active')
        <span class="green">Active</span>
    @break
    @case('pending')
        <span class="yellow">Pending</span>
    @break
    @default
        <span class="gray">Unknown</span>
@endswitch

Loops & The $loop Variable

@foreach

Every @foreach provides a $loop variable with iteration metadata:

@foreach($users as $user)
    @if($loop->first)
        <div class="first-item">
    @endif

    <p>{{ $loop->iteration }}. {{ $user->name }}</p>

    @if($loop->last)
        </div>
    @endif
@endforeach

$loop properties:

PropertyTypeDescription
$loop->indexintZero-based index
$loop->iterationintOne-based index
$loop->remainingintItems remaining
$loop->countintTotal items
$loop->firstboolIs first iteration
$loop->lastboolIs last iteration
$loop->evenboolIs even iteration
$loop->oddboolIs odd iteration
$loop->depthintNesting depth (1+)
$loop->parent?LoopParent loop (nested)

@forelse

@forelse($posts as $post)
    <h2>{{ $post->title }}</h2>
@empty
    <p>No posts found.</p>
@endforelse

@for / @while

@for($i = 0; $i < 10; $i++)
    {{ $i }}
@endfor

@while($condition)
    Processing...
@endwhile

Loop Control

@foreach($items as $item)
    @if($item->hidden)
        @continue
    @endif
    @if($loop->iteration > 5)
        @break
    @endif
    {{ $item->name }}
@endforeach

Components & Slots

Using Components

{{-- Simple component --}}
<x-alert type="warning">
    Watch out!
</x-alert>

{{-- Self-closing --}}
<x-badge text="Active" color="green" />

{{-- With named slots --}}
<x-card>
    <x-slot:header>
        Card Title
    </x-slot:header>

    Main content goes here.

    <x-slot:footer>
        <button>Save</button>
    </x-slot:footer>
</x-card>

Creating Components

{{-- resources/views/components/alert.ml.php --}}
@param(['type' => 'info', 'dismissible' => false])

<div class="alert alert-{{ $type }}" {{ $attributes }}>
    @if($slots->has('header'))
        <strong>{{ $slots->header }}</strong>
    @endif

    <div class="alert-body">{{ $slot }}</div>

    @if($dismissible)
        <button class="btn-close" data-dismiss="alert"></button>
    @endif
</div>

Function Components

Lightweight, closure-based components — no template file needed:

$view->component('badge', fn(string $text, string $color = 'blue') =>
    "<span class=\"badge bg-{$color}\">" . htmlspecialchars($text) . "</span>"
);

// Usage: <x-badge text="New" color="green" />

Attribute Bag

All extra attributes are collected in $attributes:

{{-- Component template --}}
<div {{ $attributes->merge(['class' => 'card']) }}>
    {{ $slot }}
</div>

{{-- Usage --}}
<x-card class="shadow-lg" id="my-card">Content</x-card>
{{-- Output: <div class="card shadow-lg" id="my-card">Content</div> --}}

Component Data

Inside a component:

VariableDescription
$slotDefault slot content
$slots->nameNamed slot content
$slots->has('name')Check if named slot exists
$attributesAttributeBag with all passed attributes
@aware(['key' => 'default'])Access parent component data

Layout Inheritance

Parent Layout

{{-- resources/views/layouts/app.ml.php --}}
<!DOCTYPE html>
<html>
<head>
    <title>@yield('title', 'My App')</title>
    @stack('styles')
</head>
<body>
    <nav>@yield('nav')</nav>

    <main>
        @yield('content')
    </main>

    @stack('scripts')
</body>
</html>

Child View

{{-- resources/views/home.ml.php --}}
@extends('layouts.app')

@section('title')
    Home Page
@endsection

@section('content')
    <h1>Welcome!</h1>
    <p>This is the home page.</p>
@endsection

@push('scripts')
    <script src="/js/home.js"></script>
@endpush

Stacks & Asset Management

Push CSS/JS from any child view or component into named stacks in the layout:

{{-- In layout --}}
<head>
    @stack('styles')
</head>
<body>
    @yield('content')
    @stack('scripts')
</body>

{{-- In child view or component --}}
@push('scripts')
    <script src="app.js"></script>
@endpush

@prepend('styles')
    <link rel="stylesheet" href="critical.css">
@endprepend

{{-- Push once (dedup) --}}
@pushOnce('scripts')
    <script src="shared-lib.js"></script>
@endPushOnce

Template Inclusion

{{-- Basic include --}}
@include('partials.header')

{{-- Include with data --}}
@include('partials.alert', ['type' => 'warning', 'message' => 'Heads up!'])

{{-- Conditional includes --}}
@includeWhen($isLoggedIn, 'nav.user-menu')
@includeUnless($isAdmin, 'nav.guest-menu')

{{-- Include first match --}}
@includeFirst(['custom.admin', 'admin.dashboard'], ['data' => $data])

{{-- Include if exists --}}
@includeIf('optional.sidebar')

Frontend Helpers

DirectiveExampleOutput
@json($data)@json($config)Safe JSON in HTML
@js($data)@js($settings)JS-safe (unescaped unicode)
@class([...])@class(['btn', 'active' => $isActive])class="btn active"
@style([...])@style(['color: red' => $isError])style="color: red"
<button @class(['btn', 'btn-primary' => $isPrimary, 'disabled' => !$enabled])>
    Submit
</button>

<div @style(['background: red' => $hasError, 'font-weight: bold' => $important])>
    Content
</div>

<script>
    const config = @json($appConfig);
</script>

Form Helpers

<form method="POST" action="/users">
    @csrf
    @method('PUT')

    <input type="text" name="name" value="@old('name', $user->name)">

    <input type="checkbox" @checked($user->isAdmin)>

    <select>
        @foreach($roles as $role)
            <option value="{{ $role }}" @selected($role === $currentRole)>
                {{ $role }}
            </option>
        @endforeach
    </select>

    <input type="text" @disabled(!$canEdit)>
    <textarea @readonly($isLocked)></textarea>

    @error('name')
        <span class="error">{{ $message }}</span>
    @enderror
</form>

Framework Utilities

Environment Checks

@env('production')
    {{-- Only in production --}}
    <script src="analytics.js"></script>
@endenv

@production
    {{-- Shorthand for @env('production') --}}
@endproduction

Authentication

@auth
    Welcome, {{ auth()->user()->name }}!
@endauth

@guest
    <a href="/login">Login</a>
@endguest

Authorization

@can('edit', $post)
    <a href="/posts/{{ $post->id }}/edit">Edit</a>
@endcan

@cannot('delete', $post)
    <span class="text-muted">Cannot delete</span>
@endcannot

Session

@session('success')
    <div class="alert alert-success">{{ $value }}</div>
@endsession

Service Injection

@inject('metrics', 'App\Services\MetricsService')

<div>Monthly visits: {{ $metrics->getMonthlyVisits() }}</div>

Advanced Directives

HTMX Fragment Rendering

Render only a fragment for HTMX partial updates:

<div id="user-list">
    @fragment('user-table')
        <table>
            @foreach($users as $user)
                <tr><td>{{ $user->name }}</td></tr>
            @endforeach
        </table>
    @endfragment
</div>

Teleport

Move content to a different DOM location (like Vue's <Teleport>):

@teleport('#modals')
    <div class="modal">Modal content</div>
@endteleport

Persist (HTMX)

Mark elements that should persist across HTMX morph-merges:

@persist('audio-player')
    <audio id="player" src="{{ $track->url }}"></audio>
@endpersist

Model Type Hints (IDE Support)

@model(App\Entity\User)
{{-- IDE autocomplete now knows $model is a User --}}
<h1>{{ $model->name }}</h1>

Once

@once
    <script src="shared-component.js"></script>
@endonce

Verbatim

Prevent MLView from parsing a block (useful for JS frameworks):

@verbatim
    <div id="vue-app">
        {{ vueVariable }}
    </div>
@endverbatim

Autoescape

Set the escaping context for a block:

@autoescape('js')
    var name = {{ $name }};
@endautoescape

Fragment Caching

Cache expensive template fragments with PSR-16. Requires a cache backend.

{{-- Cache sidebar for 5 minutes --}}
@cache('sidebar-' . $userId, 300)
    <div class="sidebar">
        @foreach($expensiveQuery as $item)
            <p>{{ $item->name }}</p>
        @endforeach
    </div>
@endcache

{{-- Cache forever (no TTL) --}}
@cache('static-nav')
    <nav>...</nav>
@endcache

Setup:

$view = new MLView($loader, $compiler, $renderer, $cacheDir, [
    'cache' => $redisCache, // Psr\SimpleCache\CacheInterface
]);

When no cache backend is configured, @cache blocks render normally with zero overhead.


Template Macros

Define reusable template snippets:

{{-- Define a macro --}}
@macro('statusBadge', $status, $label)
    <span class="badge badge-{{ $status }}">{{ $label }}</span>
@endmacro

{{-- Use the macro --}}
@call('statusBadge', 'success', 'Active')
@call('statusBadge', 'danger', 'Inactive')

Element-Level Directives (HEEx-Style)

Inspired by Phoenix LiveView — attach directives directly to HTML elements:

{{-- Conditional rendering --}}
<div :if="$showBanner" class="banner">Welcome!</div>

{{-- Negated conditional --}}
<p :unless="$isAdmin">You are not authorized.</p>

{{-- Loop rendering --}}
<li :for="$items as $item">{{ $item->name }}</li>

Compiles to standard PHP control structures wrapping the element.


Namespaces & Theming

View Namespaces

Organize views by package or module:

$view->addNamespace('ui', __DIR__ . '/vendor/ui-lib/views');

// Usage: ui::alert → /vendor/ui-lib/views/alert.ml.php
echo $view->render('ui::alert', ['type' => 'info']);

Theming System

// 1. Multiple view paths (checked in order)
$view->addViewPath('/path/to/overrides');

// 2. Theme activation (prepends theme path)
$view->setTheme('dark');
// Checks: themes/dark/home.ml.php → resources/views/home.ml.php

// 3. Namespace overrides in themes
// themes/dark/vendor/ui/alert.ml.php overrides ui::alert

View Composers & Events

View Composers

Automatically attach data to views by pattern:

// Attach $categories to all 'shop.*' views
$view->composer('shop.*', function (ViewData $data) {
    $data->set('categories', Category::all());
});

// Multiple patterns
$view->composer(['layouts.*', 'partials.nav'], function (ViewData $data) {
    $data->set('menuItems', Menu::forUser(auth()->user()));
});

Shared Data

$view->share('appName', 'MonkeysCloud');
// $appName available in ALL templates

Lifecycle Events

// Before render
$view->rendering(function (ViewRendering $event) {
    // $event->name, $event->data
    $event->data['renderTime'] = microtime(true);
});

// After render
$view->rendered(function (ViewRendered $event) {
    // $event->name, $event->data, $event->output
    Log::info("Rendered {$event->name}");
});

Streaming & Async

Render templates as a stream of chunks for progressive HTML delivery:

$view = new MLView($loader, $compiler, $renderer, $cacheDir);

foreach ($view->stream('dashboard', $data) as $chunk) {
    echo $chunk;
    flush();
}

Render String (No File)

$html = $view->renderString('Hello {{ $name }}!', ['name' => 'World']);

Security

Context-Aware Escaping

<a href="@escape('url', $link)"
   onclick="alert(@escape('js', $message))">
    @escape('html', $text)
</a>

Contexts: html, js, url, css, attr

Strict Mode

Warn on raw {!! !!} usage — useful for security audits:

$view = new MLView($loader, $compiler, $renderer, $cacheDir, [
    'strict_mode' => true,
]);

Default Escaping

All {{ }} output is escaped via htmlspecialchars() with ENT_QUOTES and UTF-8. Use {!! !!} or the | raw filter only for trusted content.


Caching Architecture

MLView uses a 3-tier caching system:

┌─────────────────────────────────────────────────────┐
│  L1: In-Memory Pool (CompiledTemplatePool)          │
│  Per-request dedup — avoids filemtime on repeats    │
├─────────────────────────────────────────────────────┤
│  L2: View Cache (ViewCacheInterface)                │
│  FilesystemViewCache — atomic writes, OPcache-aware │
│  Psr16ViewCache — Redis/Memcached adapter           │
├─────────────────────────────────────────────────────┤
│  L3: Fragment Cache (@cache directive)              │
│  PSR-16 store for expensive template blocks         │
└─────────────────────────────────────────────────────┘

Configuration

// Development (default) — checks filemtime, auto-recompiles
$view = new MLView($loader, $compiler, $renderer, $cacheDir);

// Production — skip filemtime checks, max speed
$view = new MLView($loader, $compiler, $renderer, $cacheDir, [
    'production' => true,
]);

// Full-featured — PSR-16 backend + fragment caching
$view = new MLView($loader, $compiler, $renderer, $cacheDir, [
    'production' => true,
    'cache'      => $redisCache, // Psr\SimpleCache\CacheInterface
]);

Cache Adapters

AdapterUse Case
FilesystemViewCacheDefault. Atomic writes, OPcache invalidation, dependency tracking
Psr16ViewCacheRedis/Memcached via any PSR-16 implementation
CustomImplement ViewCacheInterface

Cache Commands

# Clear all compiled templates
$view->clearCache();

# Or via CLI
./bin/mlview cache:clear

Performance

Benchmarks (PHP 8.5, Apple Silicon)

OperationTimeNotes
Simple render (1000×)0.015 ms/renderL1 pool hit
Loop render 100 items (500×)0.038 ms/renderWith $loop variable
Compilation (1000×)0.013 ms/compileWith early-exit optimization
Filter pipeline (1000×)0.025 ms/renderMultiple chained filters
Cache freshness check (10000×)0.004 ms/checkfilemtime comparison
Large table (1000×10)3.0 ms342 KB output
Production vs Dev mode13.8× speedupSkip filemtime checks

Optimizations Applied

  • Early-exit guards: 40+ directive compilers skipped via str_contains() when not present
  • Cached FilterRegistry: single instance shared across all expressions
  • Single-pass simple directives: 11 no-arg directives compiled in one regex
  • L1 in-memory pool: eliminates repeated filemtime calls within same request
  • Atomic writes: file_put_contents() with LOCK_EX for safe concurrent access
  • OPcache integration: opcache_invalidate() on recompile for immediate effect

Testing

Test Utilities

use MonkeysLegion\Template\Testing\TestView;

$result = $view->test('dashboard', ['user' => $user]);

$result->assertSee('Welcome');
$result->assertDontSee('Error');
$result->assertSeeInOrder(['Header', 'Content', 'Footer']);

Running Tests

composer test                 # All 476 tests
composer test:unit           # Unit tests only
composer test:integration    # Integration tests only
composer test:perf           # Performance benchmarks
composer phpstan             # Static analysis (Level 8)
composer check               # CS + PHPStan + Tests

CLI Tooling

Template Linting

# Lint the default views directory
./bin/mlview lint resources/views

# Check multiple paths
./bin/mlview lint resources/views,modules/blog/views

Checks for:

  • Missing components (<x-component>)
  • Missing included views (@include)
  • Syntax errors
  • Unclosed directives

Non-zero exit code on errors — CI/CD ready.

Pre-compilation

# Compile all templates ahead of time (deploy step)
./bin/mlview view:compile resources/views

Extensibility

Custom Directives

$view->addDirective('datetime', function ($expression) {
    return "<?php echo date('Y-m-d H:i:s', {$expression}); ?>";
});
// Usage: @datetime($timestamp)

Custom Filters

$view->addFilter('initials', function (string $name): string {
    return implode('', array_map(fn($w) => strtoupper($w[0]), explode(' ', $name)));
});
// Usage: {{ $fullName | initials }}  →  "JD"

Custom Cache Adapter

use MonkeysLegion\Template\Cache\ViewCacheInterface;

class MyCache implements ViewCacheInterface
{
    public function isFresh(string $name, string $sourcePath, string $compiledPath): bool { /* ... */ }
    public function put(string $compiledPath, string $compiledPhp): void { /* ... */ }
    public function getCompiledPath(string $name, string $sourcePath): string { /* ... */ }
    public function forget(string $name): void { /* ... */ }
    public function flush(): void { /* ... */ }
}

$renderer->setViewCache(new MyCache());

Pipeline Extension Points

ExtensionHow
Custom directives$view->addDirective()
Custom filters$view->addFilter()
Function components$view->component()
Custom cacheImplement ViewCacheInterface
Custom loaderImplement LoaderInterface
View composers$view->composer()
Render events$view->rendering() / $view->rendered()

Complete Directive Reference

Output

SyntaxDescription
{{ $var }}Escaped output
{!! $var !!}Raw output
{{ $var | filter }}Filtered output
{{-- comment --}}Template comment (stripped)

Control Flow

DirectiveDescription
@if / @elseif / @else / @endifConditionals
@unless / @endunlessNegated if
@isset / @endissetVariable existence check
@empty / @endemptyEmpty check
@switch / @case / @default / @endswitchSwitch
@foreach / @endforeachLoop with $loop variable
@forelse / @empty / @endforelseLoop with empty fallback
@for / @endforC-style for loop
@while / @endwhileWhile loop
@break / @continueLoop control

Components & Layout

DirectiveDescription
<x-name> / <x-name />Component usage
<x-slot:name>Named slot
@slot('name') / @endslotSlot (alternative syntax)
@param([...])Component defaults
@aware([...])Parent component data
@extends('layout')Layout inheritance
@section('name') / @endsectionSection definition
@yield('name', 'default')Section output
@parentInsert parent section content

Template Composition

DirectiveDescription
@include('view', [...])Include template
@includeIf('view')Include if exists
@includeWhen($cond, 'view')Conditional include
@includeUnless($cond, 'view')Negated conditional include
@includeFirst(['a', 'b'])First available
@inject('var', 'Class')Service injection

Stacks

DirectiveDescription
@stack('name')Output stack
@push('name') / @endpushAppend to stack
@prepend('name') / @endprependPrepend to stack
@pushOnce('name') / @endPushOnceDeduplicated push

Frontend

DirectiveDescription
@json($data)JSON encode
@js($data)JS-safe encode
@class([...])Conditional CSS classes
@style([...])Conditional inline styles
@checked($cond)Checked attribute
@selected($cond)Selected attribute
@disabled($cond)Disabled attribute
@readonly($cond)Readonly attribute
@requiredRequired attribute

Forms & Security

DirectiveDescription
@csrfCSRF token field
@method('PUT')HTTP method spoofing
@error('field') / @enderrorValidation errors
@old('field', 'default')Old input value
@escape('context', $var)Context-aware escaping

Framework

DirectiveDescription
@env('name') / @endenvEnvironment check
@production / @endproductionProduction shorthand
@auth / @endauthAuthenticated check
@guest / @endguestGuest check
@can('ability', $model) / @endcanAuthorization
@cannot('ability', $model) / @endcannotAuthorization negated
@session('key') / @endsessionSession check
@hasSection('name')Check section exists
@sectionMissing('name')Check section missing

Advanced

DirectiveDescription
@cache('key', ttl) / @endcacheFragment caching
@macro('name', ...) / @endmacroDefine macro
@call('name', ...)Invoke macro
@fragment('name') / @endfragmentHTMX partial rendering
@teleport('selector') / @endteleportContent teleport
@persist('id') / @endpersistHTMX persist
@model(Class)IDE type hint
@autoescape('context') / @endautoescapeBlock escaping
@options([...])Template options
@once / @endonceRender once
@verbatim / @endverbatimSkip parsing
@php / @endphpRaw PHP block
@use('Class')Import class

Element-Level (HEEx-Style)

AttributeDescription
:if="$condition"Conditional element
:unless="$condition"Negated conditional
:for="$items as $item"Loop element

Debugging

DirectiveDescription
@dump($var)Formatted var_dump
@dd($var)Dump and die

License

MIT © MonkeysCloud