Laravel

Laravel

Tutorial Laravel: Vistas y Blade Templates

Descubre el motor de plantillas Blade de Laravel y aprende a mejorar tus vistas con sintaxis elegante y eficiente para un desarrollo ágil.

Aprende Laravel GRATIS y certifícate

Introducción al motor de plantillas Blade

El motor de plantillas Blade es el sistema de templating nativo de Laravel, diseñado para facilitar la creación de vistas de manera eficiente y elegante. Blade proporciona una sintaxis simple y potente que permite combinar código PHP con HTML de forma limpia y legible.

A diferencia de otros motores de plantillas, Blade no limita el uso de código PHP en las vistas. Esto significa que puedes utilizar cualquier expresión o estructura de control de PHP dentro de tus plantillas Blade, aprovechando al máximo las capacidades del lenguaje.

Una de las características destacadas de Blade es que las vistas se compilan en código PHP puro y se almacenan en caché para mejorar el rendimiento de la aplicación. Esto asegura que el proceso de renderizado sea rápido, sin sacrificar la flexibilidad y funcionalidad que ofrece Blade.

Las plantillas Blade utilizan la extensión .blade.php, lo que permite diferenciarlas fácilmente de las vistas PHP tradicionales. Al utilizar esta extensión, Laravel reconoce y procesa automáticamente las vistas con el motor de Blade.

El uso de Blade facilita la implementación de prácticas de desarrollo modernas, como la herencia de plantillas y la inclusión de componentes reutilizables. Esto contribuye a mantener el código organizado y a mejorar la mantenibilidad de las aplicaciones Laravel.

Además, Blade ofrece una serie de directivas que simplifican tareas comunes como mostrar datos, estructuras de control y bucles. Estas directivas proporcionan una sintaxis más limpia y concisa en comparación con el uso directo de etiquetas PHP.

A continuación, se muestra un ejemplo básico de una plantilla Blade:

<!DOCTYPE html>
<html>
<head>
    <title>Mi Aplicación Laravel</title>
</head>
<body>
    <h1>Bienvenido, {{ $nombre }}</h1>
    <p>Este es un ejemplo de una vista utilizando el motor de plantillas Blade.</p>
</body>
</html>

En este ejemplo, se utiliza la sintaxis {{ }} para imprimir variables de forma segura, escapando automáticamente el contenido para prevenir vulnerabilidades como inyección de código.

Lo que daría como resultado:

El motor de plantillas Blade es una herramienta esencial en el desarrollo con Laravel, ya que potencia la creación de vistas dinámicas y escalables, manteniendo el código limpio y eficiente.

Sintaxis y directivas de Blade

El motor de plantillas Blade ofrece una sintaxis limpia y elegante que simplifica la escritura de vistas en Laravel. Las directivas de Blade son construcciones especiales que facilitan la inserción de lógica y estructuras de control directamente en las plantillas, manteniendo el código organizado y legible.

Sintaxis básica

Blade utiliza delimitadores específicos para imprimir valores y ejecutar código:

  • Imprimir variables: Para mostrar el contenido de una variable de forma segura, se utiliza {{ }}. Blade escapará automáticamente el contenido para prevenir ataques de inyección de código.
<h1>Bienvenido, {{ $usuario }}</h1>
  • Imprimir sin escape: Si deseas imprimir contenido sin escaparlo, utiliza {!! !!}. Esto es útil para imprimir HTML que proviene de fuentes seguras.
<div>{!! $contenidoHTML !!}</div>

Directivas de control de flujo

Blade proporciona directivas similares a las estructuras de control de PHP, pero con una sintaxis más limpia:

  • Condicionales:
@if($activo)
  <p>El usuario está activo.</p>
@elseif($suspendido)
  <p>El usuario está suspendido.</p>
@else
  <p>El usuario está inactivo.</p>
@endif

También existe la opción de utilizar la directiva @unless, que es el equivalente a if(!condition):

@unless($usuario->admin)
  <p>No tienes permisos de administrador.</p>
@endunless

Bucles:

  • For:
@for($i = 0; $i < 10; $i++)
  <p>Elemento {{ $i }}</p>
@endfor

  • Foreach:
@foreach($usuarios as $usuario)
  <p>Nombre: {{ $usuario->nombre }}</p>
@endforeach

  • Forelse: Combina @foreach con una comprobación de elementos vacíos.
@forelse($productos as $producto)
  <p>{{ $producto->nombre }}</p>
