> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Plantillas Blade

> Explicamos la sintaxis básica, las estructuras de control, los bucles y la herencia de layouts del motor de plantillas Blade de Laravel.

## Introducción

Blade es el motor de plantillas simple pero potente que incluye Laravel.
A diferencia de algunos motores de plantillas de PHP, Blade no limita el uso de código PHP puro dentro de las plantillas.
Todas las plantillas Blade se compilan a código PHP y se cachean, por lo que apenas añade sobrecarga a la aplicación.

Los archivos de plantilla Blade usan la extensión `.blade.php` y normalmente se guardan en el directorio `resources/views`.

### Flujo de compilación de Blade

Muestra cómo un archivo `.blade.php` se convierte en una respuesta HTML. Una vez compilado, el archivo se cachea; las siguientes solicitudes de la misma plantilla saltan la compilación.

```mermaid theme={null}
flowchart LR
    A["Archivo .blade.php"] --> B{"¿Existe caché?"}
    B -->|"Sí"| C["Usa el PHP cacheado"]
    B -->|"No"| D["Compilador Blade"]
    D --> E["Se transforma a PHP"]
    E --> F["Se guarda en storage/framework/views/"]
    F --> G["Se ejecuta PHP"]
    C --> G
    G --> H["Respuesta HTML"]
```

```php theme={null}
Route::get('/', function () {
    return view('greeting', ['name' => 'Taro']);
});
```

## Mostrar datos

Para mostrar datos pasados a la vista, encierra la variable entre dobles llaves.

```blade theme={null}
Hola, {{ $name }}.
```

<Info>
  `{{ }}` de Blade pasa automáticamente el valor por `htmlspecialchars` de PHP para prevenir ataques XSS.
</Info>

También puedes mostrar el resultado de funciones PHP.

```blade theme={null}
Timestamp UNIX actual: {{ time() }}
```

### Mostrar sin escapar

Para mostrar sin escapar, usa la sintaxis `{!! !!}`.

```blade theme={null}
Hola, {!! $name !!}.
```

<Warning>
  Cuando muestres datos introducidos por el usuario, usa siempre `{{ }}` para mantener el escape automático.
  Usar `{!! !!}` con entrada no confiable provoca vulnerabilidades XSS.
</Warning>

### Convivencia con frameworks JavaScript

Si tu framework JavaScript también usa llaves, escapa el renderizado de Blade con `@`.

```blade theme={null}
<h1>Laravel</h1>

Hola, @{{ name }}.
```

Blade elimina la `@` y `{{ name }}` llega tal cual al navegador para que lo procese el framework de JavaScript.

<Info>
  Si dudas entre centrarte en Blade o ampliar hacia Livewire o Inertia, consulta [Frontend](/es/frontend).
</Info>

## Directivas de Blade

### Condicionales (if)

```blade theme={null}
@if (count($records) === 1)
    Hay 1 registro.
@elseif (count($records) > 1)
    Hay varios registros.
@else
    No hay registros.
@endif
```

`@unless` permite escribir "salvo que…".

```blade theme={null}
@unless (Auth::check())
    No has iniciado sesión.
@endunless
```

Para comprobar si una variable está definida o no es null, usa `@isset` y `@empty`.

```blade theme={null}
@isset($records)
    // Si $records está definido y no es null
@endisset

@empty($records)
    // Si $records está "vacío"
@endempty
```

### Directivas de autenticación

```blade theme={null}
@auth
    // Contenido para usuarios autenticados
@endauth

@guest
    // Contenido para usuarios no autenticados
@endguest
```

### Switch

```blade theme={null}
@switch($i)
    @case(1)
        Primer caso...
        @break

    @case(2)
        Segundo caso...
        @break

    @default
        Caso por defecto...
@endswitch
```

### Bucles

Blade ofrece directivas cómodas para bucles.

```blade theme={null}
@for ($i = 0; $i < 10; $i++)
    Valor actual: {{ $i }}
@endfor

@foreach ($users as $user)
    <p>Usuario: {{ $user->name }}</p>
@endforeach

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

@while (true)
    <p>Bucle infinito.</p>
@endwhile
```

Dentro del bucle, `@break` y `@continue` controlan el flujo.

```blade theme={null}
@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif

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

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

También se puede pasar la condición directamente a la directiva.

```blade theme={null}
@foreach ($users as $user)
    @continue($user->type == 1)

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

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

### Variable de bucle

Dentro de `@foreach` puedes usar `$loop` para obtener información del bucle.

```blade theme={null}
@foreach ($users as $user)
    @if ($loop->first)
        Es la primera iteración.
    @endif

    @if ($loop->last)
        Es la última iteración.
    @endif

    <p>Usuario: {{ $user->name }}</p>
@endforeach
```

