Documentación de Laravel 10.x
Aquí encontrarás fragmentos de código de Laravel y consejos útiles sobre desarrollo web.
Blade es el motor de plantillas simple pero potente incluido con Laravel. A diferencia de algunos motores de plantillas PHP, Blade no te restringe a usar código PHP simple en tus plantillas. De hecho, todas las plantillas de Blade se compilan en código PHP simple y se almacenan en caché hasta que se modifican, lo que significa que Blade agrega prácticamente cero sobrecarga a tu aplicación. Los archivos de plantilla de Blade usan la extensión de archivo .blade.php
y generalmente se almacenan en el directorio resources/views
.
Las vistas de Blade se pueden devolver desde rutas o controladores utilizando el ayudante global view
. Por supuesto, como se menciona en la documentación sobre vistas, los datos se pueden pasar a la vista de Blade utilizando el segundo argumento del ayudante view
:
Route::get('/', function () { return view('greeting', ['name' => 'Finn']);});
¿Quieres llevar tus plantillas de Blade al siguiente nivel y construir interfaces dinámicas con facilidad? Echa un vistazo a Laravel Livewire. Livewire te permite escribir componentes de Blade que se complementan con funcionalidades dinámicas que normalmente solo serían posibles mediante frameworks frontend como React o Vue, proporcionando un enfoque excelente para construir frontends modernos y reactivos sin las complejidades, representación del lado del cliente o pasos de compilación de muchos frameworks de JavaScript.
Puedes mostrar datos que se pasan a tus vistas de Blade envolviendo la variable entre llaves. Por ejemplo, dada la siguiente ruta:
Route::get('/', function () { return view('welcome', ['name' => 'Samantha']);});
Puedes mostrar el contenido de la variable name
de la siguiente manera:
Hola, {{ $name }}.
Nota Las declaraciones
{{ }}
de eco de Blade se envían automáticamente a través de la funciónhtmlspecialchars
de PHP para evitar ataques XSS.
No estás limitado a mostrar el contenido de las variables que se pasan a la vista. También puedes hacer echo de los resultados de cualquier función de PHP. De hecho, puedes poner cualquier código PHP que desees dentro de una declaración de echo de Blade:
La marca de tiempo UNIX actual es {{ time() }}.
De forma predeterminada, Blade (y la función e
de Laravel) codificarán las entidades HTML dos veces. Si deseas deshabilitar la doble codificación, llama al método Blade::withoutDoubleEncoding
desde el método boot
de tu AppServiceProvider
:
<?php namespace App\Providers; use Illuminate\Support\Facades\Blade;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * Inicializa cualquier servicio de la aplicación. */ public function boot(): void { Blade::withoutDoubleEncoding(); }}
Por defecto, las declaraciones Blade {{ }}
se envían automáticamente a través de la función htmlspecialchars
de PHP para evitar ataques XSS. Si no deseas que tus datos se escapen, puedes usar la siguiente sintaxis:
Hola, {!! $name !!}.
Advertencia Ten mucho cuidado al hacer echo de contenido proporcionado por los usuarios de tu aplicación. Por lo general, debes usar la sintaxis de llaves dobles escapadas para evitar ataques XSS al mostrar datos proporcionados por el usuario.
Dado que muchos marcos de trabajo de JavaScript también utilizan llaves "curly" para indicar que una expresión determinada debe mostrarse en el navegador, puedes usar el símbolo @
para informar al motor de renderización de Blade que una expresión debe permanecer sin cambios. Por ejemplo:
<h1>Laravel</h1> Hola, @{{ name }}.
En este ejemplo, el símbolo @
será eliminado por Blade; sin embargo, la expresión {{ name }}
permanecerá sin cambios por el motor de Blade, lo que permitirá que sea renderizada por tu marco de trabajo de JavaScript.
El símbolo @
también se puede usar para escapar de las directivas de Blade:
{{-- Blade template --}}@@if() <!-- HTML output -->@if()
A veces puedes pasar un array a tu vista con la intención de renderizarlo como JSON para inicializar una variable de JavaScript. Por ejemplo:
<script> var app = <?php echo json_encode($array); ?>;</script>
Sin embargo, en lugar de llamar manualmente a json_encode
, puedes usar el método Illuminate\Support\Js::from
. El método from
acepta los mismos argumentos que la función json_encode
de PHP; sin embargo, asegurará que el JSON resultante esté correctamente escapado para su inclusión dentro de las comillas HTML. El método from
devolverá una cadena de declaración JavaScript JSON.parse
que convertirá el objeto o array dado en un objeto JavaScript válido:
<script> var app = {{ Illuminate\Support\Js::from($array) }};</script>
Las versiones más recientes del esqueleto de aplicación de Laravel incluyen un facade Js
, que proporciona un acceso conveniente a esta funcionalidad dentro de tus plantillas de Blade:
<script> var app = {{ Js::from($array) }};</script>
Advertencia Solo debes usar el método
Js::from
para renderizar variables existentes como JSON. La plantilla de Blade se basa en expresiones regulares y intentar pasar una expresión compleja a la directiva puede causar fallos inesperados.
@verbatim
Una vez que se haya definido tu manejador de echo personalizado, simplemente puedes hacer eco del objeto en tu plantilla Blade:
@verbatim <div class="container"> Hola, {{ name }}. </div>@endverbatim
Además de la herencia de plantillas y la visualización de datos, Blade también proporciona atajos convenientes para estructuras de control PHP comunes, como declaraciones condicionales y bucles. Estos atajos ofrecen una forma muy limpia y concisa de trabajar con estructuras de control PHP y siguen siendo familiares a sus contrapartes de PHP.
Puedes construir declaraciones if
usando las directivas @if
, @elseif
, @else
y @endif
. Estas directivas funcionan de manera idéntica a sus contrapartes en PHP:
@if (count($records) === 1) ¡Tengo un registro!@elseif (count($records) > 1) ¡Tengo varios registros!@else ¡No tengo ningún registro!@endif
Para mayor comodidad, Blade también proporciona una directiva @unless
:
@unless (Auth::check()) No has iniciado sesión.@endunless
Además de las directivas condicionales ya mencionadas, las directivas @isset
y @empty
se pueden usar como atajos convenientes para sus respectivas funciones de PHP:
@isset($records) // $records está definido y no es nulo...@endisset @empty($records) // $records is "empty"...@endempty
Las directivas @auth
y @guest
se pueden usar para determinar rápidamente si el usuario actual está autenticado o es un invitado:
@auth // El usuario está autenticado...@endauth @guest // El usuario no está autenticado...@endguest
Si es necesario, puedes especificar la guarda de autenticación que se debe verificar al usar las directivas @auth
y @guest
:
@auth('admin') // El usuario está autenticado...@endauth @guest('admin') // El usuario no está autenticado...@endguest
Puedes verificar si la aplicación se está ejecutando en el entorno de producción mediante la directiva @production
:
@production // Contenido específico de producción...@endproduction
O puedes determinar si la aplicación se está ejecutando en un entorno específico mediante la directiva @env
:
@env('staging') // La aplicación se está ejecutando en "staging"...@endenv @env(['staging', 'production']) // La aplicación se está ejecutando en "staging" o "production"...@endenv
Puedes determinar si una sección de herencia de plantillas tiene contenido usando la directiva @hasSection
:
@hasSection('navigation') <div class="pull-right"> @yield('navigation') </div> <div class="clearfix"></div>@endif
Puedes usar la directiva sectionMissing
para determinar si una sección no tiene contenido:
@sectionMissing('navigation') <div class="pull-right"> @include('default-navigation') </div>@endif
Las declaraciones switch
se pueden construir mediante las directivas @switch
, @case
, @break
, @default
y @endswitch
:
@switch($i) @case(1) Primer caso... @break @case(2) Segundo caso... @break @default Caso predeterminado...@endswitch
Además de las declaraciones condicionales, Blade proporciona directivas simples para trabajar con las estructuras de bucle de PHP. Nuevamente, cada una de estas directivas funciona de manera idéntica a sus contrapartes de PHP:
@for ($i = 0; $i < 10; $i++) El valor actual es {{ $i }}@endfor @foreach ($users as $user) <p>Este es el usuario {{ $user->id }}</p>@endforeach @forelse ($users as $user) <li>{{ $user->name }}</li>@empty <p>Ningún usuario</p>@endforelse @while (true) <p>Estoy haciendo un bucle infinito.</p>@endwhile
Nota Mientras iteras a través de un bucle
foreach
, puedes usar la variable del bucle para obtener información valiosa sobre el bucle, como si estás en la primera o última iteración a través del bucle.
Cuando usas bucles, también puedes omitir la iteración actual o finalizar el bucle usando las directivas @continue
y @break
:
@foreach ($users as $user) @if ($user->type == 1) @continue @endif <li>{{ $user->name }}</li> @if ($user->number == 5) @break @endif@endforeach
También puedes incluir la condición de continuación o de ruptura dentro de la declaración de la directiva:
@foreach ($users as $user) @continue($user->type == 1) <li>{{ $user->name }}</li> @break($user->number == 5)@endforeach
Mientras iteras a través de un bucle foreach
, una variable $loop
estará disponible dentro de tu bucle. Esta variable proporciona acceso a información útil como el índice actual del bucle y si esta es la primera o última iteración a través del bucle:
@foreach ($users as $user) @if ($loop->first) Esta es la primera iteración. @endif @if ($loop->last) Esta es la última iteración. @endif <p>Este es el usuario {{ $user->id }}</p>@endforeach
Si estás en un bucle anidado, puedes acceder a la variable $loop
del bucle padre a través de la propiedad parent
:
@foreach ($users as $user) @foreach ($user->posts as $post) @if ($loop->parent->first) Esta es la primera iteración del bucle principal. @endif @endforeach@endforeach
La variable $loop
también contiene una variedad de otras propiedades útiles:
Propiedad | Descripción |
---|---|
$loop->index |
El índice de la iteración actual del bucle (comienza en 0). |
$loop->iteration |
La iteración actual del bucle (comienza en 1). |
$loop->remaining |
Las iteraciones restantes en el bucle. |
$loop->count |
El número total de elementos en la matriz que se está iterando. |
$loop->first |
Si esta es la primera iteración a través del bucle. |
$loop->last |
Si esta es la última iteración a través del bucle. |
$loop->even |
Si esta es una iteración par a través del bucle. |
$loop->odd |
Si esta es una iteración impar a través del bucle. |
$loop->depth |
El nivel de anidamiento del bucle actual. |
$loop->parent |
Cuando estás en un bucle anidado, la variable de bucle del padre. |
La directiva @class
compila condicionalmente una cadena de clases CSS. La directiva acepta un array de clases donde la clave del array contiene la clase o clases que deseas agregar, mientras que el valor es una expresión booleana. Si el elemento del array tiene una clave numérica, siempre se incluirá en la lista de clases renderizadas:
@php $isActive = false; $hasError = true;@endphp <span @class([ 'p-4', 'font-bold' => $isActive, 'text-gray-500' => ! $isActive, 'bg-red' => $hasError,])></span> <span class="p-4 text-gray-500 bg-red"></span>
Asimismo, la directiva @style
se puede utilizar para agregar condicionalmente estilos CSS en línea a un elemento HTML:
@php $isActive = true;@endphp <span @style([ 'background-color: red', 'font-weight: bold' => $isActive,])></span> <span style="background-color: red; font-weight: bold;"></span>
Para mayor comodidad, puedes usar la directiva @checked
para indicar fácilmente si un checkbox de entrada HTML dado está "checked". Esta directiva imprimirá checked
si la condición proporcionada se evalúa como true
:
<input type="checkbox" name="active" value="active" @checked(old('active', $user->active)) />
De manera similar, la directiva @selected
se puede utilizar para indicar si una opción de selección debe estar "selected":
<select name="version"> @foreach ($product->versions as $version) <option value="{{ $version }}" @selected(old('version') == $version)> {{ $version }} </option> @endforeach</select>
Además, la directiva @disabled
se puede utilizar para indicar si un elemento dado debe estar "disabled":
<button type="submit" @disabled($errors->isNotEmpty())>Submit</button>
Además, la directiva @readonly
se puede utilizar para indicar si un elemento dado debe estar "readonly":
<input type="email" name="email" @readonly($user->isNotAdmin()) />
Además, la directiva @required
se puede utilizar para indicar si un elemento dado debe estar "required":
<input type="text" name="title" value="title" @required($user->isAdmin()) />
Nota Aunque eres libre de usar la directiva
@include
, los componentes de Blade ofrecen funcionalidad similar y brindan varias ventajas sobre la directiva@include
, como la vinculación de datos y atributos.
La directiva @include
de Blade te permite incluir una vista de Blade desde otra vista. Todas las variables disponibles para la vista principal estarán disponibles para la vista incluida:
<div> @include('shared.errors') <form> <!-- Form Contents --> </form></div>
Aunque la vista incluida heredará todos los datos disponibles en la vista principal, también puedes pasar un array de datos adicionales que se deben poner a disposición de la vista incluida:
@include('view.name', ['status' => 'complete'])
Si intentas @include
una vista que no existe, Laravel lanzará un error. Si deseas incluir una vista que puede estar presente o no, debes usar la directiva @includeIf
:
@includeIf('view.name', ['status' => 'complete'])
Si deseas @include
una vista si una expresión booleana dada se evalúa como true
o false
, puedes usar las directivas @includeWhen
y @includeUnless
:
@includeWhen($boolean, 'view.name', ['status' => 'complete']) @includeUnless($boolean, 'view.name', ['status' => 'complete'])
Para incluir la primera vista que existe de un conjunto dado de vistas, puedes usar la directiva includeFirst
:
@includeFirst(['custom.admin', 'admin'], ['status' => 'complete'])
Advertencia Debes evitar el uso de las constantes
__DIR__
y__FILE__
en tus vistas de Blade, ya que se referirán a la ubicación de la vista compilada y en caché.
Puedes combinar bucles e inclusiones en una sola línea con la directiva @each
de Blade:
@each('view.name', $jobs, 'job')
El primer argumento de la directiva @each
es la vista que se va a renderizar para cada elemento en el array o colección. El segundo argumento es el array o colección que deseas recorrer, mientras que el tercer argumento es el nombre de la variable que se asignará a la iteración actual dentro de la vista. Entonces, por ejemplo, si estás iterando sobre un array de jobs
, típicamente querrás acceder a cada trabajo como una variable job
dentro de la vista. La clave del array para la iteración actual estará disponible como la variable key
dentro de la vista.
También puedes pasar un cuarto argumento a la directiva @each
. Este argumento determina la vista que se renderizará si el array dado está vacío.
@each('view.name', $jobs, 'job', 'view.empty')
Advertencia Las vistas renderizadas mediante
@each
no heredan las variables de la vista principal. Si la vista secundaria requiere estas variables, debes utilizar las directivas@foreach
y@include
en su lugar.
@once
La directiva @once
te permite definir una parte de la plantilla que solo se evaluará una vez por ciclo de renderizado. Esto puede ser útil para insertar una determinada pieza de JavaScript en el encabezado de la página usando stacks. Por ejemplo, si estás renderizando un componente específico dentro de un bucle, es posible que desees empujar el JavaScript al encabezado solo la primera vez que se renderiza el componente:
@once @push('scripts') <script> // Tu JavaScript personalizado... </script> @endpush@endonce
Dado que la directiva @once
se usa a menudo en conjunción con las directivas @push
o @prepend
, las directivas @pushOnce
y @prependOnce
están disponibles para tu conveniencia:
@pushOnce('scripts') <script> // Tu JavaScript personalizado... </script>@endPushOnce
En algunas situaciones, es útil incrustar código PHP en tus vistas. Puedes usar la directiva @php
de Blade para ejecutar un bloque de PHP simple dentro de tu plantilla:
@php $counter = 1;@endphp
Blade también te permite definir comentarios en tus vistas. Sin embargo, a diferencia de los comentarios HTML, los comentarios de Blade no se incluyen en el HTML devuelto por tu aplicación:
{{-- Este comentario no estará presente en el HTML renderizado --}}
Los componentes y slots brindan beneficios similares a las secciones, layouts e inclusiones; sin embargo, algunos pueden encontrar que el modelo mental de componentes y slots es más fácil de entender. Hay dos enfoques para escribir componentes: componentes basados en clases y componentes anónimos.
Para crear un componente basado en clases, puedes usar el comando Artisan make:component
. Para ilustrar cómo usar componentes, crearemos un componente simple llamado Alert
. El comando make:component
colocará el componente en el directorio app/View/Components
:
php artisan make:component Alert
El comando make:component
también creará una plantilla de vista para el componente. La vista se colocará en el directorio resources/views/components
. Cuando escribes componentes para tu propia aplicación, los componentes se descubren automáticamente dentro del directorio app/View/Components
y el directorio resources/views/components
, por lo que generalmente no se requiere más registro de componentes.
También puedes crear componentes dentro de subdirectorios:
php artisan make:component Forms/Input
El comando anterior creará un componente Input
en el directorio app/View/Components/Forms
y la vista se colocará en el directorio resources/views/components/forms
.
Si deseas crear un componente anónimo (un componente solo con una plantilla de Blade y sin clase), puedes usar la bandera --view
al invocar el comando make:component
:
php artisan make:component forms.input --view
El comando anterior creará un archivo Blade en resources/views/components/forms/input.blade.php
que se puede renderizar como un componente a través de <x-forms.input />
.
Cuando escribes componentes para tu propia aplicación, los componentes se descubren automáticamente dentro del directorio app/View/Components
y el directorio resources/views/components
.
Sin embargo, si estás construyendo un paquete que utiliza componentes de Blade, deberás registrar manualmente la clase de tu componente y su alias de etiqueta HTML. Por lo general, debes registrar tus componentes en el método boot
del proveedor de servicios de tu paquete:
use Illuminate\Support\Facades\Blade; /** * Inicializa los servicios de tu paquete. */public function boot(): void{ Blade::component('package-alert', Alert::class);}
Una vez que tu componente ha sido registrado, se puede renderizar utilizando su alias de etiqueta:
<x-package-alert/>
Alternativamente, puedes usar el método componentNamespace
para cargar automáticamente las clases de componentes por convención. Por ejemplo, un paquete Nightshade
podría tener componentes Calendar
y ColorPicker
que residen dentro del espacio de nombres Package\Views\Components
:
use Illuminate\Support\Facades\Blade; /** * Inicializa los servicios de tu paquete. */public function boot(): void{ Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');}
Esto permitirá el uso de componentes de paquete por su espacio de nombres de proveedor utilizando la sintaxis nombre-paquete::
:
<x-nightshade::calendar /><x-nightshade::color-picker />
Blade detectará automáticamente la clase vinculada a este componente poniendo la primera letra en mayúscula. Los subdirectorios también son compatibles utilizando la notación "punto".
Para mostrar un componente, puedes usar una etiqueta de componente de Blade dentro de una de tus plantillas de Blade. Las etiquetas de componente de Blade comienzan con la cadena x-
seguida del nombre en kebab case de la clase del componente:
<x-alert/> <x-user-profile/>
Si la clase del componente está anidada más profundamente dentro del directorio app/View/Components
, puedes usar el carácter .
para indicar la anidación de directorios. Por ejemplo, si asumimos que un componente está ubicado en app/View/Components/Inputs/Button.php
, podemos renderizarlo así:
<x-inputs.button/>
Si deseas renderizar tu componente de forma condicional, puedes definir un método shouldRender
en la clase de tu componente. Si el método shouldRender
devuelve false
, el componente no se renderizará:
use Illuminate\Support\Str; /** * Determina si el componente debe renderizarse. */public function shouldRender(): bool{ return Str::length($this->message) > 0;}
Puedes pasar datos a los componentes de Blade usando atributos HTML. Los valores primitivos codificados se pueden pasar al componente mediante cadenas de atributos HTML simples. Las expresiones y variables de PHP deben pasarse al componente a través de atributos que usan el carácter :
como prefijo:
<x-alert type="error" :message="$message"/>
Debes definir todos los atributos de datos del componente en el constructor de su clase. Todas las propiedades públicas en un componente se pondrán automáticamente a disposición de la vista del componente. No es necesario pasar los datos a la vista desde el método render
del componente:
<?php namespace App\View\Components; use Illuminate\View\Component;use Illuminate\View\View; class Alert extends Component{ /** * Crea la instancia del componente. */ public function __construct( public string $type, public string $message, ) {} /** * Obtiene la vista o el contenido que representa el componente. */ public function render(): View { return view('components.alert'); }}
Cuando se renderiza tu componente, puedes mostrar el contenido de las variables públicas de tu componente haciendo un echo de las variables por nombre:
<div class="alert alert-{{ $type }}"> {{ $message }}</div>
Los argumentos del constructor del componente deben especificarse utilizando camelCase
, mientras que kebab-case
se debe usar al hacer referencia a los nombres de argumento en tus atributos HTML. Por ejemplo, dado el siguiente constructor de componente:
/** * Crea la instancia del componente. */public function __construct( public string $alertType,) {}
El argumento $alertType
se puede proporcionar al componente de la siguiente manera:
<x-alert alert-type="danger" />
Al pasar atributos a componentes, también puedes usar una sintaxis de "atributo corto". Esto es conveniente ya que los nombres de los atributos a menudo coinciden con los nombres de las variables a las que corresponden:
{{-- Short attribute syntax... --}}<x-profile :$userId :$name /> {{-- Is equivalent to... --}}<x-profile :user-id="$userId" :name="$name" />
Dado que algunos marcos de JavaScript, como Alpine.js, también utilizan atributos con dos puntos como prefijo, puedes usar un doble dos puntos (::
) como prefijo para informar a Blade que el atributo no es una expresión de PHP. Por ejemplo, dada el siguiente componente:
<x-button ::class="{ danger: isDeleting }"> Submit</x-button>
El siguiente HTML se renderizará con Blade:
<button :class="{ danger: isDeleting }"> Submit</button>
Además de que las variables públicas estén disponibles para la plantilla de tu componente, también se pueden invocar cualquier método público en el componente. Por ejemplo, imagina un componente que tiene un método isSelected
:
/** * Determina si la opción dada es la opción actualmente seleccionada. */public function isSelected(string $option): bool{ return $option === $this->selected;}
Puedes ejecutar este método desde la plantilla de tu componente invocando la variable que coincide con el nombre del método:
<option {{ $isSelected($value) ? 'selected' : '' }} value="{{ $value }}"> {{ $label }}</option>
Los componentes de Blade también te permiten acceder al nombre del componente, a los atributos y al slot dentro del método render
de la clase. Sin embargo, para acceder a estos datos, debes devolver un cierre desde el método render
de tu componente. El cierre recibirá un array $data
como su único argumento. Este array contendrá varios elementos que proporcionan información sobre el componente:
use Closure; /** * Obtiene la vista o el contenido que representa el componente. */public function render(): Closure{ return function (array $data) { // $data['componentName']; // $data['attributes']; // $data['slot']; return 'modify_10x/blade.return_text_856'; };}
El componentName
es igual al nombre utilizado en la etiqueta HTML después del prefijo x-
. Entonces, el componentName
de <x-alert />
será alert
. El elemento attributes
contendrá todos los atributos que estaban presentes en la etiqueta HTML. El elemento slot
es una instancia de Illuminate\Support\HtmlString
con el contenido del slot del componente.
El cierre debe devolver una cadena. Si la cadena devuelta corresponde a una vista existente, esa vista se renderizará; de lo contrario, la cadena devuelta se evaluará como una vista Blade en línea.
Si tu componente requiere dependencias del contenedor de servicios de Laravel, puedes enumerarlas antes que cualquiera de los atributos de datos del componente y se inyectarán automáticamente mediante el contenedor:
use App\Services\AlertCreator; /** * Crea la instancia del componente. */public function __construct( public AlertCreator $creator, public string $type, public string $message,) {}
Si deseas evitar que algunos métodos o propiedades públicas se expongan como variables en la plantilla de tu componente, puedes agregarlos a una propiedad de array $except
en tu componente:
<?php namespace App\View\Components; use Illuminate\View\Component; class Alert extends Component{ /** * Las propiedades / métodos que no deben exponerse en la plantilla del componente. * * @var array */ protected $except = ['type']; /** * Crea la instancia del componente. */ public function __construct( public string $type, ) {}}
Ya hemos examinado cómo pasar atributos de datos a un componente; sin embargo, a veces es posible que necesites especificar atributos HTML adicionales, como class
, que no forman parte de los datos necesarios para que funcione un componente. Normalmente, deseas pasar estos atributos adicionales hacia abajo al elemento raíz de la plantilla del componente. Por ejemplo, imagina que quieres renderizar un componente alert
de la siguiente manera:
<x-alert type="error" :message="$message" class="mt-4"/>
Todos los atributos que no forman parte del constructor del componente se agregarán automáticamente a la "bolsa de atributos" del componente. Esta bolsa de atributos está automáticamente disponible para el componente a través de la variable $attributes
. Todos los atributos se pueden renderizar dentro del componente haciendo un echo de esta variable:
<div {{ $attributes }}> <!-- Component content --></div>
Advertencia En este momento, no se admite el uso de directivas como
@env
dentro de las etiquetas de los componentes. Por ejemplo,<x-alert :live=\"@env('production')\"/>
no se compilará.
A veces es posible que necesites especificar valores predeterminados para atributos o combinar valores adicionales en algunos de los atributos del componente. Para lograr esto, puedes usar el método merge
de la bolsa de atributos. Este método es particularmente útil para definir un conjunto de clases CSS predeterminadas que siempre se deben aplicar a un componente:
<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}> {{ $message }}</div>
Si asumimos que este componente se utiliza de la siguiente manera:
<x-alert type="error" :message="$message" class="mb-4"/>
El HTML final, renderizado del componente, aparecerá de la siguiente manera:
<div class="alert alert-error mb-4"> <!-- Contenido de la variable $message --></div>
A veces puede ser necesario combinar clases si una condición dada es true
. Puedes lograr esto mediante el método class
, que acepta un array de clases donde la clave del array contiene la clase o clases que deseas agregar, mientras que el valor es una expresión booleana. Si el elemento del array tiene una clave numérica, siempre se incluirá en la lista de clases renderizadas:
<div {{ $attributes->class(['p-4', 'bg-red' => $hasError]) }}> {{ $message }}</div>
Si necesitas combinar otros atributos en tu componente, puedes encadenar el método merge
al método class
:
<button {{ $attributes->class(['p-4'])->merge(['type' => 'button']) }}> {{ $slot }}</button>
Nota Si necesitas compilar condicionalmente clases en otros elementos HTML que no deben recibir atributos fusionados, puedes usar la directiva
@class
.
Cuando combines atributos que no son atributos class
, los valores proporcionados al método merge
se considerarán los valores "predeterminados" del atributo. Sin embargo, a diferencia del atributo class
, estos atributos no se combinarán con los valores de atributos inyectados. En su lugar, serán sobrescritos. Por ejemplo, la implementación de un componente button
podría ser así:
<button {{ $attributes->merge(['type' => 'button']) }}> {{ $slot }}</button>
Para renderizar el componente de botón con un type
personalizado, se puede especificar al consumir el componente. Si no se especifica ningún tipo, se usará el tipo button
:
<x-button type="submit"> Submit</x-button>
El HTML renderizado del componente button
en este ejemplo sería:
<button type="submit"> Submit</button>
Si deseas que un atributo distinto de class
tenga su valor predeterminado y los valores inyectados se unan, puedes usar el método prepends
. En este ejemplo, el atributo data-controller
siempre comenzará con profile-controller
y cualquier valor adicional inyectado de data-controller
se colocará después de este valor predeterminado:
<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}> {{ $slot }}</div>
Puedes filtrar atributos usando el método filter
. Este método acepta un cierre que debe devolver true
si deseas retener el atributo en la bolsa de atributos:
{{ $attributes->filter(fn (string $value, string $key) => $key == 'foo') }}
Por conveniencia, puedes usar el método whereStartsWith
para recuperar todos los atributos cuyas claves comienzan con una cadena dada:
{{ $attributes->whereStartsWith('wire:model') }}
Conversamente, el método whereDoesntStartWith
se puede utilizar para excluir todos los atributos cuyas claves comienzan con una cadena dada:
{{ $attributes->whereDoesntStartWith('wire:model') }}
Usando el método first
, puedes renderizar el primer atributo en una bolsa de atributos dada:
{{ $attributes->whereStartsWith('wire:model')->first() }}
Si deseas verificar si un atributo está presente en el componente, puedes usar el método has
. Este método acepta el nombre del atributo como su único argumento y devuelve un booleano que indica si el atributo está presente o no:
@if ($attributes->has('class')) <div>El atributo de clase está presente</div>@endif
Si se pasa un array al método has
, el método determinará si todos los atributos dados están presentes en el componente:
@if ($attributes->has(['name', 'class'])) <div>Todos los atributos están presentes</div>@endif
El método hasAny
se puede utilizar para determinar si alguno de los atributos dados está presente en el componente:
@if ($attributes->hasAny(['href', ':href', 'v-bind:href'])) <div>Uno de los atributos está presente</div>@endif
Puedes recuperar el valor de un atributo específico usando el método get
:
{{ $attributes->get('class') }}
Por defecto, algunas palabras clave están reservadas para el uso interno de Blade con el fin de renderizar componentes. Las siguientes palabras clave no se pueden definir como propiedades públicas o nombres de métodos dentro de tus componentes:
data
render
resolveView
shouldRender
view
withAttributes
withName
A menudo necesitarás pasar contenido adicional a tu componente a través de "slots". Los slots de componente se representan haciendo un eco de la variable $slot
. Para explorar este concepto, imaginemos que un componente alert
tiene el siguiente marcado:
<!-- /resources/views/components/alert.blade.php --> <div class="alert alert-danger"> {{ $slot }}</div>
Podemos pasar contenido al slot
inyectando contenido en el componente:
<x-alert> <strong>¡Vaya!</strong> Algo salió mal.</x-alert>
A veces, un componente puede necesitar renderizar múltiples slots diferentes en diferentes ubicaciones dentro del componente. Modifiquemos nuestro componente de alerta para permitir la inyección de un slot de "título":
<!-- /resources/views/components/alert.blade.php --> <span class="alert-title">{{ $title }}</span> <div class="alert alert-danger"> {{ $slot }}</div>
Puedes definir el contenido del slot nombrado usando la etiqueta x-slot
. Cualquier contenido que no esté dentro de una etiqueta x-slot
explícita se pasará al componente en la variable $slot
:
<x-alert> <x-slot:title> Server Error </x-slot> <strong>¡Vaya!</strong> Algo salió mal.</x-alert>
Si has utilizado un marco de trabajo de JavaScript como Vue, es posible que estés familiarizado con los "scoped slots", que te permiten acceder a datos o métodos desde el componente dentro de tu slot. Puedes lograr un comportamiento similar en Laravel definiendo métodos o propiedades públicas en tu componente y accediendo al componente dentro de tu slot a través de la variable $component
. En este ejemplo, asumiremos que el componente x-alert
tiene un método público formatAlert
definido en su clase de componente:
<x-alert> <x-slot:title> {{ $component->formatAlert('Error del servidor') }} </x-slot> <strong>¡Vaya!</strong> Algo salió mal.</x-alert>
Al igual que los componentes de Blade, puedes asignar atributos adicionales a los slots, como nombres de clases CSS:
<x-card class="shadow-sm"> <x-slot:heading class="font-bold"> Encabezado </x-slot> Contenido <x-slot:footer class="text-sm"> Pie de página </x-slot></x-card>
Para interactuar con los atributos del slot, puedes acceder a la propiedad attributes
de la variable del slot. Para obtener más información sobre cómo interactuar con los atributos, consulta la documentación sobre atributos de componente:
@props([ 'heading', 'footer',]) <div {{ $attributes->class(['border']) }}> <h1 {{ $heading->attributes->class(['text-lg']) }}> {{ $heading }} </h1> {{ $slot }} <footer {{ $footer->attributes->class(['text-gray-700']) }}> {{ $footer }} </footer></div>
Para componentes muy pequeños, puede sentirse engorroso administrar tanto la clase del componente como la plantilla de vista del componente. Por esta razón, puedes devolver el marcado del componente directamente desde el método render
:
/** * Obtiene la vista o el contenido que representa el componente. */public function render(): string{ return <<<'blade' <div class="alert alert-danger"> {{ $slot }} </div> blade;}
Para crear un componente que represente una vista en línea, puedes usar la opción inline
al ejecutar el comando make:component
:
php artisan make:component Alert --inline
A veces necesitarás renderizar un componente pero no sabrás qué componente se debe renderizar hasta en tiempo de ejecución. En esta situación, puedes usar el componente incorporado de Laravel dynamic-component
para renderizar el componente en función de un valor o variable en tiempo de ejecución:
// $componentName = "secondary-button"; <x-dynamic-component :component="$componentName" class="mt-4" />
Advertencia La siguiente documentación sobre el registro manual de componentes es principalmente aplicable a aquellos que están escribiendo paquetes de Laravel que incluyen componentes de vista. Si no estás escribiendo un paquete, esta parte de la documentación de componentes puede no ser relevante para ti.
Cuando escribes componentes para tu propia aplicación, los componentes se descubren automáticamente dentro del directorio app/View/Components
y el directorio resources/views/components
.
Sin embargo, si estás construyendo un paquete que utiliza componentes de Blade o colocando componentes en directorios no convencionales, deberás registrar manualmente la clase de tu componente y su alias de etiqueta HTML para que Laravel sepa dónde encontrar el componente. Por lo general, debes registrar tus componentes en el método boot
del proveedor de servicios de tu paquete:
use Illuminate\Support\Facades\Blade;use VendorPackage\View\Components\AlertComponent; /** * Inicializa los servicios de tu paquete. */public function boot(): void{ Blade::component('package-alert', AlertComponent::class);}
Una vez que tu componente haya sido registrado, se puede renderizar usando su alias de etiqueta:
<x-package-alert/>
Alternativamente, puedes usar el método componentNamespace
para cargar automáticamente las clases de componentes por convención. Por ejemplo, un paquete Nightshade
podría tener componentes Calendar
y ColorPicker
que residen en el espacio de nombres Package\Views\Components
:
use Illuminate\Support\Facades\Blade; /** * Inicializa los servicios de tu paquete. */public function boot(): void{ Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');}
Esto permitirá el uso de componentes de paquetes mediante su espacio de nombres de proveedor utilizando la sintaxis package-name::
:
<x-nightshade::calendar /><x-nightshade::color-picker />
Blade detectará automáticamente la clase vinculada a este componente utilizando pascal-case en el nombre del componente. Los subdirectorios también son compatibles utilizando la notación "punto".
Similar a los componentes en línea, los componentes anónimos proporcionan un mecanismo para gestionar un componente a través de un solo archivo. Sin embargo, los componentes anónimos utilizan un solo archivo de vista y no tienen una clase asociada. Para definir un componente anónimo, solo necesitas colocar una plantilla de Blade dentro de tu directorio resources/views/components
. Por ejemplo, asumiendo que has definido un componente en resources/views/components/alert.blade.php
, simplemente puedes renderizarlo así:
<x-alert/>
Puedes usar el carácter .
para indicar si un componente está anidado más profundamente dentro del directorio components
. Por ejemplo, suponiendo que el componente está definido en resources/views/components/inputs/button.blade.php
, puedes renderizarlo así:
<x-inputs.button/>
A veces, cuando un componente está compuesto por muchas plantillas de Blade, es posible que desees agrupar las plantillas dadas del componente dentro de un solo directorio. Por ejemplo, imagina un componente "accordion" con la siguiente estructura de directorio:
/resources/views/components/accordion.blade.php/resources/views/components/accordion/item.blade.php
Esta estructura de directorio te permite renderizar el componente de acordeón y su ítem de la siguiente manera:
<x-accordion> <x-accordion.item> ... </x-accordion.item></x-accordion>
Sin embargo, para renderizar el componente de acordeón a través de x-accordion
, nos vimos obligados a colocar la plantilla del componente de acordeón "index" en el directorio resources/views/components
en lugar de anidarla dentro del directorio accordion
con las otras plantillas relacionadas con el acordeón.
Afortunadamente, Blade te permite colocar un archivo index.blade.php
dentro del directorio de plantillas de un componente. Cuando existe una plantilla index.blade.php
para el componente, se renderizará como el nodo "raíz" del componente. Así que podemos seguir usando la misma sintaxis de Blade dada en el ejemplo anterior; sin embargo, ajustaremos nuestra estructura de directorios de la siguiente manera:
/resources/views/components/accordion/index.blade.php/resources/views/components/accordion/item.blade.php
Dado que los componentes anónimos no tienen ninguna clase asociada, puede que te preguntes cómo diferenciar qué datos deben pasarse al componente como variables y qué atributos deben colocarse en la bolsa de atributos del componente.
Puedes especificar qué atributos deben considerarse variables de datos utilizando la directiva @props
en la parte superior de la plantilla de Blade de tu componente. Todos los demás atributos en el componente estarán disponibles a través de la bolsa de atributos del componente. Si deseas asignar un valor predeterminado a una variable de datos, puedes especificar el nombre de la variable como la clave del array y el valor predeterminado como el valor del array:
<!-- /resources/views/components/alert.blade.php --> @props(['type' => 'info', 'message']) <div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}> {{ $message }}</div>
Dada la definición del componente anterior, podemos renderizar el componente de la siguiente manera:
<x-alert type="error" :message="$message" class="mb-4"/>
A veces, es posible que desees acceder a datos de un componente principal dentro de un componente secundario. En estos casos, puedes usar la directiva @aware
. Por ejemplo, imagina que estás construyendo un componente de menú complejo que consta de un componente principal <x-menu>
y un componente secundario <x-menu.item>
:
<x-menu color="purple"> <x-menu.item>...</x-menu.item> <x-menu.item>...</x-menu.item></x-menu>
El componente <x-menu>
puede tener una implementación como la siguiente:
<!-- /resources/views/components/menu/index.blade.php --> @props(['color' => 'gray']) <ul {{ $attributes->merge(['class' => 'bg-'.$color.'-200']) }}> {{ $slot }}</ul>
Dado que el atributo color
solo se pasó al componente principal (<x-menu>
), no estará disponible dentro de <x-menu.item>
. Sin embargo, si usamos la directiva @aware
, podemos hacer que esté disponible también dentro de <x-menu.item>
:
<!-- /resources/views/components/menu/item.blade.php --> @aware(['color' => 'gray']) <li {{ $attributes->merge(['class' => 'text-'.$color.'-800']) }}> {{ $slot }}</li>
Advertencia La directiva
@aware
no puede acceder a datos padres que no se pasan explícitamente al componente padre a través de atributos HTML. Los valores predeterminados de@props
que no se pasan explícitamente al componente padre no pueden ser accedidos por la directiva@aware
.
Como se discutió anteriormente, los componentes anónimos generalmente se definen colocando una plantilla de Blade dentro de tu directorio resources/views/components
. Sin embargo, ocasionalmente querrás registrar otras rutas de componentes anónimos con Laravel además de la ruta predeterminada.
El método anonymousComponentPath
acepta la "ruta" a la ubicación del componente anónimo como su primer argumento y un "espacio de nombres" opcional bajo el cual se deben colocar los componentes como su segundo argumento. Típicamente, este método debe ser llamado desde el método boot
de uno de los proveedores de servicios de tu aplicación:
/** * Inicializa cualquier servicio de la aplicación. */public function boot(): void{ Blade::anonymousComponentPath(__DIR__.'/../components');}
Cuando las rutas de los componentes se registran sin un prefijo especificado como en el ejemplo anterior, también se pueden renderizar en tus componentes de Blade sin un prefijo correspondiente. Por ejemplo, si existe un componente panel.blade.php
en la ruta registrada anteriormente, se puede renderizar así:
<x-panel />
Los "espacios de nombres" de prefijo se pueden proporcionar como segundo argumento al método anonymousComponentPath
:
Blade::anonymousComponentPath(__DIR__.'/../components', 'dashboard');
Cuando se proporciona un prefijo, los componentes dentro de ese "espacio de nombres" pueden renderizarse prefiriendo el espacio de nombres del componente al nombre del componente cuando se renderiza el componente:
<x-dashboard::panel />
La mayoría de las aplicaciones web mantienen el mismo diseño general en varias páginas. Sería increíblemente engorroso y difícil de mantener nuestra aplicación si tuviéramos que repetir todo el HTML de diseño en cada vista que creamos. Afortunadamente, es conveniente definir este diseño como un solo componente Blade y luego usarlo en toda nuestra aplicación.
Por ejemplo, imagina que estamos construyendo una aplicación de lista de tareas. Podríamos definir un componente layout
que se ve así:
<!-- resources/views/components/layout.blade.php --> <html> <head> <title>{{ $title ?? 'Gestor de tareas pendientes' }}</title> </head> <body> <h1>Tarea pendiente</h1> <hr/> {{ $slot }} </body></html>
Una vez que se ha definido el componente layout
, podemos crear una vista de Blade que utilice el componente. En este ejemplo, definiremos una vista simple que muestra nuestra lista de tareas:
<!-- resources/views/tasks.blade.php --> <x-layout> @foreach ($tasks as $task) {{ $task }} @endforeach</x-layout>
Recuerda que el contenido que se inyecta en un componente se suministrará al variable $slot
predeterminado dentro de nuestro componente layout
. Como habrás notado, nuestro layout
también respeta un espacio $title
si se proporciona; de lo contrario, se muestra un título predeterminado. Podemos inyectar un título personalizado desde nuestra vista de lista de tareas usando la sintaxis de ranura estándar discutida en la documentación de componentes:
<!-- resources/views/tasks.blade.php --> <x-layout> <x-slot:title> Título personalizado </x-slot> @foreach ($tasks as $task) {{ $task }} @endforeach</x-layout>
Ahora que hemos definido nuestro diseño y vistas de lista de tareas, solo necesitamos devolver la vista task
desde una ruta:
use App\Models\Task; Route::get('/tasks', function () { return view('tasks', ['tasks' => Task::all()]);});
Los diseños también se pueden crear mediante "herencia de plantillas". Esta fue la forma principal de construir aplicaciones antes de la introducción de componentes.
Para empezar, veamos un ejemplo simple. Primero, examinaremos un diseño de página. Dado que la mayoría de las aplicaciones web mantienen el mismo diseño general en varias páginas, es conveniente definir este diseño como una única vista de Blade:
<!-- resources/views/layouts/app.blade.php --> <html> <head> <title>Nombre de la aplicación - @yield('title')</title> </head> <body> @section('sidebar') Este es la barra lateral principal. @show <div class="container"> @yield('content') </div> </body></html>
Como puedes ver, este archivo contiene marcas HTML típicas. Sin embargo, ten en cuenta las directivas @section
y @yield
. La directiva @section
, como su nombre indica, define una sección de contenido, mientras que la directiva @yield
se utiliza para mostrar el contenido de una sección dada.
Ahora que hemos definido un diseño para nuestra aplicación, definamos una página secundaria que herede el diseño.
Al definir una vista secundaria, utiliza la directiva de Blade @extends
para especificar qué diseño debe "heredar" la vista secundaria. Las vistas que extienden un diseño de Blade pueden inyectar contenido en las secciones del diseño mediante directivas @section
. Recuerda, como se ve en el ejemplo anterior, el contenido de estas secciones se mostrará en el diseño mediante @yield
:
<!-- resources/views/child.blade.php --> @extends('layouts.app') @section('title', 'Page Title') @section('sidebar') @parent <p>Esto se añadirá a la barra lateral principal.</p>@endsection @section('content') <p>Este es el contenido de mi cuerpo.</p>@endsection
En este ejemplo, la sección sidebar
utiliza la directiva @parent
para agregar (en lugar de sobrescribir) contenido a la barra lateral del diseño. La directiva @parent
se reemplazará por el contenido del diseño cuando se renderice la vista.
Nota A diferencia del ejemplo anterior, esta sección
sidebar
termina con@endsection
en lugar de@show
. La directiva@endsection
solo definirá una sección mientras que@show
definirá y rendirá inmediatamente la sección.
La directiva @yield
también acepta un valor predeterminado como su segundo parámetro. Este valor se renderizará si la sección que se está cediendo está indefinida:
@yield('content', 'Contenido predeterminado')
Siempre que definas un formulario HTML en tu aplicación, debes incluir un campo de token CSRF oculto en el formulario para que el middleware de protección CSRF pueda validar la solicitud. Puedes usar la directiva de Blade @csrf
para generar el campo de token:
<form method="POST" action="/profile"> @csrf ...</form>
Dado que los formularios HTML no pueden realizar solicitudes PUT
, PATCH
o DELETE
, deberás agregar un campo oculto _method
para simular estos verbos HTTP. La directiva de Blade @method
puede crear este campo por ti:
<form action="/foo/bar" method="POST"> @method('PUT') ...</form>
La directiva @error
se puede usar para verificar rápidamente si existen mensajes de error de validación para un atributo dado. Dentro de una directiva @error
, puedes imprimir la variable $message
para mostrar el mensaje de error:
<!-- /resources/views/post/create.blade.php --> <label for="title">Título de la publicación</label> <input id="title" type="text" class="@error('title') is-invalid @enderror"> @error('title') <div class="alert alert-danger">{{ $message }}</div>@enderror
Dado que la directiva @error
se compila a una declaración "if", puedes usar la directiva @else
para renderizar contenido cuando no hay un error para un atributo:
<!-- /resources/views/auth.blade.php --> <label for="email">Dirección de correo electrónico</label> <input id="email" type="email" class="@error('email') is-invalid @else is-valid @enderror">
Puedes pasar el nombre de una bolsa de errores específica como segundo parámetro a la directiva @error
para recuperar mensajes de error de validación en páginas que contienen múltiples formularios:
<!-- /resources/views/auth.blade.php --> <label for="email">Dirección de correo electrónico</label> <input id="email" type="email" class="@error('email', 'login') is-invalid @enderror"> @error('email', 'login') <div class="alert alert-danger">{{ $message }}</div>@enderror
Blade te permite agregar a pilas con nombres que se pueden renderizar en otro lugar, en otra vista o diseño. Esto puede ser particularmente útil para especificar cualquier biblioteca de JavaScript requerida por tus vistas secundarias:
@push('scripts') <script src="/example.js"></script>@endpush
Si deseas @push
contenido si una expresión booleana dada se evalúa como true
, puedes usar la directiva @pushIf
:
@pushIf($shouldPush, 'scripts') <script src="/example.js"></script>@endPushIf
Puedes agregar contenido a una pila tantas veces como sea necesario. Para renderizar el contenido completo de la pila, pasa el nombre de la pila a la directiva @stack
:
<head> <!-- Contenidos de la cabeza --> @stack('scripts')</head>
Si deseas agregar contenido al principio de una pila, debes usar la directiva @prepend
:
@push('scripts') Esto será segundo...@endpush // Esto será primero... @prepend('scripts') Esto será primero...@endprepend
La directiva @inject
se puede utilizar para recuperar un servicio del contenedor de servicios de Laravel. El primer argumento pasado a @inject
es el nombre de la variable en la que se colocará el servicio, mientras que el segundo argumento es la clase o nombre de interfaz del servicio que deseas resolver:
@inject('metrics', 'App\Services\MetricsService') <div> Ingresos mensuales:: {{ $metrics->monthlyRevenue() }}.</div>
A veces, es posible que necesites transformar una cadena de plantilla Blade sin procesar en HTML válido. Puedes lograr esto usando el método render
proporcionado por el facade Blade
. El método render
acepta la cadena de plantilla Blade y un array opcional de datos para proporcionar a la plantilla:
use Illuminate\Support\Facades\Blade; return Blade::render('Hola, {{ $name }}', ['name' => 'Julian Bashir']);
Laravel renderiza plantillas Blade en línea escribiéndolas en el directorio storage/framework/views
. Si deseas que Laravel elimine estos archivos temporales después de renderizar la plantilla Blade, puedes proporcionar el argumento deleteCachedView
al método:
return Blade::render( 'Hola, {{ $name }}', ['name' => 'Julian Bashir'], deleteCachedView: true);
Cuando usas frameworks frontend como Turbo y htmx, a veces necesitarás devolver solo una parte de una plantilla Blade en tu respuesta HTTP. Los "fragmentos" de Blade te permiten hacer precisamente eso. Para empezar, coloca una parte de tu plantilla Blade dentro de las directivas @fragment
y @endfragment
:
@fragment('user-list') <ul> @foreach ($users as $user) <li>{{ $user->name }}</li> @endforeach </ul>@endfragment
Luego, al renderizar la vista que utiliza esta plantilla, puedes invocar el método fragment
para especificar que solo el fragmento especificado debe incluirse en la respuesta HTTP saliente:
return view('dashboard', ['users' => $users])->fragment('user-list');
El método fragmentIf
te permite devolver condicionalmente un fragmento de una vista según una condición dada. De lo contrario, se devolverá la vista completa:
return view('dashboard', ['users' => $users]) ->fragmentIf($request->hasHeader('HX-Request'), 'user-list');
Los métodos fragments
y fragmentsIf
te permiten devolver varios fragmentos de vista en la respuesta. Los fragmentos se concatenarán:
view('dashboard', ['users' => $users]) ->fragments(['user-list', 'comment-list']); view('dashboard', ['users' => $users]) ->fragmentsIf( $request->hasHeader('HX-Request'), ['user-list', 'comment-list'] );
Blade te permite definir tus propias directivas personalizadas mediante el método directive
. Cuando el compilador Blade encuentra la directiva personalizada, llamará a la devolución de llamada proporcionada con la expresión que contiene la directiva.
El siguiente ejemplo crea una directiva @datetime($var)
que formatea un $var
dado, que debería ser una instancia de DateTime
:
<?php namespace App\Providers; use Illuminate\Support\Facades\Blade;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * Registra cualquier servicio de la aplicación. */ public function register(): void { // ... } /** * Inicializa cualquier servicio de la aplicación. */ public function boot(): void { Blade::directive('datetime', function (string $expression) { return "<?php echo ($expression)->format('m/d/Y H:i'); ?>"; }); }}
Como puedes ver, encadenaremos el método format
en cualquier expresión que se pase a la directiva. Entonces, en este ejemplo, el PHP final generado por esta directiva será:
<?php echo ($var)->format('m/d/Y H:i'); ?>
Advertencia Después de actualizar la lógica de una directiva de Blade, deberás eliminar todas las vistas de Blade en caché. Las vistas de Blade en caché se pueden eliminar utilizando el comando
view:clear
de Artisan.
Si intentas "hacer eco" de un objeto usando Blade, se invocará el método __toString
del objeto. El método __toString
es uno de los "métodos mágicos" integrados de PHP. Sin embargo, a veces es posible que no tengas control sobre el método __toString
de una clase determinada, como cuando la clase con la que estás interactuando pertenece a una biblioteca de terceros.
En estos casos, Blade te permite registrar un manejador de echo personalizado para ese tipo particular de objeto. Para lograr esto, debes invocar el método stringable
de Blade. El método stringable
acepta un cierre. Este cierre debe hacer una sugerencia de tipo del tipo de objeto del que es responsable de renderizar. Normalmente, el método stringable
debe invocarse dentro del método boot
de la clase AppServiceProvider
de tu aplicación:
use Illuminate\Support\Facades\Blade;use Money\Money; /** * Inicializa cualquier servicio de la aplicación. */public function boot(): void{ Blade::stringable(function (Money $money) { return $money->formatTo('en_GB'); });}
Programar una directiva personalizada a veces es más complejo de lo necesario al definir declaraciones condicionales personalizadas simples. Por esa razón, Blade proporciona un método Blade::if
que te permite definir rápidamente directivas condicionales personalizadas utilizando cierres. Por ejemplo, definamos una condición personalizada que verifique el "disco" predeterminado configurado para la aplicación. Podemos hacer esto en el método boot
de nuestro AppServiceProvider
:
Cost: {{ $money }}
Programar una directiva personalizada a veces es más complejo de lo necesario al definir declaraciones condicionales simples. Por esa razón, Blade proporciona un método Blade::if
que te permite definir rápidamente directivas condicionales personalizadas mediante cierres. Por ejemplo, veamos cómo definir una condición personalizada que verifica el "disco" predeterminado configurado para la aplicación. Podemos hacer esto en el método boot
de nuestro AppServiceProvider
:
use Illuminate\Support\Facades\Blade; /** * Inicializa cualquier servicio de la aplicación. */public function boot(): void{ Blade::if('disk', function (string $value) { return config('filesystems.default') === $value; });}
Una vez que se haya definido la condición personalizada, puedes usarla en tus plantillas:
@disk('local') <!-- La aplicación está utilizando el disco local... -->@elsedisk('s3') <!-- La aplicación está utilizando el disco s3... -->@else <!-- La aplicación está utilizando algún otro disco... -->@enddisk @unlessdisk('local') <!-- La aplicación no está utilizando el disco local... -->@enddisk