Plantillas Blade

# Introducción

Blade es un simple pero poderoso motor de plantillas incluido con Laravel. A diferencia de otros populares motores de plantillas para PHP, Blade no limita el uso de código PHP simple en las vistas. Las vistas en Blade se compilan a código PHP y se cachean hasta que son modificadas, básicamente esto se traduce en que Blade añade sobrecarga cero a las aplicaciones. Las vistas en Blade usan la extensión .blade.php y normalmente se almacenan en el directorio resources/views.

# Herencia de plantillas

Definir una plantilla

Dos de los principales beneficios de usar Blade son la herencia de la plantilla y las secciones. Para empezar, echemos un vistazo a un simple ejemplo. Primero, examinaremos un diseño de página "maestro". Dado que la mayoría de las aplicaciones web mantienen la misma disposición general en varias páginas, es conveniente definir esta disposición como una sola vista de Blade:

<!-- Stored in resources/views/layouts/app.blade.php -->

<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            This is the master sidebar.
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

Como puedes ver, este archivo contiene el típico marcado HTML. Sin embargo, toma nota de las directivas @section@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 determinada.

Ahora que hemos definido un diseño para nuestra aplicación, definamos una página hija que herede el diseño.

Extender una plantilla

Cuando defina una vista infantil, utilice la directiva Blade @extends para especificar qué diseño debe "heredar" la vista infantil. Las vistas que extienden un diseño Blade pueden inyectar contenido en las secciones del diseño utilizando las directivas @section. Recuerde que, como se ve en el ejemplo anterior, el contenido de estas secciones se mostrará en la maqueta utilizando @yield:

<!-- Stored in resources/views/child.blade.php -->

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
    @parent

    <p>This is appended to the master sidebar.</p>
@endsection

@section('content')
    <p>This is my body content.</p>
@endsection

En este ejemplo, la sección sidebar utiliza la directiva @parent dpara añadir (en lugar de sobrescribir) contenido a la barra lateral del diseño. La directiva @parent será reemplazada por el contenido de la presentación cuando se renderice la vista.

Al contrario que el ejemplo anterior, esta sección del sidebar termina con @endsection en lugar de @show. La directiva @endsection sólo definirá una sección, mientras que @show definirá e inmediatamente dará la sección.

La directiva @yield también acepta un valor por defecto como segundo parámetro. Este valor se renderizará si la sección que se está rindiendo no está definida:

@yield('content', View::make('view.name'))

Las vistas de las cuchillas pueden ser devueltas de las rutas usando el helper global view:

Route::get('blade', function () {
    return view('child');
});

# Visualización de datos

Puedes mostrar los datos pasados a tus vistas de la cuchilla envolviendo la variable con tirantes rizados. Por ejemplo, dada la siguiente ruta:

Route::get('greeting', function () {
    return view('welcome', ['name' => 'Samantha']);
});

Puedes mostrar el contenido de la variable name de esta manera:

Hello, {{ $name }}.

Las declaraciones de Blade {{ }} se envían automáticamente a través de la función htmlspecialchars de PHP para prevenir ataques XSS

No se limita a mostrar el contenido de las variables pasadas a la vista. También puedes hacerte eco de los resultados de cualquier función PHP. De hecho, puedes poner cualquier código PHP que desees dentro de una declaración de eco de Blade:

The current UNIX timestamp is {{ time() }}.

Mostrando datos no escapados

Por defecto, las declaraciones de Blade {{ }} sse envían automáticamente a través de la función htmlspecialchars de PHP para prevenir ataques XSS. Si no quiere que sus datos se escapen, puede usar la siguiente sintaxis:

Hello, {!! $name !!}.

Tenga mucho cuidado al hacer eco de los contenidos suministrados por los usuarios de su aplicación. Utilice siempre la sintaxis de doble rizo escapado para evitar ataques XSS cuando muestre datos suministrados por el usuario.

Renderizando JSON

