3-. Plantillas de Blade con Laravel 11

Conceptos clave

  • @extends : La vista hija dice "yo voy a usar un layout padre"

  • @section : Define un bloque de contenido (como un hueco o sección)

  • @yield : En el layout padre, muestra el contenido que la vista hija ponga en esa sección

  • @show : Muestra la sección (similar a @yield pero usada en el layout)

Con @show (tu código original):

blade
@section('sidebar')
    Este es mi master sidebar.
@show

Resultado si la hija NO define 'sidebar': Muestra "Este es mi master sidebar."

Sin @show (usando @yield):

blade
@yield('sidebar')

Tu ejemplo (layout padre)

blade
<!-- resources/views/layouts/master.blade.php -->
<html>
    <head>
        <title>@yield('title', 'Título por defecto')</title>
    </head>
    <body>
        @section('sidebar')
            Este es mi master sidebar.
        @show

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

Ejemplo aún más pequeño (3 líneas)

Layout padre (layout.blade.php):

blade
<html>
    <body>
        @yield('contenido')
    </body>
</html>

Vista hija (home.blade.php):

blade
@extends('layout')

@section('contenido')
    <h1>Hola Mundo!</h1>
@endsection

Resultado final:

html
<html>
    <body>
        <h1>Hola Mundo!</h1>
    </body>
</html>

Ejemplo práctico con tu código

Layout padre - layouts/app.blade.php:

blade
<html>
    <head>
        <title>Mi App - @yield('title')</title>
    </head>
    <body>
        <nav>Menú principal</nav>
        
        @section('sidebar')
            <aside>Sidebar por defecto</aside>
        @show

        <main>
            @yield('content')
        </main>
        
        <footer>© 2026</footer>
    </body>
</html>

Vista hija - productos/index.blade.php:

blade
@extends('layouts.app')

@section('title', 'Lista de productos')

@section('sidebar')
    <aside>
        <h3>Filtros</h3>
        <ul>
            <li>Electrónica</li>
            <li>Ropa</li>
        </ul>
    </aside>
@endsection

@section('content')
    <h1>Productos</h1>
    <ul>
        <li>Laptop - $1000</li>
        <li>Mouse - $20</li>
    </ul>
@endsection

Resultado final renderizado:

html
<html>
    <head>
        <title>Mi App - Lista de productos</title>
    </head>
    <body>
        <nav>Menú principal</nav>
        
        <aside>
            <h3>Filtros</h3>
            <ul>
                <li>Electrónica</li>
                <li>Ropa</li>
            </ul>
        </aside>

        <main>
            <h1>Productos</h1>
            <ul>
                <li>Laptop - $1000</li>
                <li>Mouse - $20</li>
            </ul>
        </main>
        
        <footer>© 2026</footer>
    </body>
</html>

Diferencia clave

blade
<!-- En el LAYOUT -->
@section('sidebar')      <!-- Define la sección -->
    Contenido por defecto
@show                     <!-- La muestra inmediatamente -->

<!-- En el LAYOUT también puedes usar -->
@yield('sidebar')         <!-- Solo muestra lo que la vista hija ponga -->

Regla de oro

  • @yield : Usa en layout cuando solo quieras mostrar contenido de la vista hija

  • @section + @show : Usa en layout cuando quieras un contenido por defecto que la hija pueda sobrescribir

En el LAYOUTSi la hija DEFINE la secciónSi la hija NO define la sección
@yield('contenido')Muestra lo de la hijaMuestra VACÍO
@section('contenido')...@showMuestra lo de la hijaMuestra el CONTENIDO POR DEFECTO

Convenciones de Nomenclatura en Laravel

Aquí te explico las convenciones más comunes para nombrar elementos en Laravel, con ejemplos claros:

1. Modelos

  • Singular y en PascalCase (primera letra mayúscula)

  • Corresponden a una tabla en la base de datos

  • Ejemplo: UserPostProductCategory

php
// app/Models/User.php
class User extends Model
{
    // ...
}

2. Tablas de Base de Datos

  • Plural y en snake_case (minúsculas con guiones bajos)

  • Corresponden al modelo en singular

  • Ejemplo: userspostsproduct_categories

php
// En una migración
Schema::create('users', function (Blueprint $table) {
    $table->id();
    // ...
});

3. Controladores

  • Singular con sufijo Controller y en PascalCase

  • Para recursos, puedes usar NombreResourceController

  • Ejemplo: UserControllerPostControllerProductCategoryController

php
// app/Http/Controllers/UserController.php
class UserController extends Controller
{
    // ...
}

4. Variables en General

  • camelCase (primera letra minúscula, palabras siguientes con mayúscula inicial)

  • Ejemplo: $userName$totalAmount$isActive

5. Variables de Modelo (una instancia)

  • Singular y en camelCase

  • Representa una sola entidad/registro

  • Ejemplo: $user$post$productCategory