@empty
  <p>No hay productos disponibles.</p>
@endforelse

  • While:
@while($contador < 5)
  <p>Contador: {{ $contador }}</p>
  <?php $contador++; ?>
@endwhile

Directivas de comentarios

Para agregar comentarios que no se rendericen en el HTML final, utiliza {{-- --}}:

{{-- Este es un comentario que no aparecerá en el código HTML generado --}}

Directivas de inclusión de vistas

  • @include: Inserta una vista dentro de otra, permitiendo reutilizar componentes comunes.
@include('partials.header')
  • @includeIf: Incluye la vista solo si existe.
@includeIf('partials.footer')

Directivas de estructura

  • @extends: Indica que una vista hereda de un layout principal.
@extends('layouts.app')
  • @section y @endsection: Define secciones de contenido que se insertarán en el layout.
@section('contenido')
  <p>Este es el contenido de la página.</p>
@endsection
  • @yield: Marca el lugar en el layout donde se insertará una sección.
<div class="contenido">
  @yield('contenido')
</div>

Directivas de PHP

Para ejecutar código PHP puro dentro de una plantilla Blade, utiliza @php y @endphp:

@php
    $fechaActual = date('d/m/Y');
@endphp

<p>Fecha de hoy: {{ $fechaActual }}</p>

Directivas de variables y condiciones

  • @isset y @endisset: Comprueba si una variable está definida.
@isset($usuario)
  <p>Usuario: {{ $usuario->nombre }}</p>
@endisset
  • @empty y @endempty: Comprueba si una variable está vacía.
@empty($notificaciones)
  <p>No tienes nuevas notificaciones.</p>
@endempty

Directivas de bucles avanzados

Blade proporciona variables especiales dentro de los bucles @foreach:

@foreach($items as $item)
    <p>{{ $loop->iteration }} - {{ $item }}</p>

    @if($loop->first)
        <p>Este es el primer elemento.</p>
    @endif

    @if($loop->last)
        <p>Este es el último elemento.</p>
    @endif
@endforeach

Algunas propiedades disponibles en $loop son:

  • $loop->index: Índice actual del bucle (comienza en 0).
  • $loop->iteration: Número de iteración actual (comienza en 1).
  • $loop->remaining: Número de iteraciones restantes.
  • $loop->count: Número total de elementos en el bucle.
  • $loop->first: Es true si es la primera iteración.
  • $loop->last: Es true si es la última iteración.

Directivas personalizadas

Es posible crear directivas personalizadas para extender la funcionalidad de Blade. Se registran en el método boot del AppServiceProvider:

// En app/Providers/AppServiceProvider.php

public function boot()
{
    Blade::directive('moneda', function ($cantidad) {
        return "<?php echo number_format($cantidad, 2, ',', '.'); ?>";
    });
}

Y se utilizan en las vistas:

<p>Precio: @moneda($producto->precio)</p>

Escape de directivas

Si necesitas mostrar una directiva Blade sin que sea procesada, puedes prefixarla con una @ extra:

@@foreach($elementos as $elemento)
    Esto mostrará literalmente @@foreach
@endforeach

El resultado será:

@foreach($elementos as $elemento)
    Esto mostrará literalmente @@foreach
@endforeach

Estructuras de JSON

Para convertir datos en formato JSON, utiliza la directiva @json:

<script>
    var datos = @json($datos);
</script>

Esto inserta los datos de forma segura en el script, facilitando el paso de información del servidor al cliente.

Plantillas heredadas

La herencia de plantillas permite definir un layout base y extenderlo en diferentes vistas. Esto promueve la reutilización y mantiene un diseño consistente.

Layout base (layouts/app.blade.php):

<!DOCTYPE html>
<html>
<head>
    <title>@yield('titulo')</title>
</head>
<body>
    @include('partials.navbar')

    <div class="contenido">
        @yield('contenido')
    </div>

    @include('partials.footer')
</body>
</html>

Vista que extiende el layout:

@extends('layouts.app')

@section('titulo', 'Página de inicio')

@section('contenido')
    <h1>Bienvenido a la página de inicio</h1>
    <p>Este es el contenido principal.</p>
@endsection

En este ejemplo, se utiliza @section para definir el contenido que se insertará en las áreas marcadas por @yield en el layout.

Componentes y slots

Blade permite crear componentes reutilizables con slots para contenido dinámico:

Componente (resources/views/components/alert.blade.php):

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

Uso del componente:

<x-alert tipo="success">
    ¡Operación realizada con éxito!
