Blade avançat
Funcionalitats avançades de Blade: directives personalitzades, service injection, stacks i fragments.
Directives personalitzades#
Blade et permet crear les teves pròpies directives per encapsular lògica que es repeteix sovint a les vistes. Les directives es registren al mètode boot() d'un service provider:
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Blade;
public function boot(): void
{
Blade::directive('datetime', function (string $expression) {
return "<?php echo ($expression)->format('d/m/Y H:i'); ?>";
});
Blade::directive('money', function (string $expression) {
return "<?php echo number_format($expression, 2, ',', '.') . ' €'; ?>";
});
}Un cop registrades, pots utilitzar-les a qualsevol vista Blade:
<p>Publicat: @datetime($article->created_at)</p>
<p>Preu: @money($product->price)</p>
{{-- Resultat: Publicat: 15/01/2024 14:30 --}}
{{-- Resultat: Preu: 29,99 € --}}Les directives es compilen a PHP pur i es guarden en cache, de manera que no afecten el rendiment. Recorda que després de crear o modificar una directiva, cal esborrar la cache de vistes amb php artisan view:clear.
Directives condicionals personalitzades#
Pots crear directives condicionals que funcionin com @if però amb una semàntica més clara:
Blade::if('admin', function () {
return auth()->check() && auth()->user()->is_admin;
});
Blade::if('env', function (string $environment) {
return app()->environment($environment);
});@admin
<a href="/admin">Panell d'administració</a>
@endadmin
@env('local')
<div class="debug-bar">Mode de desenvolupament</div>
@endenvStacks#
Els stacks permeten que les vistes filles o els components afegeixin contingut a zones específiques del layout. Són especialment útils per afegir scripts o estils que només necessita una pàgina o component concret.
Al layout, defineixes on es renderitzarà cada stack amb @stack:
{{-- Layout --}}
<head>
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
@stack('styles')
</head>
<body>
{{ $slot }}
<script src="{{ asset('js/app.js') }}"></script>
@stack('scripts')
</body>Des de qualsevol vista filla o component, pots afegir contingut al stack amb @push:
@push('styles')
<link rel="stylesheet" href="{{ asset('css/datepicker.css') }}">
@endpush
@push('scripts')
<script src="{{ asset('js/datepicker.js') }}"></script>
<script>
initDatepicker('#birthday');
</script>
@endpushSi necessites que el contingut vagi al principi del stack en lloc del final, utilitza @prepend:
@prepend('scripts')
<script src="{{ asset('js/vendor/jquery.js') }}"></script>
@endprependAixò és útil quan un script necessita carregar-se abans que els altres scripts del stack.
@once#
Quan un component es renderitza múltiples vegades a la mateixa pàgina, potser necessites que certs scripts o estils s'incloguin només un cop. La directiva @once garanteix que el contingut es renderitzi una sola vegada:
{{-- Component que es pot renderitzar moltes vegades --}}
@once
@push('styles')
<link rel="stylesheet" href="{{ asset('css/tooltip.css') }}">
@endpush
@push('scripts')
<script src="{{ asset('js/tooltip.js') }}"></script>
@endpush
@endonce
<span class="tooltip" data-text="{{ $text }}">
{{ $slot }}
</span>Sense @once, si el component es renderitza 10 vegades, el CSS i el JavaScript s'inclourien 10 vegades. Amb @once, s'inclouen una sola vegada.
Renderització condicional de classes i estils#
La directiva @class genera una llista de classes CSS condicionals de manera neta. Les classes sense condició s'inclouen sempre, i les que tenen una condició només s'inclouen si la condició és certa:
<div @class([
'p-4 rounded-lg border',
'bg-green-50 border-green-300 text-green-800' => $status === 'success',
'bg-red-50 border-red-300 text-red-800' => $status === 'error',
'bg-yellow-50 border-yellow-300 text-yellow-800' => $status === 'warning',
'bg-blue-50 border-blue-300 text-blue-800' => $status === 'info',
])>
{{ $message }}
</div>De la mateixa manera, @style permet afegir estils inline condicionals:
<div @style([
'background-color: red' => $isHighlighted,
'font-weight: bold' => $isImportant,
'padding: 1rem',
])>
{{ $content }}
</div>Atributs condicionals#
La directiva @checked, @selected, @disabled i @readonly simplifiquen l'escriptura d'atributs HTML condicionals als formularis:
<input type="checkbox"
name="active"
value="1"
@checked(old('active', $user->active)) />
<select name="role">
@foreach($roles as $role)
<option value="{{ $role->id }}" @selected(old('role') == $role->id)>
{{ $role->name }}
</option>
@endforeach
</select>
<input type="text"
name="email"
value="{{ $user->email }}"
@readonly(!$user->isAdmin()) />
<button type="submit" @disabled($form->hasErrors())>
Enviar
</button>Service Injection#
Pots injectar serveis directament a les vistes amb la directiva @inject. Això és útil quan una vista necessita accedir a un servei sense haver de passar-lo explícitament des del controlador:
@inject('metrics', 'App\Services\MetricsService')
<div class="dashboard">
<p>Ingressos del mes: {{ $metrics->monthlyRevenue() }} €</p>
<p>Usuaris actius: {{ $metrics->activeUsers() }}</p>
<p>Comandes pendents: {{ $metrics->pendingOrders() }}</p>
</div>El primer paràmetre és el nom de la variable que estarà disponible a la vista, i el segon és la classe o interfície del servei. Laravel resoldrà el servei des del contenidor automàticament.
Tot i que @inject és pràctic, és recomanable utilitzar-lo amb moderació. En la majoria de casos, és millor passar les dades des del controlador per mantenir les vistes el més senzilles possible.
Renderitzar strings com a Blade#
Si necessites processar un string que conté sintaxi Blade (per exemple, contingut d'una base de dades que conté directives Blade), pots fer servir el mètode Blade::render():
use Illuminate\Support\Facades\Blade;
$html = Blade::render('Hola, {{ $name }}', ['name' => 'Joan']);Fer servir Blade::render() amb contingut d'usuaris pot ser perillós perquè les directives Blade executen codi PHP. Només utilitza'l amb contingut de confiança.
Cache de vistes#
Blade compila les vistes a PHP pur i les guarda en cache al directori storage/framework/views/. Aquestes vistes compilades es regeneren automàticament quan el fitxer .blade.php es modifica. En producció, pots precompilar totes les vistes per millorar el rendiment:
# Compilar totes les vistes
php artisan view:cache
# Esborrar la cache de vistes
php artisan view:clearDurant el desenvolupament local, no cal preocupar-se per la cache: Blade detecta automàticament els canvis i recompila les vistes.