A veces puede pasar un array a su vista con la intención de renderizarlo como JSON para inicializar una variable JavaScript. Por ejemplo:

<script>
    var app = <?php echo json_encode($array); ?>;
</script>

Sin embargo, en lugar de llamar manualmente a json_encode, puedes usar la directiva @json. La directiva  @json acepta los mismos argumentos que la función json_encode de PHP:

<script>
    var app = @json($array);

    var app = @json($array, JSON_PRETTY_PRINT);
</script>

Sólo debes usar la directiva @json para convertir las variables existentes en JSON. La plantilla de Blade se basa en expresiones regulares y los intentos de pasar una expresión compleja a la directiva pueden causar fallos inesperados.

Codificación de entidades HTML

Por defecto, Blade (y el ayudante Laravel e) ) codificarán doblemente las entidades HTML. Si desea desactivar la doble codificación, llame al método Blade::withoutDoubleEncoding desde el método boot de su AppServiceProvider:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Blade::withoutDoubleEncoding();
    }
}

Blade & JavaScript Frameworks

Dado que muchos marcos de JavaScript también utilizan llaves "rizadas" para indicar que una expresión determinada debe mostrarse en el navegador, puede utilizar el símbolo @ para informar al motor de renderizado Blade de que una expresión debe permanecer intacta. Por ejemplo:

<h1>Laravel</h1>

Hello, @{{ name }}.

En este ejemplo, el símbolo @ será eliminado por Blade; sin embargo, la expresión {{ name }} permanecerá intacta por el motor de Blade, permitiendo que en su lugar sea renderizada por su marco de JavaScript.

El símbolo @ también puede ser usado para escapar de las directivas de Blade:

{{-- Blade --}}
@@json()

<!-- HTML output -->
@json()

La directiva @verbatim

Si está mostrando variables JavaScript en una gran parte de su plantilla, puede envolver el HTML en la directiva @verbatim para no tener que anteponer a cada declaración de eco de Blade un símbolo @:

@verbatim
    <div class="container">
        Hello, {{ name }}.
    </div>
@endverbatim

# Estructuras de control

Además de la herencia de plantillas y la visualización de datos, Blade también proporciona cómodos atajos para las estructuras de control comunes de PHP, como las declaraciones condicionales y los bucles. Estos atajos proporcionan una forma muy limpia y concisa de trabajar con las estructuras de control de PHP, a la vez que resultan familiares para sus homólogos de PHP.

Estructura IF

Puede construir si declaraciones usando las directivas @if, @elseif, @else, y @endif. Estas directivas funcionan de manera idéntica a sus contrapartes de PHP:

@if (count($records) === 1)
    I have one record!
@elseif (count($records) > 1)
    I have multiple records!
@else
    I don't have any records!
@endif

Para mayor comodidad, Blade también proporciona una directiva  @unless:

@unless (Auth::check())
    You are not signed in.
@endunless

Además de las directivas condicionales ya discutidas, las directivas @isset@empty pueden ser usadas como atajos convenientes para sus respectivas funciones de PHP:

@isset($records)
    // $records is defined and is not null...
@endisset

@empty($records)
    // $records is "empty"...
@endempty

Directivas de autenticación

Las directivas @auth and @guest pueden utilizarse para determinar rápidamente si el usuario actual está autenticado o es un invitado:

@auth
    // The user is authenticated...
@endauth

@guest
    // The user is not authenticated...
@endguest

Si es necesario, puede especificar la guardia de autenticación que debe comprobarse cuando se utilizan las directivas @auth@guest:

@auth('admin')
    // The user is authenticated...
@endauth

@guest('admin')
    // The user is not authenticated...
@endguest

Directiva section

Puedes comprobar si una sección tiene contenido usando la directiva @hasSection:

@hasSection('navigation')
    <div class="pull-right">
        @yield('navigation')
    </div>

    <div class="clearfix"></div>
@endif

Puede utilizar la directiva sectionMissing para determinar si una sección no tiene contenido:

@sectionMissing('navigation')
    <div class="pull-right">
        @include('default-navigation')
    </div>
@endif

Directiva Environment

Puede comprobar si la aplicación se está ejecutando en el entorno de producción utilizando la directiva @production:

@production
    // Production specific content...
@endproduction

O bien, puede determinar si la aplicación se está ejecutando en un entorno específico utilizando la directiva @env:

@env('staging')
    // The application is running in "staging"...
@endenv

@env(['staging', 'production'])
    // The application is running in "staging" or "production"...
@endenv

Estructura Switch

Las declaraciones de los interruptores pueden construirse usando las directivas @switch, @case, @break, @default@endswitch:

@switch($i)
    @case(1)
        First case...
        @break

    @case(2)
        Second case...
        @break

    @default
        Default case...
@endswitch

Loops

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 forma idéntica a sus contrapartes de PHP:

@for ($i = 0; $i < 10; $i++)
    The current value is {{ $i }}
@endfor

@foreach ($users as $user)
    <p>This is user {{ $user->id }}</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>No users</p>
@endforelse

@while (true)
    <p>I'm looping forever.</p>
@endwhile

Cuando se hace un bucle, se puede utilizar la "loop variable" para obtener información valiosa sobre el bucle, como por ejemplo si se está en la primera o en la última iteración a través del bucle.

Cuando se usan los bucles también se puede terminar el bucle o saltar la iteración actual:

@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif

    <li>{{ $user->name }}</li>

    @if ($user->number == 5)
        @break
    @endif
@endforeach

También puede incluir la condición con la declaración de la directiva en una línea:

@foreach ($users as $user)
    @continue($user->type == 1)

    <li>{{ $user->name }}</li>

    @break($user->number == 5)
@endforeach

La variable Loop

Al hacer un bucle, una variable $loop estará disponible dentro de tu bucle. Esta variable proporciona acceso a algunos bits útiles de información como el índice del bucle actual y si esta es la primera o la última iteración a través del bucle:

@foreach ($users as $user)
    @if ($loop->first)
        This is the first iteration.
    @endif

    @if ($loop->last)
        This is the last iteration.
    @endif

    <p>This is user {{ $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)
            This is first iteration of the parent loop.
        @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 del bucle actual (comienza en 0).
$loop->iteration La iteración del bucle actual (comienza en 1).
$loop->remaining Las iteraciones que quedan en el bucle.
$loop->count El número total de elementos de 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 se trata de una iteración uniforme a través del bucle.
$loop->odd Si se trata de una iteración extraña a través del bucle.
$loop->depth El nivel de anidación del bucle actual.
$loop->parent Cuando en un bucle anidado, la variable de bucle del padre.

Comentarios

Blade también le permite definir comentarios en sus vistas. Sin embargo, a diferencia de los comentarios HTML, los comentarios de Blade no se incluyen en el HTML devuelto por su aplicación:

{{-- This comment will not be present in the rendered HTML --}}

PHP

En algunas situaciones, es útil incrustar código PHP en sus vistas. Puedes usar la directiva Blade @php para ejecutar un bloque de PHP plano dentro de tu plantilla:

@php
    //
@endphp

Aunque Blade proporciona esta característica, su uso frecuente puede ser una señal de que tiene demasiada lógica incrustada en su plantilla.

La directiva @once

La directiva @once permite definir una porción de la plantilla que sólo será evaluada una vez por ciclo de renderizado. Esto puede ser útil para empujar un trozo determinado de JavaScript en el encabezado de la página usando stacks. Por ejemplo, si está renderizando un component dado dentro de un bucle, puede que desee empujar el JavaScript al encabezado sólo la primera vez que se renderice el componente:

@once
    @push('scripts')
        <script>
            // Your custom JavaScript...
        </script>
    @endpush
@endonce

# Formularios

CSRF Field

Cada vez que defina un formulario HTML en su aplicación, debe incluir un campo oculto de token CSRF en el formulario para que el middleware de protección CSRF pueda validar la solicitud. Puede usar la directiva @csrf Blade para generar el campo token:

<form method="POST" action="/profile">
    @csrf

    ...
</form>

Metodo Field

Como los formularios HTML no pueden hacer peticiones PUT, PATCH, or DELETE,necesitarás añadir un campo _method oculto para falsificar estos verbos HTTP. La directiva Blade @method puede crear este campo para usted:

<form action="/foo/bar" method="POST">
    @method('PUT')

    ...
</form>

Errores de validación

La directiva @error puede utilizarse para comprobar rápidamente si existen mensajes de error de validación para un atributo determinado. Dentro de una directiva @error, puede hacer eco de la variable $message para mostrar el mensaje de error:

<!-- /resources/views/post/create.blade.php -->

<label for="title">Post Title</label>

<input id="title" type="text" class="@error('title') is-invalid @enderror">

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

Puede pasar el nombre de una bolsa de errores específica como segundo parámetro a la directiva @error para recuperar los mensajes de error de validación en páginas que contienen múltiples formularios:

<!-- /resources/views/auth.blade.php -->

<label for="email">Email address</label>

<input id="email" type="email" class="@error('email', 'login') is-invalid @enderror">

@error('email', 'login')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

# Componentes

Los componentes y slots proporcionan beneficios similares a las secciones y layouts; sin embargo, algunos pueden encontrar el modelo mental de los componentes y slots 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 los componentes, crearemos un simple componente 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 de resources/views/components.

Registro manual de los componentes del paquete

Al escribir componentes para su propia aplicación, los componentes se descubren automáticamente dentro del directorio app/View/Components y del directorio resources/views/components.

Sin embargo, si está construyendo un paquete que utiliza componentes Blade, tendrá que registrar manualmente su clase de componente y su alias de etiqueta HTML. Por lo general, deberá registrar sus componentes en el método "boot" del proveedor de servicios de su paquete:

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap your package's services.
 */
public function boot()
{
    Blade::component('package-alert', AlertComponent::class);
}

Una vez que su componente ha sido registrado, puede ser renderizado usando su alias de etiqueta:

<x-package-alert/>

Alternativamente, puede usar el método componentNamespace para autolimpiar las clases de componentes por convención. Por ejemplo, un paquete Nightshade podría tener componentes CalendarColorPicker que residen dentro del namespace Package\Views\Components:

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap your package's services.
 */
public function boot()
{
    Blade::componentNamespace('Nightshade\\Views\\Components', 'nightshade');
}

Esto permitirá el uso de los componentes del paquete por su espacio de nombre de proveedor usando la sintaxis package-name::

<x-nightshade::calendar />
<x-nightshade::color-picker />

Blade detectará automáticamente la clase que está vinculada a este componente al poner en pascal el nombre del componente. Los subdirectorios también son soportados usando la notación "dot"

Mostrando los componentes

Para mostrar un componente, puede utilizar una etiqueta de componente Blade dentro de una de sus plantillas Blade. Las etiquetas de componentes Blade empiezan con la cadena x- seguida del kebab case del nombre de la clase del componente.

<x-alert/>

<x-user-profile/>

Si la clase de componente está anidada más profundamente dentro del directorio App\View\Components, puede utilizar el carácter "." para indicar la anidación del directorio. Por ejemplo, si asumimos que un componente se encuentra en App\View\Components\Inputs\Button.php, podemos representarlo así:

<x-inputs.button/>

Pasar datos a los componentes

Puede pasar datos a los componentes de Blade utilizando atributos HTML. Se pueden pasar valores primitivos de código duro al componente usando simples atributos HTML. Las expresiones y variables de PHP deben ser pasadas al componente mediante atributos que utilicen el carácter ":" como prefijo:

<x-alert type="error" :message="$message"/>

Debería definir los datos necesarios del componente en su constructor de clase. Todas las propiedades públicas de 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;

class Alert extends Component
{
    /**
     * The alert type.
     *
     * @var string
     */
    public $type;

    /**
     * The alert message.
     *
     * @var string
     */
    public $message;

    /**
     * Create the component instance.
     *
     * @param  string  $type
     * @param  string  $message
     * @return void
     */
    public function __construct($type, $message)
    {
        $this->type = $type;
        $this->message = $message;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.alert');
    }
}

Cuando su componente se renderiza, puede mostrar el contenido de las variables públicas de su componente haciendo eco de las variables por nombre:

<div class="alert alert-{{ $type }}">
    {{ $message }}
</div>

Casing

Los argumentos de los constructores de componentes deben ser especificados usando camelCase, mientras que el kebab-case debe ser usado cuando se hace referencia a los nombres de los argumentos en sus atributos HTML. Por ejemplo, dado el siguiente constructor de componentes:

/**
 * Create the component instance.
 *
 * @param  string  $alertType
 * @return void
 */
public function __construct($alertType)
{
    $this->alertType = $alertType;
}

El argumento $alertType se puede proporcionar así:

<x-alert alert-type="danger" />

Métodos de componentes

Además de las variables públicas disponibles en la plantilla de su componente, también se puede ejecutar cualquier método público en el componente. Por ejemplo, imagine un componente que tiene un método isSelected:

/**
 * Determine if the given option is the current selected option.
 *
 * @param  string  $option
 * @return bool
 */
public function isSelected($option)
{
    return $option === $this->selected;
}

Puede ejecutar este método desde su plantilla de componentes invocando la variable que coincida con el nombre del método:

<option {{ $isSelected($value) ? 'selected="selected"' : '' }} value="{{ $value }}">
    {{ $label }}
</option>

Usando atributos y slots dentro de la clase

Los componentes de la hoja también permiten acceder al nombre del componente, los atributos y la ranura dentro del método de renderización de la clase. Sin embargo, para acceder a estos datos, debe devolver un Cierre del método render del componente. El Closure recibirá un array $data como único argumento:

/**
 * Get the view / contents that represent the component.
 *
 * @return \Illuminate\View\View|\Closure|string
 */
public function render()
{
    return function (array $data) {
        // $data['componentName'];
        // $data['attributes'];
        // $data['slot'];

        return '<div>Components content</div>';
    };
}

El componentName es igual al nombre utilizado en la etiqueta HTML después del prefijo x-. Así que <x-alert /> del componentName será "alert". el elemento "attributes" contendrá todos los atributos que estaban presentes en el tag HTML. El elemento slot es una instancia Illuminate\Support\HtmlString con el contenido del slot del componente.

El cierre debería devolver una cuerda. Si la cadena devuelta corresponde a una vista existente, esa vista se renderizará; de lo contrario, la cadena devuelta se evaluará como una vista en línea de la hoja.

Dependencias adicionales

Si su componente requiere dependencias del contenedor de servicios de Laravel, puede enumerarlas antes de cualquiera de los atributos de datos del componente y serán inyectadas automáticamente por el contenedor:

use App\Services\AlertCreator

/**
 * Create the component instance.
 *
 * @param  \App\Services\AlertCreator  $creator
 * @param  string  $type
 * @param  string  $message
 * @return void
 */
public function __construct(AlertCreator $creator, $type, $message)
{
    $this->creator = $creator;
    $this->type = $type;
    $this->message = $message;
}

Manejo de atributos

Ya hemos examinado la forma de pasar atributos de datos a un componente; sin embargo, a veces puede ser necesario especificar atributos HTML adicionales, como class, que no forman parte de los datos necesarios para el funcionamiento de un componente. Normalmente, se desea pasar estos atributos adicionales al elemento raíz de la plantilla del componente. Por ejemplo, imagínese que queremos hacer un componente alert de esta manera:

<x-alert type="error" :message="$message" class="mt-4"/>

Todos los atributos que no forman parte del constructor del componente se añadirán automáticamente a la "bolsa de atributos" del componente. Esta bolsa de atributos se pone automáticamente a disposición del componente a través de la variable $attributes. Todos los atributos pueden ser mostrados dentro del componente haciendo eco de esta variable:

<div {{ $attributes }}>
    <!-- Component Content -->
</div>

El uso de directivas como @env directamente en un componente no está soportado en este momento.

Atributos predeterminados / fusionados

A veces puede ser necesario especificar valores predeterminados para los atributos o fusionar valores adicionales en algunos de los atributos del componente. Para ello, puede utilizar el método de fusión de la bolsa de atributos:

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>

Si asumimos que este componente se utiliza así:

<x-alert type="error" :message="$message" class="mb-4"/>

El HTML final del componente aparecerá como el siguiente:

<div class="alert alert-error mb-4">
    <!-- Contents of the $message variable -->
</div>

Fusión de atributos que no son de clase

Cuando se fusionan atributos que no son de class los valores proporcionados al método de merge se considerarán los valores "default" vdel atributo que pueden ser sobrescritos por el consumidor del componente. A diferencia de los atributos de "class" los atributos que no son de clase no se añaden entre sí. Por ejemplo, un componente "button" puede tener el siguiente aspecto::

<button {{ $attributes->merge(['type' => 'button']) }}>
    {{ $slot }}
</button>

Para renderizar el componente de botones con un type, personalizado, puede especificarse al consumir el componente. Si no se especifica ningún tipo, se utilizará 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 desea que un atributo distinto de class tenga sus valores juntos, puede utilizar el método prepends:

<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}>
    {{ $slot }}