php
$user = User::find(1); // Una sola instancia de User

6. Variables de Modelo (múltiples instancias)

  • Plural y en camelCase

  • Representa una colección de entidades/registros

  • Ejemplo: $users$posts$productCategories

php
$users = User::all(); // Colección de usuarios

7. Variables en Vistas (pasadas desde controlador)

  • Mismas convenciones que las variables generales

  • Normalmente se pasa una colección para listados y una instancia para detalles

php
// En controlador
return view('users.index', ['users' => User::all()]);
return view('users.show', ['user' => User::find(1)]);

Ejemplo Completo

Modelo y Tabla:

php
// app/Models/Product.php
class Product extends Model
{
    // ...
}

// Migración
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('product_name');
    // ...
});

Controlador:

php
// app/Http/Controllers/ProductController.php
class ProductController extends Controller
{
    public function index()
    {
        $products = Product::all(); // Colección
        return view('products.index', compact('products'));
    }

    public function show(Product $product) // Instancia única
    {
        $relatedProducts = $product->related()->get(); // Otra colección
        return view('products.show', compact('product', 'relatedProducts'));
    }
}

Vista:

php
// resources/views/products/index.blade.php
@foreach($products as $product)
    <p>{{ $product->product_name }}</p>
@endforeach

// resources/views/products/show.blade.php
<h1>{{ $product->product_name }}</h1>
@foreach($relatedProducts as $relatedProduct)
    <p>{{ $relatedProduct->product_name }}</p>
@endforeach

Plantillas de Blade con Laravel 11

Si alguna vez has utilizado Vue.js o ReactJS, estarás familiarizado con el concepto de componentes. En Laravel también contamos con componentes de Blade y los vamos a utilizar para crear nuestro layout y extraer este contenido repetido.

Creando componentes de Blade

Los componentes de Blade se ubican en la carpeta resources/views/components. Aquí tenemos varios archivos que se generaron automáticamente al elegir Laravel Breeze (hablaremos de esto más adelante).

Vamos a crear un componente llamado layout.blade.php. Actualmente, lo único que cambia en nuestras vistas es el <h1>, así que:

  1. Copiamos la parte superior de la vista (head, meta tags, etc.) y la pegamos en el layout

  2. Copiamos el cierre (footer, scripts, etc.) y lo pegamos al final del layout

Dentro de todo componente de Blade tenemos disponible una variable reservada especial llamada $slot donde se imprimirá el contenido variable. Es similar a los slots en VueJS o a children en React.

Usando el componente Layout

Para utilizar nuestro componente en la vista welcome.blade.php:

  1. Dejamos solo el <h1> en la vista

  2. Tenemos dos opciones para usar el componente:

Opción 1: Directiva @component

blade
@component('components.layout')
    <!-- Contenido que irá en el $slot -->
@endcomponent

Opción 2: Etiqueta de componente (recomendada)

blade
<x-layout>
    <!-- Contenido que irá en el $slot -->
</x-layout>

La segunda opción es más limpia y asume automáticamente que el componente está en la carpeta components.

Slots con nombre para contenido opcional

Si queremos agregar un sidebar opcional:

  1. En el layout:

blade
@isset($sidebar)
    <div id="sidebar">{{ $sidebar }}</div>
@endisset

<!-- Alternativa más corta: -->
@isset($sidebar)
    {{ $sidebar }}
@endisset
  1. En la vista:

blade
<x-layout>
    <x-slot name="sidebar">
        <!-- Contenido del sidebar -->
    </x-slot>
</x-layout>

Propiedades del componente

Para modificar metadatos como título y descripción:

  1. En el layout:

blade
<title>{{ $metaTitle ?? 'Título por defecto' }}</title>
<meta name="description" content="{{ $metaDescription ?? 'Descripción por defecto' }}">
  1. En la vista (como atributos):

blade
<x-layout 
    :meta-title="Título personalizado" 
    :meta-description="Descripción personalizada"
>
    <!-- Nota: usamos kebab-case en atributos pero camelCase en propiedades -->
</x-layout>

Componentes anidados

Si tenemos componentes en subcarpetas:

blade
<x-navigation.main /> <!-- Para components/navigation/main.blade.php -->

Evaluando código PHP en propiedades

Si necesitamos evaluar código PHP en las propiedades:

blade
<x-component :prop=":2 + 2" /> <!-- Evaluará a 4 -->
<x-component prop="2 + 2" />   <!-- Mostrará el string "2 + 2" -->

Conclusión

Con estos cambios, podemos actualizar todas nuestras vistas para usar el layout consistente. Los componentes de Blade nos permiten:

  • Reducir código repetido

  • Crear plantillas reutilizables

  • Mantener una estructura limpia y organizada

  • Trabajar con lógica opcional (slots)

Comentarios

Entradas más populares de este blog

8-Creación de una API RESTful con Laravel

02 -Rutas en Laravel

3-Rutas