</x-alert>

Este enfoque mejora la modularidad y facilita el mantenimiento de componentes de interfaz de usuario.

Layouts y secciones

En Laravel, los layouts son plantillas maestras que permiten definir una estructura común para varias vistas, facilitando la consistencia y reutilización del código. Mediante el uso de layouts, es posible definir elementos como cabeceras, pies de página o barras de navegación en un solo lugar.

Para crear un layout, se utiliza una vista Blade que servirá como plantilla base. Por convención, los layouts se ubican en la carpeta resources/views/layouts. Un ejemplo de un layout básico podría ser:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>@yield('titulo')</title>
    <link rel="stylesheet" href="{{ asset('css/estilos.css') }}">
</head>
<body>
    @include('partials.nav')

    <div class="container">
        @yield('contenido')
    </div>

    @include('partials.footer')
</body>
</html>

En este layout, se utilizan las directivas @yield para definir secciones que serán rellenadas por las vistas hijas. La directiva @yield('titulo') indica el lugar donde se insertará el título de la página, mientras que @yield('contenido') señala dónde se ubicará el contenido principal.

Las secciones son bloques de contenido que las vistas hijas pueden definir y que serán inyectados en los lugares correspondientes del layout. Para extender un layout y definir secciones, se utiliza la directiva @extends al inicio de la vista hija:

@extends('layouts.app')

@section('titulo', 'Página de inicio')

@section('contenido')
    <h1>Bienvenido a nuestra aplicación</h1>
    <p>Aquí encontrarás información relevante sobre nuestros servicios.</p>
@endsection

En este ejemplo, la vista hija home.blade.php extiende el layout app.blade.php y define las secciones titulo y contenido. La directiva @section('titulo', 'Página de inicio') asigna directamente el valor de la sección, mientras que @section('contenido') permite incluir múltiples líneas de contenido hasta @endsection.

Es posible definir tantas secciones como se requieran en el layout y en las vistas hijas. Además, se pueden establecer valores por defecto en las secciones utilizando la sintaxis de @yield:

<title>@yield('titulo', 'Mi Aplicación Laravel')</title>

Si la vista hija no define la sección titulo, se utilizará el valor por defecto 'Mi Aplicación Laravel'.

Para organizar mejor el contenido, las secciones pueden anidarse y combinarse con otros componentes de Blade. Es común incluir archivos parciales utilizando @include dentro de las secciones para mantener el código modular.

También es posible utilizar la directiva @section de forma abreviada cuando solo se necesita definir un valor simple:

@section('titulo', 'Contacto')

Si se requiere pasar parámetros al layout desde la vista hija, se pueden compartir variables. Por ejemplo, para establecer una variable $claseBody en el layout:

<body class="@yield('claseBody')">

Y en la vista hija:

@section('claseBody', 'pagina-inicio')

De este modo, se pueden personalizar atributos del layout desde las vistas que lo extienden.

Además de @yield y @section, Blade proporciona la directiva @show, que finaliza la sección y la muestra inmediatamente en el lugar donde se define. Sin embargo, su uso es menos común en favor de @section y @endsection.

Las subsecciones son otra característica útil cuando se trabaja con layouts complejos. Permiten definir secciones dentro de otras secciones. Por ejemplo:

En el layout:

<div class="sidebar">
    @yield('sidebar')
</div>

En una vista intermedia:

@section('sidebar')
    @parent
    <p>Contenido adicional de la barra lateral.</p>
@endsection

La directiva @parent incluye el contenido de la sección original definida en el layout, permitiendo agregar más contenido sin reemplazar el existente.

Es importante mantener las vistas organizadas y los layouts limpios para optimizar el mantenimiento de la aplicación. La separación clara entre la estructura común y el contenido específico de cada vista facilita la colaboración y la escalabilidad del proyecto.