</div>

Atributos de fltrado

Se pueden filtrar los atributos utilizando el método filter. Este método acepta un cierre que debe devolver true si desea mantener el atributo en la bolsa de atributos:

{{ $attributes->filter(fn ($value, $key) => $key == 'foo') }}

Para mayor comodidad, puede utilizar el método whereStartsWith para recuperar todos los atributos cuyas claves comiencen con una determinada cadena:

{{ $attributes->whereStartsWith('wire:model') }}

Using the first method, you may render the first attribute in a given attribute bag:

{{ $attributes->whereStartsWith('wire:model')->first() }}

Slots

A menudo, tendrá que pasar contenido adicional a su componente a través de "slots".Imaginemos que un componente de alert que hemos creado tiene el siguiente marcado:

<!-- /resources/views/components/alert.blade.php -->

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

Podemos pasar el contenido al slot inyectando el contenido en el componente:

<x-alert>
    <strong>Whoops!</strong> Something went wrong!
</x-alert>

A veces, un componente puede tener que hacer varias ranuras diferentes en diferentes lugares dentro del componente. Modifiquemos nuestro componente de alerta para permitir la inyección de un "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 de la ranura nombrada usando la etiqueta x-slot. . Cualquier contenido que no esté dentro de una etiqueta x-slot se pasará al componente de la variable $slot:

