- Blade compila plantillas .blade.php a PHP puro y ofrece directivas limpias para condicionales, bucles, layouts y componentes.
- Los stacks de Blade (@stack, @push, @prepend) permiten centralizar scripts y estilos, delegando en las vistas hijas lo que se apila.
- Directivas de entorno, autorización, sesión y validación integran las vistas con el resto del framework de forma segura y expresiva.
- Las directivas personalizadas y helpers como Js::from abren la puerta a patrones avanzados, incluida una directiva tipo hasStack.

Si trabajas con Laravel a diario, tarde o temprano acabas topándote con Blade, sus directivas y, cómo no, con los stacks de vistas y la idea de una hipotética directiva hasStack para gestionarlos mejor. Puede que vengas de usar plantillas clásicas en PHP, o que estés acostumbrado a React o Vue, pero cuando entiendes bien Blade y todo lo que ofrece (stacks incluidos) es cuando tu forma de organizar las vistas da un salto de calidad.
En este artículo vamos a hilar fino: verás de forma muy detallada cómo funciona Blade, qué son las directivas de control, cómo se estructuran layouts, componentes, slots, atributos, autorización, entornos y, dentro de ese contexto, cómo encaja el concepto de stacks y una directiva tipo hasStack para saber si hay contenido apilado antes de renderizarlo. Todo con ejemplos prácticos y con un enfoque realista pensado para proyectos Laravel modernos.
Qué es Blade y por qué es clave entender sus directivas
Blade es el motor de plantillas oficial de Laravel. No te obliga a dejar de usar PHP, pero te regala una sintaxis mucho más limpia para mezclar lógica de presentación y HTML sin estar abriendo y cerrando <?php ?> todo el rato. Cada plantilla .blade.php se compila a PHP puro y se cachea en storage/framework/views, con lo que la sobrecarga en tiempo de ejecución es mínima.
Las vistas Blade se guardan normalmente en resources/views y se devuelven desde rutas o controladores con el helper view(). A este helper le puedes pasar datos en un segundo argumento (array asociativo, compact(), etc.), y en la vista se consumen con la sintaxis de dobles llaves para mostrar contenido escapado o con llaves de exclamación para contenido sin escapar.
Una gran ventaja de Blade es que ofrece directivas específicas (esas palabras que comienzan por @) para manejar condicionales, bucles, autorización, pilas de scripts, componentes, slots, validación, entornos… Todo eso hace que el código de la vista sea mucho más legible y mantenible que una mezcla caótica de PHP clásico con echo y HTML plano.
Sintaxis básica de Blade: eco, escape y verbatim
La operación más típica en una vista es mostrar datos. Con Blade, para imprimir el contenido de una variable basta con usar {{ }}, lo que internamente se traduce en un echo e($variable) y, por tanto, escapa entidades HTML para evitar XSS:
Mostrar variables escapadas es tan simple como:
{{ $name }}
Si quieres mostrar HTML ya generado o contenido que no debe escaparse (por ejemplo porque lo controlas tú y sabes que es seguro), puedes recurrir a la sintaxis {!! !!}, que desactiva el escapado automático y deja que el navegador lo interprete tal cual:
{!! $htmlSeguro !!}
Si trabajas con frameworks frontend que también usan llaves (por ejemplo, Vue o alguna librería de templating en el cliente), Blade te deja “escapar” su propio motor con el prefijo @. De este modo, @{{ variableJavascript }} no se interpretará como una expresión Blade, sino que quedará en el HTML para ser procesada por el framework del navegador.
Cuando tienes grandes bloques donde necesitas respetar íntegramente las dobles llaves sin que Blade las toque, puedes rodearlos con la directiva @verbatim … @endverbatim. Todo lo que haya dentro se dejará intacto, una ayuda muy útil al integrar plantillas de frontend complejas.
Estructuras de control: if, switch, bucles y la variable $loop
Blade ofrece un juego completo de directivas de control de flujo que envuelven la sintaxis de PHP pero de manera más legible y consistente. En la práctica, la lógica es casi idéntica, pero ganas claridad y evitas abusar de tags PHP en medio del HTML.
Las sentencias if se escriben con @if, @elseif, @else y se cierran con @endif. También tienes atajos como @unless (negación de una condición), @isset para verificar que una variable está definida y @empty para chequear si está vacía.
Para escenarios con múltiples posibles valores, la directiva @switch replica la estructura del switch de PHP con @case, @break, @default y cierre con @endswitch, facilitando condicionales múltiples de lectura clara.
En cuanto a bucles, tienes @for, @foreach y @while, además de @forelse, muy útil cuando quieres iterar una colección pero también necesitas manejar el caso de lista vacía sin escribir un if adicional. Con @forelse ... @empty ... @endforelse puedes renderizar contenido alternativo si no hay elementos.
Mientras recorres un @foreach, Blade pone a tu disposición la variable $loop, un objeto que contiene información muy útil de la iteración actual: índice, si es la primera o la última vuelta, si el índice es par o impar, cuántas iteraciones totales hay o incluso acceso al bucle padre en caso de bucles anidados mediante $loop->parent.
Herencia de plantillas, layouts y secciones
En aplicaciones reales no quieres repetir cabeceras, menús o pies de página en cada vista. Blade permite definir un layout maestro (lo típico es guardarlo en resources/views/layouts/master.blade.php) que todas las páginas heredan. Dentro del layout defines zonas “huecas” con @yield y el resto del HTML común se mantiene estable.
Para usar ese layout desde una vista hija solo tienes que indicar @extends(‘layouts.master’) y declarar las secciones que quieras rellenar usando @section y @endsection. Cada @yield('nombre') del master se corresponderá con un @section('nombre') en la vista hija.
Además, la directiva @parent te permite no solo sobrescribir una sección, sino añadir contenido por encima o por debajo de lo que define el layout. Esto es muy útil en barras laterales o bloques que quieres extender, no reemplazar.
Si necesitas incluir fragmentos de HTML reusables sin herencia completa, Blade proporciona @include y toda una familia de directivas relacionadas: @includeIf, @includeWhen, @includeUnless y @includeFirst, que te permiten incluir sub-vistas de forma condicional o elegir la primera que exista en una lista de posibles rutas.
Para casos donde repites un pequeño fragmento por cada elemento de una colección, la directiva @each combina foreach + include en una sola línea, pudiendo incluso definir una vista alternativa para el caso en el que la colección llegue vacía.
Componentes de Blade, slots y atributos
Los componentes Blade son la evolución natural de layouts e includes: te permiten encapsular piezas de interfaz reutilizables (botones, alerts, tarjetas, formularios…) con lógica propia, propiedades y slots con contenido inyectable desde fuera, todo con una sintaxis muy cercana a los componentes de frameworks JS modernos.
Hay dos grandes tipos de componentes: los basados en clase (ubicados en app/View/Components, generados con php artisan make:component) y los anónimos, que son solo vistas en resources/views/components sin clase asociada. En ambos casos se renderizan en las vistas con etiquetas del tipo <x-alert /> o <x-forms.input />.
Los componentes basados en clase reciben datos a través de atributos HTML (con kebab-case en la vista y camelCase en el constructor), se exponen en la vista del componente como propiedades públicas y pueden optar por un método shouldRender() para decidir condicionalmente si se deben mostrar.
Para contenido flexible, los componentes cuentan con slots. El contenido principal se accede como $slot en la plantilla del componente, y los slots con nombre se definen usando <x-slot name="titulo">...</x-slot> al usar el componente. Desde dentro puedes llamar a métodos del componente a través de $component y hasta comprobar si un slot está vacío con $slot->isEmpty() o si tiene contenido real con $slot->hasActualContent().
Los componentes también gestionan de forma elegante los atributos adicionales que no casan con propiedades del constructor (por ejemplo class, id, data-*). Todo eso se agrupa en un “attribute bag” accesible con $attributes, que puedes renderizar tal cual o manipular con métodos como merge(), class(), prepend(), filter(), whereStartsWith(), has() o get().
Además, Blade incluye directivas específicas para HTML típico de formularios: @checked, @selected, @disabled, @readonly y @required, que imprimen el atributo correspondiente solo si la condición que reciben se evalúa como verdadera.
Layouts usando componentes y herencia clásica
En Laravel moderno, cada vez es más habitual definir el layout global de la app como un componente Blade (por ejemplo, <x-layout>) en lugar de usar solo la herencia clásica de @extends. De este modo, el layout puede recibir slots, atributos y propiedades igual que el resto de componentes.
El patrón típico consiste en crear un componente Layout con php artisan make:component Layout, definir en su plantilla la estructura HTML base (cabecera, enlaces CSS, nav, footer) y usar {{ $slot }} para inyectar el contenido principal. Opcionalmente, se define un slot nombrado title para que cada página especifique su título de forma declarativa.
Por otro lado, sigue existiendo la opción “clásica” con herencia de plantillas vía @extends, @section y @yield, muy usada antes de la popularización de los componentes. Puedes seguir mezclando ambos enfoques, usar layouts basados en componentes para todo, o quedarte con la herencia tradicional si tu proyecto ya está montado así.
En ambos casos, el objetivo es el mismo: no repetir el esqueleto de HTML en cada vista, mantener un único punto de verdad para el layout y permitir que cada página solo se preocupe de su contenido específico.
Sesión, autenticación, entorno y autorización en Blade
Blade amarra muy bien con el resto del framework, así que no se limita a pintar HTML: también te da directivas de alto nivel para interactuar con la sesión, el sistema de autenticación, el entorno de la app y las reglas de autorización.
Para la parte de autenticación existen directivas como @auth y @guest, que muestran su contenido solo si hay un usuario autenticado o si es un invitado, respectivamente. Además, puedes especificar un guard concreto como argumento para afinar el contexto de autenticación que se usa.
Las directivas de entorno como @production o @env('local') permiten condicionar secciones de la vista dependiendo del environment actual de Laravel. Muy útil, por ejemplo, para mostrar banners, trazas de debug o scripts solo en local o staging.
En cuanto a sesión, la directiva @session facilita comprobar si existe una clave en sesión y, si existe, ofrece su valor a través de la variable $value. Esto resuelve de forma elegante el clásico caso de mensajes flash o avisos.
Para la autorización al estilo policies y gates, Blade proporciona @can, @cannot y @canany. Con ellas puedes mostrar u ocultar botones, enlaces o bloques completos según si el usuario tiene permiso para una acción concreta sobre un modelo o clase. Combinadas con @guest o @auth, permiten construir interfaces mucho más seguras y claras.
Formularios, validación y tratamiento de errores en las vistas
Cuando pasas de las vistas estáticas a los formularios es donde se ve lo cómodo que es Blade. Laravel exige incluir un token CSRF en todos los formularios que modifican datos, y para no tener que escribir manualmente el campo oculto existe la directiva @csrf, que genera el input con el token correspondiente.
Los métodos HTTP como PUT, PATCH o DELETE se simulan a través de un campo oculto _method, y Blade pone a tu disposición @method(‘PUT’) (o PATCH/DELETE) para generarlo automáticamente dentro del formulario.
Para mostrar errores de validación existe la directiva @error, que se asocia a un campo concreto. Dentro, tienes disponible la variable $message con el texto de error. Al ser en realidad un if compilado, puedes usar @else para mostrar contenido alternativo cuando no hay error.
El objeto $errors está siempre presente en las vistas y agrupa todos los mensajes de validación de la request actual. Se integra perfectamente con el helper old(), que te permite “repopular” el formulario con los valores enviados por el usuario tras un fallo de validación, manteniendo las entradas y mostrando los errores de forma clara.
Al combinar estas directivas con las reglas de validación en controladores o Form Requests, tienes un flujo de validación en servidor sólido, complementario a la validación en cliente, y mucho más seguro frente a manipulaciones malintencionadas.
Stacks en Blade: @stack, @push, @prepend y el concepto de hasStack
Una de las funcionalidades menos comentadas pero más útiles de Blade para proyectos grandes son los stacks. Un stack es, básicamente, una pila de fragmentos de vista a los que puedes ir añadiendo contenido desde vistas hijas, componentes o includes, para luego renderizarlo todo junto en un punto concreto del layout maestro.
La directiva @stack(‘nombre’) marca el lugar donde se van a volcar todos los fragmentos asociados a ese stack. En cambio, desde cualquier otra vista puedes usar @push(‘nombre’) para enviar contenido al final de la pila o @prepend(‘nombre’) para colocarlo al principio. Esto se usa muchísimo para scripts y estilos específicos de página.
Imagina, por ejemplo, que en tu layout tienes algo así en el <head> y al final del <body>:
@stack('styles')
...
@stack('scripts')
Luego, en una vista concreta que necesita un JS adicional, podrías hacer:
@push('scripts')
<script src="/js/pagina-especifica.js"></script>
@endpush
Esto permite que el layout no tenga que conocer cada script o estilo de cada página; solo define los stacks y son las vistas hijas las que van apilando lo que necesitan. También existe @pushIf para empujar contenido según una condición booleana sin tener que escribir el if completo.
Dentro de este contexto, muchos desarrolladores echan de menos una directiva tipo @hasStack o similar que permitiera comprobar si un determinado stack tiene contenido antes de renderizarlo. Aunque Blade de fábrica no trae una directiva con ese nombre, la idea es clara: poder hacer algo como “si el stack de scripts está vacío, no imprimir etiquetas adicionales” o “si hay elementos en un stack de metadatos, envolverlos en un bloque concreto”.
La forma de conseguir un comportamiento equivalente hoy en día es complementar las directivas de stacks con lógica en el layout o con helpers personalizados, o incluso con directivas propias registradas vía Blade::directive(). De esta manera se puede simular una directiva hasStack que consulte internamente la pila antes de decidir qué HTML generar.
JSON, JavaScript y directivas auxiliares en Blade
En muchas vistas de Laravel necesitas pasar datos desde el backend a JavaScript. Lo típico es hacer un json_encode() de un array o colección y dejarlo dentro de un script inline, pero eso no siempre es seguro ni cómodo. Laravel facilita este trabajo con el helper Js::from(), que serializa y escapa correctamente valores PHP a JSON para incrustarlos en HTML.
Cuando rendersas datos complejos hacia el navegador, Js::from() evita problemas de comillas o caracteres especiales y devuelve una expresión JSON.parse() segura para la inclusión en atributos o scripts. No se recomienda pasar expresiones complejas dentro de la directiva porque internamente Blade usa regex al compilarlas, y la cosa puede romperse de formas poco evidentes.
Además, Blade permite definir comentarios de plantilla que no se envían al HTML final (a diferencia de los comentarios HTML clásicos) y bloques @php … @endphp donde ejecutar pequeños trozos de PHP puro cuando de verdad no queda más remedio. Incluso puedes usar @use para importar clases dentro de la vista o asignarles alias, algo cómodo cuando trabajas con helpers o componentes muy específicos.
Si llegas al punto de necesitar una funcionalidad de eco muy especializada para determinados objetos, puedes registrar manejadores de eco personalizados con Blade::stringable(), de forma que al hacer eco de un objeto concreto Blade llame a tu callback en vez de al método mágico __toString() de la clase.
Vistas de error, fragmentos y directivas personalizadas
Laravel te deja personalizar de forma muy sencilla las vistas de error: basta con crear archivos en resources/views/errors con el código HTTP como nombre (por ejemplo, 404.blade.php o 500.blade.php). Cada vez que se produzca ese error, se usará tu plantilla en lugar de la genérica del framework.
Para casos en los que trabajas con herramientas como Turbo o htmx y solo quieres devolver fragmentos concretos de una vista, Blade ofrece las directivas @fragment … @endfragment combinadas con métodos como view('...')->fragment('nombre'), fragmentIf(), fragments() y fragmentsIf(). De esta forma puedes reutilizar la misma plantilla completa y extraer solo las partes que necesitas según el contexto.
Si el repertorio de directivas no te basta, siempre puedes crear las tuyas con Blade::directive(). Lo habitual es registrarlas en el método boot() de AppServiceProvider o en un proveedor dedicado. El compilador de Blade te pasará como string la expresión que haya dentro de la directiva y tú devuelves el PHP que quieras que genere al compilarse.
Para condiciones personalizadas sencillas existe también Blade::if(), que crea directivas condicionales en una sola línea. Por ejemplo, podrías definir @disk('s3') para comprobar si el disco por defecto de la app es S3, y usarla luego en cualquier vista como si fuera una directiva nativa.
Con este arsenal puedes llegar a montar un lenguaje de plantillas prácticamente a tu medida, incluyendo una directiva tipo hasStack si quieres, que haga de azúcar sintáctico sobre la lógica que consulte internamente si una pila tiene contenido o no antes de imprimirla.
Dominar Blade en profundidad —desde la sintaxis básica hasta los componentes avanzados, las directivas de autorización, validación, entornos y sobre todo el manejo de stacks— te permite construir vistas modulares, seguras, consistentes y fáciles de mantener, donde una futura directiva como hasStack encajaría de forma natural para redondear aún más el control sobre lo que se inyecta en cada zona de tu layout.
Tabla de Contenidos
- Qué es Blade y por qué es clave entender sus directivas
- Sintaxis básica de Blade: eco, escape y verbatim
- Estructuras de control: if, switch, bucles y la variable $loop
- Herencia de plantillas, layouts y secciones
- Componentes de Blade, slots y atributos
- Layouts usando componentes y herencia clásica
- Sesión, autenticación, entorno y autorización en Blade
- Formularios, validación y tratamiento de errores en las vistas
- Stacks en Blade: @stack, @push, @prepend y el concepto de hasStack
- JSON, JavaScript y directivas auxiliares en Blade
- Vistas de error, fragmentos y directivas personalizadas