Es recomendable aprovechar las características de Blade para minimizar la repetición de código y seguir los principios de diseño DRY (Don't Repeat Yourself). Los layouts y secciones en Laravel son herramientas esenciales para lograr una arquitectura de vistas bien estructurada y sostenible.

Incluyendo y extendiendo vistas

En Laravel, la modularización de vistas es fundamental para mantener el código organizado y reutilizable. Esto se logra mediante la inclusión y extensión de vistas utilizando las directivas que el motor de plantillas Blade proporciona. Estas herramientas permiten componer interfaces complejas a partir de piezas más pequeñas y manejables.

Incluir vistas con @include

La directiva @include es esencial para insertar una vista dentro de otra. Esto es útil para crear componentes reutilizables como encabezados, pies de página o barras de navegación. La sintaxis básica es:

@include('ruta.de.la.vista')

Por ejemplo, para incluir una barra de navegación ubicada en resources/views/partials/nav.blade.php, se utiliza:

@include('partials.nav')

Es importante destacar que la ruta proporcionada en @include es relativa al directorio resources/views y no se incluye la extensión .blade.php.

Pasar datos a vistas incluidas

En ocasiones, es necesario pasar variables a las vistas que se están incluyendo. Esto se logra pasando un array asociativo como segundo argumento de @include:

@include('partials.alerta', ['tipo' => 'error', 'mensaje' => 'Acceso denegado'])

En la vista alerta.blade.php, se pueden utilizar las variables $tipo y $mensaje directamente:

<div class="alert alert-{{ $tipo }}">
    {{ $mensaje }}
</div>

Este mecanismo facilita la personalización de vistas parciales según el contexto en el que se incluyen.

Inclusión condicional de vistas

Blade proporciona varias directivas para incluir vistas de forma condicional:

  • @includeIf: Incluye la vista solo si existe.
@includeIf('partials.contacto')
  • @includeWhen: Incluye la vista si una condición es verdadera.
@includeWhen($usuario->esAdmin(), 'admin.panel')
  • @includeUnless: Incluye la vista a menos que una condición sea verdadera.
@includeUnless($usuario->activo, 'partials.activar-cuenta')
  • @includeFirst: Incluye la primera vista que exista en una lista de vistas.
@includeFirst(['custom.lista', 'defaults.lista'], ['elementos' => $elementos])

Estas directivas aumentan la flexibilidad y permiten manejar situaciones en las que una vista puede no estar disponible o solo debe mostrarse bajo ciertas condiciones.

Extender vistas con @extends

La directiva @extends permite que una vista herede de otra, especificando un layout base. Esto ya se ha utilizado para trabajar con layouts y secciones, pero también es posible extender vistas para crear variaciones de una plantilla existente.

Por ejemplo, se podría tener una vista producto.blade.php que extiende de layouts.app y define secciones específicas:

@extends('layouts.app')

@section('titulo', 'Detalle del Producto')

@section('contenido')
    @include('productos.detalle', ['producto' => $producto])
@endsection

En este caso, se combina @extends con @include para estructurar la vista de forma modular y ordenada.

Iteración de vistas con @each

La directiva @each es útil para iterar sobre una colección y renderear una vista para cada elemento. Su sintaxis es:

@each('vista.elemento', $coleccion, 'variable', 'vista.vacia')
  • ‘vista.elemento’: La vista que se usará para cada elemento.
  • $coleccion: La colección de elementos a iterar.
  • ‘variable’: El nombre de la variable que representará cada elemento en la vista.
  • ‘vista.vacia’: (Opcional) La vista que se usará si la colección está vacía.

Por ejemplo:

@each('partials.item', $items, 'item', 'partials.sin-items')

En la vista partials.item, se puede acceder a $item:

<li>{{ $item->nombre }}</li>

Si $items está vacío, se incluirá la vista partials.sin-items que podría contener un mensaje como:

<p>No hay elementos disponibles.</p>

Esta directiva simplifica el código y mejora la legibilidad al manejar listas de elementos.

Pilas de contenido con @push y @stack

Las directivas @push y @stack permiten agregar contenido a una pila identificada por un nombre, facilitando la inyección de scripts o estilos adicionales desde las vistas hijas hacia el layout principal.

En el layout, se define la ubicación de la pila:

<head>
    <title>@yield('titulo')</title>
    @stack('estilos')
</head>

En las vistas hijas, se puede empujar contenido a esta pila:

@push('estilos')
    <link rel="stylesheet" href="{{ asset('css/pagina-especifica.css') }}">
@endpush

Al renderizar la vista, el contenido de la pila estilos se insertará en el lugar indicado por @stack('estilos').

Esto es especialmente útil para agregar scripts al final del body:

<body>
    @yield('contenido')

    @stack('scripts')
</body>

Y en la vista hija:

@push('scripts')
    <script src="{{ asset('js/pagina-especifica.js') }}"></script>
@endpush

El uso de pilas de contenido mejora la organización y permite que cada vista administre sus propias dependencias sin modificar el layout.

Componentes anónimos y de clase

Además de los componentes regulares, Blade soporta componentes anónimos y componentes de clase, que proporcionan una forma más estructurada de crear componentes reutilizables.

Componentes anónimos

Los componentes anónimos se ubican en resources/views/components y se nombran con la extensión .blade.php. Por ejemplo, un componente alerta.blade.php:

<div class="alert alert-{{ $tipo }}">
    {{ $mensaje }}
</div>

Se pueden utilizar en las vistas de la siguiente manera:

<x-alerta :tipo="$tipo" :mensaje="$mensaje" />

Los atributos precedidos por : indican que se está pasando una variable en lugar de una cadena literal.

Componentes de clase

Los componentes de clase permiten mayor lógica y se definen mediante clases PHP ubicadas en app/View/Components. Por ejemplo, una clase de componente Mensaje.php:

namespace App\View\Components;

use Illuminate\View\Component;

class Mensaje extends Component
{
    public $usuario;

    public function __construct($usuario)
    {
        $this->usuario = $usuario;
    }

    public function render()
    {
        return view('components.mensaje');
    }
}

Y su vista correspondiente mensaje.blade.php:

<p>Hola, {{ $usuario }}. Tienes un nuevo mensaje.</p>

Se utiliza en las vistas con:

<x-mensaje :usuario="$nombreUsuario" />

Los componentes de clase permiten encapsular comportamiento y lógica de presentación, mejorando la modularidad.

Slots en componentes

Los slots permiten definir áreas de contenido dinámico dentro de un componente. El slot por defecto se accede mediante {{ $slot }}, pero es posible definir slots nombrados.

Por ejemplo, un componente tarjeta.blade.php:

<div class="tarjeta">
    <div class="tarjeta-header">
        {{ $titulo }}
    </div>
    <div class="tarjeta-body">
        {{ $slot }}
    </div>
    <div class="tarjeta-footer">
        {{ $footer }}
    </div>
</div>

Se utiliza asignando contenido a los slots:

<x-tarjeta>
    <x-slot name="titulo">
        Título de la Tarjeta
    </x-slot>

    Contenido principal de la tarjeta.

    <x-slot name="footer">
        Pie de la Tarjeta
    </x-slot>
</x-tarjeta>

Este enfoque permite crear componentes altamente personalizables y reutilizables.

Alias de componentes

Para facilitar el uso de componentes, es posible registrar alias en el archivo AppServiceProvider.php:

public function boot()
{
    Blade::component('components.alerta', 'alerta');
}

Ahora, el componente alerta se puede utilizar directamente:

<x-alerta tipo="warning" mensaje="Acción no permitida" />

Herencia múltiple con @component

La directiva @component permite anidar componentes y pasar contenido entre ellos. Se utiliza definiendo un componente y pasando un bloque de contenido:

@component('components.layout')
    @component('components.card')
        @slot('title')
            Título de la Tarjeta
        @endslot

        Contenido de la tarjeta.

    @endcomponent
@endcomponent

Este método es más verboso pero ofrece mayor control en situaciones complejas.

Uso avanzado de @include

Además de pasar variables individuales, se puede pasar todo el contexto de la vista actual a la vista incluida utilizando with:

@include('partials.detalles', $datos->toArray())

O utilizando el método with después de @include:

@include('partials.detalles')->with('extra', $valorExtra)

Esto permite compartir más información con las vistas incluidas y mantenerlas sincronizadas con el estado actual.

Es recomendable mantener las vistas limpias y evitar la lógica compleja en ellas. Utilizar los mecanismos de Blade para incluir y extender vistas contribuye a un código más mantenible y facilita la colaboración entre desarrolladores.

Al modularizar las vistas y aprovechar las herramientas que Laravel ofrece, se mejora la escalabilidad de la aplicación y se promueve la adherencia a buenas prácticas de desarrollo.

Para seguir leyendo hazte Plus

¿Ya eres Plus? Accede a la app

Plan mensual

19.00 € /mes

Precio normal mensual: 19 €
47 % DE DESCUENTO

Plan anual

10.00 € /mes

Ahorras 108 € al año
Precio normal anual: 120 €
Aprende Laravel GRATIS online

Todas las lecciones de Laravel

Accede a todas las lecciones de Laravel y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Laravel y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la sintaxis básica y directivas de Blade.
  • Crear vistas dinámicas con herencia de plantillas.
  • Implementar componentes reutilizables.
  • Utilizar directivas de control de flujo y bucles.
  • Optimizar la inserción de lógica en las vistas.