<x-alert>
    <x-slot name="title">
        Server Error
    </x-slot>

    <strong>Whoops!</strong> Something went wrong!
</x-alert>

Scoped Slots

Si ha utilizado un marco de JavaScript como Vue, es posible que esté familiarizado con las "scoped slots", que le permiten acceder a los datos o métodos del componente dentro de su ranura. Puedes lograr un comportamiento similar en Laravel definiendo métodos o propiedades públicas en tu componente y accediendo al componente dentro de tu ranura a través de la variable $component:

<x-alert>
    <x-slot name="title">
        {{ $component->formatAlert('Server Error') }}
    </x-slot>

    <strong>Whoops!</strong> Something went wrong!
</x-alert>

Vistas de los componentes en linea

En el caso de componentes muy pequeños, puede resultar engorroso manejar tanto la clase de componente como la plantilla de vista del componente. Por esta razón, puede devolver el marcado del componente directamente desde el método render:

/**
 * Get the view / contents that represent the component.
 *
 * @return \Illuminate\View\View|\Closure|string
 */
public function render()
{
    return <<<'blade'
        <div class="alert alert-danger">
            {{ $slot }}
        </div>
    blade;
}

Generar vistas de componentes en linea

Para crear un componente que renderice una vista inline puede utilizar la opción en línea cuando ejecute el comando make:component:

php artisan make:component Alert --inline

Componentes anónimos

Al igual que los componentes en línea, los componentes anónimos proporcionan un mecanismo para gestionar un componente a través de un único archivo. Sin embargo, los componentes anónimos utilizan un único archivo de visualización y no tienen ninguna clase asociada. Para definir un componente anónimo, sólo es necesario colocar una plantilla Blade dentro del directorio resources/views/components. Por ejemplo, suponiendo que haya definido un componente en resources/views/components/alert.blade.php:

<x-alert/>

Puede utilizar 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, puede representarlo así:

<x-inputs.button/>

Propiedades / Atributos de los datos

Dado que los componentes anónimos no tienen ninguna clase asociada, cabe preguntarse cómo se puede diferenciar qué datos deben pasarse al componente como variables y qué atributos deben colocarse en la bolsa de atributos del componente.

Puede especificar qué atributos deben considerarse variables de datos utilizando la directiva @props en la parte superior de la plantilla Blade de su componente. Todos los demás atributos del componente estarán disponibles a través de la bolsa de atributos del componente. Si desea dar a una variable de datos un valor predeterminado, puede especificar el nombre de la variable como clave del array y el valor predeterminado como valor del array:

<!-- /resources/views/components/alert.blade.php -->

@props(['type' => 'info', 'message'])

<div {{ $attributes->merge(['class' => 'alert alert-'.$type]) }}>
    {{ $message }}
</div>

Componentes dinamicos

A veces puede ser necesario renderizar un componente pero no saber qué componente debe ser renderizado hasta el tiempo de ejecución. En esta situación, puede utilizar el componente dynamic-component incorporado de Laravel para renderizar el componente en base a un valor o variable en tiempo de ejecución:

<x-dynamic-component :component="$componentName" class="mt-4" />

# Incluyendo sub vistas

La directiva @include de Blade le permite incluir una vista de Blade desde otra vista. Todas las variables que estén disponibles en la vista padre estarán disponibles en 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 puede pasar una serie de datos adicionales a la vista incluida:

@include('view.name', ['some' => 'data'])

If you attempt to @include una vista que no existe, Laravel arrojará un error. Si desea incluir una vista que puede o no estar presente, debe usar la directiva @includeIf:

@includeIf('view.name', ['some' => 'data'])

Si desea @include una vista si una expresión booleana dada se evalúa como true, puede usar la directiva @includeWhen:

@includeWhen($boolean, 'view.name', ['some' => 'data'])

Si desea @include una vista si una expresión booleana dada se evalúa como false, puede usar la directiva @includeUnless:

@includeUnless($boolean, 'view.name', ['some' => 'data'])

Para incluir la primera vista que existe de un determinado conjunto de vistas, puede utilizar la directiva includeFirst:

@includeFirst(['custom.admin', 'admin'], ['some' => 'data'])

Debes evitar usar las constantes __DIR__ y __FILE__ en tus vistas Blade, ya que se referirán a la ubicación de la vista cacheada, compilada.

Incluir alias

Si los datos de su Blade están almacenados en un subdirectorio, puede que desee ponerles un alias para facilitar el acceso. Por ejemplo, imagine un Blade include que esté almacenado en  resources/views/includes/input.blade.php con el siguiente contenido:

<input type="{{ $type ?? 'text' }}">

Puede utilizar el método include para denominar al include desde includes.input hasta input. Típicamente, esto debería hacerse en el método "boot de su AppServiceProvider:

use Illuminate\Support\Facades\Blade;