| Propiedad          | Descripción                                     |
| ------------------ | ----------------------------------------------- |
| `$loop->index`     | Índice actual (empieza en 0)                    |
| `$loop->iteration` | Número de iteración (empieza en 1)              |
| `$loop->remaining` | Iteraciones restantes                           |
| `$loop->count`     | Número de elementos del array                   |
| `$loop->first`     | ¿Primera iteración?                             |
| `$loop->last`      | ¿Última iteración?                              |
| `$loop->even`      | ¿Iteración par?                                 |
| `$loop->odd`       | ¿Iteración impar?                               |
| `$loop->depth`     | Nivel de anidación actual                       |
| `$loop->parent`    | En bucles anidados, la variable del bucle padre |

## Comentarios

Los comentarios de Blade no aparecen en la página renderizada.

```blade theme={null}
{{-- Este comentario no aparecerá en el HTML renderizado --}}
```

## Layouts

### Layout con componentes

Para crear layouts en Laravel se recomiendan los componentes Blade.

Primero, crea el componente de layout.

```blade theme={null}
<!-- resources/views/components/layout.blade.php -->
<html>
    <head>
        <title>{{ $title ?? 'Nombre de la app' }}</title>
    </head>
    <body>
        <header>
            <nav>
                <!-- Navegación -->
            </nav>
        </header>

        <main>
            {{ $slot }}
        </main>
    </body>
</html>
```

Después, crea una vista que use ese layout.

```blade theme={null}
<!-- resources/views/dashboard.blade.php -->
<x-layout>
    <x-slot:title>Dashboard</x-slot>

    <h1>Dashboard</h1>
    <p>¡Bienvenido!</p>
</x-layout>
```

### Layout con herencia de plantillas

La forma clásica usa herencia con `@extends`, `@section` y `@yield`.

```mermaid theme={null}
flowchart TD
    A["Vista hija<br>@extends('layouts.app')"] --> B["Layout padre<br>layouts/app.blade.php"]
    A --> C["@section('title', 'Página hija')"]
    A --> D["@section('content')<br>Cuerpo del contenido<br>@endsection"]
    B --> E["@yield('title')<br>← inserta title"]
    B --> F["@yield('content')<br>← inserta content"]
    C --> E
    D --> F
    E --> G["HTML final"]
    F --> G
```

**Definición del layout padre:**

```blade theme={null}
<!-- resources/views/layouts/app.blade.php -->
<html>
    <head>
        <title>Nombre de la app - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            Sidebar por defecto
        @show

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

**Uso del layout en la vista hija:**

```blade theme={null}
<!-- resources/views/child.blade.php -->
@extends('layouts.app')

@section('title', 'Página hija')

@section('sidebar')
    @parent

    <p>Contenido adicional del sidebar</p>
@endsection

@section('content')
    <p>Cuerpo del contenido</p>
@endsection
```

<Info>
  Con `@parent` puedes conservar el contenido del `@section` padre y añadir más.
</Info>

## Incluir subvistas

`@include` incrusta una vista Blade dentro de otra.
Todas las variables disponibles en la vista padre lo estarán también en la incluida.

```blade theme={null}
<div>
    @include('shared.errors')

    <form>
        <!-- Contenido del formulario -->
    </form>
</div>
```

También puedes pasar variables adicionales.

```blade theme={null}
@include('view.name', ['status' => 'complete'])
```

## Protección CSRF en formularios

En formularios HTML que envíen `POST`, `PUT`, `PATCH` o `DELETE` en rutas del archivo `web`, incluye siempre `@csrf`.

```blade theme={null}
<form method="POST" action="/profile">
    @csrf

    <!-- Campos del formulario -->
</form>
```

Para enviar `PUT`, `PATCH` o `DELETE` desde un formulario, usa `@method`.

```blade theme={null}
<form method="POST" action="/post/1">
    @csrf
    @method('DELETE')

    <button type="submit">Eliminar</button>
</form>
```

<Info>
  Consulta [Protección CSRF](/es/csrf) para los detalles operativos, como la validación de Origin y las cabeceras `X-CSRF-TOKEN` / `X-XSRF-TOKEN`.
</Info>

## Resumen

Resumen de las funcionalidades principales de Blade.

<AccordionGroup>
  <Accordion title="Mostrar datos">
    `{{ $variable }}` para mostrar con escape; `{!! $variable !!}` sin escape.
  </Accordion>

  <Accordion title="Condicionales">
    `@if`, `@elseif`, `@else`, `@endif`, `@unless`, `@isset`, `@empty`, `@auth`, `@guest`.
  </Accordion>

  <Accordion title="Bucles">
    `@for`, `@foreach`, `@forelse`, `@while` y la variable `$loop`.
  </Accordion>

  <Accordion title="Layouts">
    Basados en componentes (`<x-layout>` con `{{ $slot }}`) o con herencia (`@extends`, `@section`, `@yield`).
  </Accordion>

  <Accordion title="Subvistas">
    Reutilización de vistas con `@include`.
  </Accordion>
</AccordionGroup>


## Related topics

- [Envío de correo](/es/mail.md)
- [Pruebas HTTP](/es/http-tests.md)
- [Bundling de assets con Vite](/es/vite.md)
- [Validación](/es/validation.md)
- [Respuestas](/es/responses.md)