Blade::include('includes.input', 'input');

Una vez que el "include" ha sido alienado, puedes renderizarlo usando el nombre del alias como directiva de Blade:

@input(['type' => 'email'])

Renderización de vistas para colecciones

Puede combinar los bucles e incluye en una línea con la directiva @each directive:

@each('view.name', $jobs, 'job')

El primer argumento es la vista parcial a renderizar para cada elemento de la matriz o colección. El segundo argumento es la matriz o colección sobre la que se desea iterar, mientras que el tercer argumento es el nombre de la variable que se asignará a la iteración actual dentro de la vista. Así, por ejemplo, si se está iterando sobre una matriz de jobs, normalmente se querrá acceder a cada trabajo como una variable de job entro del parcial de la vista. La clave de la iteración actual estará disponible como la variable key dentro del parcial de la vista.

También puede pasar un cuarto argumento a la directiva @each. Este argumento determina la vista que se mostrará si la matriz dada está vací

@each('view.name', $jobs, 'job', 'view.empty')

Las vistas que se muestran mediante @each no heredan las variables de la vista principal. Si la vista inferior requiere estas variables, debe usar @foreach@include en su lugar.

# Stacks

Blade le permite empujar a pilas con nombre 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 las vistas de su hijo:

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

Puede empujar a una pila tantas veces como sea necesario. Para mostrar el contenido completo de la pila, pasa el nombre de la pila a la directiva @stack:

<head>
    <!-- Head Contents -->

    @stack('scripts')
</head>

Si desea preparar el contenido al principio de una pila, debe usar la directiva @prepend:

@push('scripts')
    This will be second...
@endpush

// Later...

@prepend('scripts')
    This will be first...
@endprepend

# Inyeción de servicio

La directiva @inject puede utilizarse para recuperar un servicio del contenedor de servicio de Laravel. El primer argumento que se pasa a @inject es el nombre de la variable en la que se colocará el servicio, mientras que el segundo argumento es el nombre de la clase o interfaz del servicio que se desea resolver:

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

<div>
    Monthly Revenue: {{ $metrics->monthlyRevenue() }}.
</div>

# Extender Blade

Blade le permite definir sus propias directivas personalizadas usando el método directive. Cuando el compilador Blade se encuentra con la directiva personalizada, llamará a la llamada proporcionada con la expresión que contiene la directiva.

El siguiente ejemplo crea una directiva @datetime($var) que da formato a un $vardado, 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
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Blade::directive('datetime', function ($expression) {
            return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
        });
    }
}

Como pueden ver, encadenaremos el método del format en cualquier expresión que se pase a la directiva. Así que, en este ejemplo, el PHP final generado por esta directiva será:

<?php echo ($var)->format('m/d/Y H:i'); ?>

Después de actualizar la lógica de una directiva Blade, tendrás que borrar todas las vistas Blade almacenadas. Las vistas Blade en caché pueden ser eliminadas usando el comando Artisan view:clear.

Estructuras if personalizadas

La programación de una directiva personalizada es a veces más compleja de lo necesario cuando se definen expresiones condicionales simples y personalizadas. Por esta razón, Blade provee un método Blade::if que permite definir rápidamente una directiva condicional propia utilizando Closures. Por ejemplo, definamos una condición personalizada que compruebe el entorno de aplicación actual. Podemos hacer esto en el método boot de nuestro AppServiceProvider:

use Illuminate\Support\Facades\Blade;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Blade::if('cloud', function ($provider) {
        return config('filesystems.default') === $provider;
    });
}

Una vez definido el condicional personalizado, podemos usarlo fácilmente en nuestras plantillas:

@cloud('digitalocean')
    // The application is using the digitalocean cloud provider...
@elsecloud('aws')
    // The application is using the aws provider...
@else
    // The application is not using the digitalocean or aws environment...
@endcloud

@unlesscloud('aws')
    // The application is not using the aws environment...
@endcloud