1- Instalar Laravel
Instalar Laravel
Ejecuta en tu terminal (Linux/macOS) o CMD/PowerShell (Windows):
composer create-project laravel/laravel nombre-del-proyectoReemplaza nombre-del-proyecto con el nombre de tu aplicación.
3. Entrar al directorio del proyecto
cd nombre-del-proyecto4. Configurar el entorno
Copia el archivo
.env.exampley renómbralo a.env:cp .env.example .envGenera la clave de la aplicación:
php artisan key:generateConfigura la base de datos en
.env:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=nombre_basedatos DB_USERNAME=usuario DB_PASSWORD=contraseña
5. Ejecutar migraciones (opcional)
Si necesitas tablas en la base de datos:
php artisan migrate6. Iniciar el servidor de desarrollo
php artisan serveEsto iniciará un servidor en http://localhost:8000.
7. Abrir en el navegador
Visita:
http://localhost:8000Pasos adicionales (opcionales)
Instalar herramientas frontend (Vite, Bootstrap, etc.):
npm install && npm run devCrear autenticación:
composer require laravel/breeze --dev php artisan breeze:install npm install && npm run dev php artisan migratePersonalizar rutas en
routes/web.php.
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:
User,Post,ProductCategory
// 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:
users,posts,product_categories
// En una migración
Schema::create('users', function (Blueprint $table) {
$table->id();
// ...
});3. Controladores
Singular con sufijo
Controllery en PascalCasePara recursos, puedes usar
NombreResourceControllerEjemplo:
UserController,PostController,ProductCategoryController
// 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
$user = User::find(1); // Una sola instancia de User6. Variables de Modelo (múltiples instancias)
Plural y en camelCase
Representa una colección de entidades/registros
Ejemplo:
$users,$posts,$productCategories
$users = User::all(); // Colección de usuariosRutas en Laravel: Explicación y Ejemplos
Las rutas en Laravel son el mecanismo que permite definir cómo responde tu aplicación a las solicitudes HTTP entrantes. Todas las rutas de Laravel se definen en los archivos dentro del directorio routes/.
Tipos básicos de rutas
Usando compact()
El método compact() te permite pasar variables y arrays a las vistas convirtiendo los nombres de variables en un array asociativo.
// En el controlador public function index() { $titulo = "Página de Inicio"; $usuarios = ['Ana', 'Carlos', 'María']; return view('vista', compact('titulo', 'usuarios')); } // En la vista (vista.blade.php) <h1>{{ $titulo }}</h1> <ul> @foreach($usuarios as $usuario) <li>{{ $usuario }}</li> @endforeach </ul>
usando with() en lugar de compact():
// En el controlador public function index() { $titulo = "Página de Inicio"; $usuarios = ['Ana', 'Carlos', 'María']; // Usando with() para pasar cada variable individualmente return view('vista') ->with('titulo', $titulo) ->with('usuarios', $usuarios); } // En la vista (vista.blade.php) - Esto permanece igual <h1>{{ $titulo }}</h1> <ul> @foreach($usuarios as $usuario) <li>{{ $usuario }}</li> @endforeach </ul>
Explicación:
Método
with()encadenado: Pasa cada variable por separado encadenando múltiples llamadas awith()Método
with()con array: Alternativamente puedes pasar todas las variables en un array asociativo (opción comentada)
Pasando un Array desde las Rutas
Puedes pasar datos directamente desde las rutas usando un array como segundo parámetro:
// En routes/web.php Route::get('/ejemplo', function () { return view('ejemplo', [ 'nombre' => 'Ejemplo Ruta', 'valores' => [1, 2, 3, 4, 5] ]); }); // En la vista (ejemplo.blade.php) <h2>{{ $nombre }}</h2> Suma de valores: {{ array_sum($valores) }}
Combinando métodos
También puedes combinar estos métodos según tus necesidades:
public function show($id) { $usuario = User::find($id); $roles = ['admin', 'editor', 'usuario']; return view('perfil') ->with('usuario', $usuario) ->compact('roles'); }
Todos estos métodos son equivalentes en funcionalidad, la elección depende de tus preferencias de estilo de código.
Aquí tienes el ejemplo modificado definiendo el array fuera y pasando solo el nombre de la variable:
// En routes/web.php Route::get('/ejemplo', function () { $datos = [ 'nombre' => 'Ejemplo Ruta', 'valores' => [1, 2, 3, 4, 5] ]; // Opción 1: Pasar el array completo usando compact return view('ejemplo', compact('datos')); // Opción 2: Pasar el array usando with // return view('ejemplo')->with('datos', $datos); }); // En la vista (ejemplo.blade.php) <h2>{{ $datos['nombre'] }}</h2> Suma de valores: {{ array_sum($datos['valores']) }}
Otra alternativa más limpia sería usar el operador de propagación de PHP:
// En routes/web.php Route::get('/ejemplo', function () { $datos = [ 'nombre' => 'Ejemplo Ruta', 'valores' => [1, 2, 3, 4, 5] ]; return view('ejemplo', [...$datos]); }); // En la vista (ejemplo.blade.php) - Ahora las variables están en el scope directamente <h2>{{ $nombre }}</h2> Suma de valores: {{ array_sum($valores) }}
$datosEjemplo = [
'nombre' => 'Ejemplo Ruta',
'valores' => [1, 2, 3, 4, 5],
];
Route::get('/ejemplo', function () use ($datosEjemplo) { // Usa 'use' para heredar la variable
return view('ejemplo', ['datos' => $datosEjemplo]);
});1. Ejemplo usando with()
// En routes/web.php
$datosEjemplo = [
'nombre' => 'Ejemplo Ruta',
'valores' => [1, 2, 3, 4, 5],
];
Route::get('/ejemplo', function () use ($datosEjemplo) {
// Opción con with() - Pasa los datos individualmente
return view('ejemplo')->with('datos', $datosEjemplo);
});2. Ejemplo usando compact()
// En routes/web.php
$datosEjemplo = [
'nombre' => 'Ejemplo Ruta',
'valores' => [1, 2, 3, 4, 5],
];
Route::get('/ejemplo', function () use ($datosEjemplo) {
// Opción con compact() - Pasa el array automáticamente
return view('ejemplo', compact('datosEjemplo'));
});Nota:
Esta última forma con el operador ... (disponible en PHP 7.4+) es particularmente elegante ya que:
Define el array en una variable
Lo expande al pasarlo a la vista
Permite acceder a las claves del array como variables directas en la vista
Cómo Pasar Datos con Redirect en Laravel
En Laravel, hay varias formas de pasar datos cuando haces un redirect. Aquí te muestro los métodos más comunes:
1. Usando with() para datos de sesión flash
// En tu controlador o ruta return redirect('/ruta-destino')->with('key', 'value');
Ejemplo completo:
public function store(Request $request) { // Lógica de guardado... return redirect('/dashboard') ->with('success', 'Registro creado exitosamente!') ->with('warning', 'Por favor complete su perfil'); }
En la vista destino (usando Blade):
@if(session('success')) <div class="alert alert-success"> {{ session('success') }} </div> @endif @if(session('warning')) <div class="alert alert-warning"> {{ session('warning') }} </div> @endif
2. Pasando un array de datos
return redirect('/ruta-destino')->with([ 'status' => 'success', 'message' => 'Operación completada' ]);
3. Redireccionar con datos en la URL (para datos no sensibles)
return redirect('/ruta-destino?status=success&id=123');
public function store(Request $request)
{
// 1. Validación de datos
// 4. Redirección con mensaje de éxito
return redirect()->route('usuarios.show', $usuario->id)
->with('success', 'Usuario creado exitosamente!');
}
Variaciones Comunes
Redirección a la vista anterior
return back()->with('status', 'Registro creado con éxito');
return back()->with('status', 'Registro creado con éxito');
Redirección con datos flash adicionales
return redirect('dashboard')
->with('success', 'Usuario creado')
->with('stats', [
'total' => User::count(),
'nuevos' => User::whereDate('created_at', today())->count()
]);
return redirect('dashboard') ->with('success', 'Usuario creado') ->with('stats', [ 'total' => User::count(), 'nuevos' => User::whereDate('created_at', today())->count() ]);
Redirección después de almacenar archivos
public function store(Request $request)
{
$path = $request->file('avatar')->store('avatars');
// Guardar el path en la base de datos...
return redirect('perfil')
->with('success', 'Avatar subido correctamente')
->with('avatar_path', $path);
}
public function store(Request $request) { $path = $request->file('avatar')->store('avatars'); // Guardar el path en la base de datos... return redirect('perfil') ->with('success', 'Avatar subido correctamente') ->with('avatar_path', $path); }
Buenas Prácticas
Validación: Siempre valida los datos antes de almacenarlos
Mensajes flash: Proporciona feedback al usuario sobre el resultado
Seguridad: Nunca pases datos sensibles en la URL
Nombres de rutas: Usa rutas con nombre (route()) en lugar de paths directos
Manejo de errores: Usa withErrors() para mostrar errores de validación
Validación: Siempre valida los datos antes de almacenarlos
Mensajes flash: Proporciona feedback al usuario sobre el resultado
Seguridad: Nunca pases datos sensibles en la URL
Nombres de rutas: Usa rutas con nombre (route()) en lugar de paths directos
Manejo de errores: Usa withErrors() para mostrar errores de validación
1. Rutas básicas
Route::get('/saludo', function () {
return '¡Hola Mundo!';
});
Route::get('/saludo', function () {
return '¡Hola Mundo!';
});Cuando se visita /saludo en el navegador, se mostrará "¡Hola Mundo!".
2. Rutas con parámetros
Route::get('/usuario/{id}', function ($id) {
return 'Usuario '.$id;
});
Route::get('/usuario/{id}', function ($id) {
return 'Usuario '.$id;
});Esta ruta capturará el ID de la URL y lo pasará a la función.
3. Rutas con parámetros opcionales
Route::get('/post/{titulo?}', function ($titulo = 'Título por defecto') {
return $titulo;
});
Route::get('/post/{titulo?}', function ($titulo = 'Título por defecto') {
return $titulo;
});El parámetro titulo es opcional y tiene un valor por defecto.
4. Rutas con restricciones
Route::get('/user/{id}', function ($id) {
// Solo se ejecutará si {id} es numérico
})->where('id', '[0-9]+');
Route::get('/user/{id}', function ($id) {
// Solo se ejecutará si {id} es numérico
})->where('id', '[0-9]+');5. Rutas con nombre
Route::get('/perfil', function () {
// ...
})->name('perfil');
Route::get('/perfil', function () {
// ...
})->name('perfil');Aquí te explico las diferentes formas de enviar datos desde un controlador a una vista en Laravel:
1. Usando el método with()
return view('vista')->with('variable', $valor);
// O también:
return view('vista')->with(['key1' => $valor1, 'key2' => $valor2]);
return view('vista')->with('variable', $valor); // O también: return view('vista')->with(['key1' => $valor1, 'key2' => $valor2]);
2. Pasando un array directamente a view()
return view('vista', ['nombre' => $valor]);
// Alternativa:
return view('vista', compact('variable'));
return view('vista', ['nombre' => $valor]); // Alternativa: return view('vista', compact('variable'));
3. Usando la función compact()
$data1 = "valor1";
$data2 = "valor2";
return view('vista', compact('data1', 'data2'));
$data1 = "valor1"; $data2 = "valor2"; return view('vista', compact('data1', 'data2'));
4. Método withVariable() (Magic method)
return view('vista')->withNombre($nombre)->withEdad($edad);
return view('vista')->withNombre($nombre)->withEdad($edad);
5. Usando view()->share() (Para datos globales)
// En un service provider
view()->share('key', 'value');
// En un service provider view()->share('key', 'value');
6. Usando View::make()
return View::make('vista', ['dato' => $valor]);
return View::make('vista', ['dato' => $valor]);
📌 Ejemplo completo:
public function index()
{
$users = User::all();
$title = "Listado de usuarios";
// Puedes usar cualquiera de estas formas:
return view('users.index', compact('users', 'title'));
// ó
return view('users.index')->with(compact('users', 'title'));
// ó
return view('users.index', ['users' => $users, 'title' => $title]);
}
En la vista accedes así:
<h1>{{ $title }}</h1>
@foreach($users as $user)
{{ $user->name }}
@endforeach
public function index() { $users = User::all(); $title = "Listado de usuarios"; // Puedes usar cualquiera de estas formas: return view('users.index', compact('users', 'title')); // ó return view('users.index')->with(compact('users', 'title')); // ó return view('users.index', ['users' => $users, 'title' => $title]); }
<h1>{{ $title }}</h1> @foreach($users as $user) {{ $user->name }} @endforeach
Controladores en Laravel
Los controladores en Laravel son una parte fundamental de la arquitectura MVC (Modelo-Vista-Controlador) y sirven como intermediarios entre las rutas y la lógica de tu aplicación.
Los controladores en Laravel son una parte fundamental de la arquitectura MVC (Modelo-Vista-Controlador) y sirven como intermediarios entre las rutas y la lógica de tu aplicación.
¿Qué son los controladores?
Los controladores son clases PHP que organizan la lógica relacionada con las peticiones HTTP. En lugar de poner toda tu lógica en los archivos de rutas, los controladores te permiten organizarla en clases separadas.
Los controladores son clases PHP que organizan la lógica relacionada con las peticiones HTTP. En lugar de poner toda tu lógica en los archivos de rutas, los controladores te permiten organizarla en clases separadas.
Creación de un controlador
Puedes crear un controlador usando Artisan:
php artisan make:controller NombreControllerEsto creará un archivo en app/Http/Controllers/NombreController.php.
Puedes crear un controlador usando Artisan:
php artisan make:controller NombreControllerEsto creará un archivo en app/Http/Controllers/NombreController.php.
Estructura básica
Un controlador típico se ve así:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
class UserController extends Controller
{
/**
* Mostrar una lista de usuarios.
*/
public function index()
{
$users = User::all();
return view('users.index', ['users' => $users]);
}
/**
* Mostrar el formulario para crear un nuevo usuario.
*/
public function create()
{
return view('users.create');
}
/**
* Almacenar un nuevo usuario en la base de datos.
*/
public function store(Request $request)
{
// Validación y almacenamiento
}
// Otros métodos...
}
Un controlador típico se ve así:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\User;
class UserController extends Controller
{
/**
* Mostrar una lista de usuarios.
*/
public function index()
{
$users = User::all();
return view('users.index', ['users' => $users]);
}
/**
* Mostrar el formulario para crear un nuevo usuario.
*/
public function create()
{
return view('users.create');
}
/**
* Almacenar un nuevo usuario en la base de datos.
*/
public function store(Request $request)
{
// Validación y almacenamiento
}
// Otros métodos...
}Tipos de controladores
Controladores de recursos (Resource Controllers): Manejan todas las operaciones CRUD típicas.
php artisan make:controller PhotoController --resourceEsto genera automáticamente métodos para index, create, store, show, edit, update y destroy.
Controladores de API: Similar a los resource pero sin los métodos create y edit (que son para vistas HTML).
php artisan make:controller API/PhotoController --apiControladores simples: Contienen los métodos que tú defines.
Controladores de recursos (Resource Controllers): Manejan todas las operaciones CRUD típicas.
php artisan make:controller PhotoController --resourceEsto genera automáticamente métodos para index, create, store, show, edit, update y destroy.
Controladores de API: Similar a los resource pero sin los métodos create y edit (que son para vistas HTML).
php artisan make:controller API/PhotoController --apiControladores simples: Contienen los métodos que tú defines.
Uso en rutas
Puedes asignar controladores a rutas:
// Ruta básica
Route::get('/user', [UserController::class, 'index']);
// Resource controller
Route::resource('photos', PhotoController::class);
// API resource controller
Route::apiResource('photos', PhotoController::class);
Puedes asignar controladores a rutas:
// Ruta básica
Route::get('/user', [UserController::class, 'index']);
// Resource controller
Route::resource('photos', PhotoController::class);
// API resource controller
Route::apiResource('photos', PhotoController::class);Inyección de dependencias
Laravel permite la inyección automática de dependencias en los métodos del controlador:
public function store(Request $request)
{
// $request ya está inyectado
$name = $request->input('name');
}
Laravel permite la inyección automática de dependencias en los métodos del controlador:
public function store(Request $request)
{
// $request ya está inyectado
$name = $request->input('name');
}Buenas prácticas
Mantén los controladores delgados (mínima lógica)
Mueve la lógica de negocio a servicios o modelos
Usa la validación de solicitudes (Request Validation)
Sigue las convenciones de nombres (singular para recursos)
Considera usar Form Requests para validaciones complejas
Los controladores son una parte esencial para organizar tu aplicación Laravel de manera limpia y mantenible.
Verificar el contenido de un Request en Laravel
En Laravel hay varias formas de inspeccionar el contenido de un $request. Aquí te muestro diferentes alternativas:
Mantén los controladores delgados (mínima lógica)
Mueve la lógica de negocio a servicios o modelos
Usa la validación de solicitudes (Request Validation)
Sigue las convenciones de nombres (singular para recursos)
Considera usar Form Requests para validaciones complejas
Los controladores son una parte esencial para organizar tu aplicación Laravel de manera limpia y mantenible.
Verificar el contenido de un Request en Laravel
En Laravel hay varias formas de inspeccionar el contenido de un $request. Aquí te muestro diferentes alternativas:
1. Ver todo el contenido del Request
// Muestra todo el contenido y detiene la ejecución (más para desarrollo)
dd($request->all());
// Alternativa que no detiene la ejecución
dump($request->all());
// Ver como array PHP
var_dump($request->all());
// Ver en el log (útil en producción)
\Log::debug($request->all());
// Muestra todo el contenido y detiene la ejecución (más para desarrollo)
dd($request->all());
// Alternativa que no detiene la ejecución
dump($request->all());
// Ver como array PHP
var_dump($request->all());
// Ver en el log (útil en producción)
\Log::debug($request->all());2. Verificar inputs específicos
// Verificar si un campo existe en el request
if ($request->has('nombre_campo')) {
// El campo está presente (puede estar vacío)
}
// Verificar si un campo existe y no está vacío
if ($request->filled('nombre_campo')) {
// El campo está presente y no está vacío
}
// Obtener el valor de un campo específico
$valor = $request->input('nombre_campo');
// Ver un campo específico con dd
dd($request->input('nombre_campo'));
// Ver varios campos específicos
dd($request->only(['campo1', 'campo2']));
// Verificar si un campo existe en el request
if ($request->has('nombre_campo')) {
// El campo está presente (puede estar vacío)
}
// Verificar si un campo existe y no está vacío
if ($request->filled('nombre_campo')) {
// El campo está presente y no está vacío
}
// Obtener el valor de un campo específico
$valor = $request->input('nombre_campo');
// Ver un campo específico con dd
dd($request->input('nombre_campo'));
// Ver varios campos específicos
dd($request->only(['campo1', 'campo2']));3. Ver información adicional del Request
// Ver todos los headers
dd($request->headers->all());
// Ver el método HTTP (GET, POST, etc.)
dd($request->method());
// Ver la URL completa
dd($request->fullUrl());
// Ver los archivos subidos
dd($request->allFiles());
// Ver todos los headers
dd($request->headers->all());
// Ver el método HTTP (GET, POST, etc.)
dd($request->method());
// Ver la URL completa
dd($request->fullUrl());
// Ver los archivos subidos
dd($request->allFiles());4. Alternativas para desarrollo
// Usar el helper ray() si usas la librería spatie/ray
ray($request->all());
// Mostrar en formato JSON (útil para APIs)
return response()->json($request->all());Para desarrollo, dd() o dump() son muy útiles, pero para producción es mejor usar el log (\Log::debug()) o implementar un sistema de monitoreo más robusto.
Características principales de Blade
Sintaxis Limpia
Blade usa directivas (@directiva) que se compilan a código PHP puro, pero son más fáciles de leer y escribir.
Ejemplo:
@if($user->isAdmin())
<p>Eres administrador</p>
@else
<p>Eres usuario normal</p>
@endifHerencia de Layouts
Permite definir plantillas base (layouts) que pueden ser extendidas por otras vistas, evitando repetir código (como headers/footers).
Ejemplo de layout (resources/views/layouts/app.blade.php):
<html>
<head><title>@yield('title')</title></head>
<body>
@section('sidebar') Contenido del sidebar @show
<div class="container">
@yield('content')
</div>
</body>
</html>Extender el layout:
@extends('layouts.app')
@section('title', 'Página de inicio')
@section('content')
<h1>Contenido principal</h1>
@endsection
Inclusión de Subvistas
Usa @include para reutilizar componentes:
@include('shared.header')Mostrar Datos
Escapa automáticamente variables para prevenir XSS:
<p>{{ $user->name }}</p> <!-- Escapado -->
<p>{!! $rawHtml !!}</p> <!-- Sin escapar (usar con cuidado) -->Bucles y Condicionales
Similar a PHP pero más legible:
@foreach($users as $user)
<p>{{ $user->email }}</p>
@endforeach
@for($i = 0; $i < 10; $i++)
{{ $i }}
@endforComponentes y Slots
Ideal para elementos reutilizables (ej. alertas, cards):
<!-- resources/views/components/alert.blade.php -->
<div class="alert alert-{{ $type }}">
{{ $slot }} <!-- Contenido dinámico -->
</div>
<!-- Uso -->
<x-alert type="success">
¡Operación exitosa!
</x-alert>Stacks y Push
Para agregar CSS/JS específicos en layouts:
@push('scripts')
<script src="/js/custom.js"></script>
@endpush
<!-- En el layout -->
@stack('scripts')Directivas Personalizadas
Puedes crear tus propias directivas con Blade::directive():
// En AppServiceProvider::boot()
Blade::directive('datetime', function ($expression) {
return "<?php echo ($expression)->format('d/m/Y H:i'); ?>";
});
<!-- Uso -->
@datetime($post->created_at)
// Usar el helper ray() si usas la librería spatie/ray
ray($request->all());
// Mostrar en formato JSON (útil para APIs)
return response()->json($request->all());Para desarrollo, dd() o dump() son muy útiles, pero para producción es mejor usar el log (\Log::debug()) o implementar un sistema de monitoreo más robusto.
Características principales de Blade
Sintaxis Limpia
Blade usa directivas (@directiva) que se compilan a código PHP puro, pero son más fáciles de leer y escribir.
Ejemplo:@if($user->isAdmin()) <p>Eres administrador</p> @else <p>Eres usuario normal</p> @endifHerencia de Layouts
Permite definir plantillas base (layouts) que pueden ser extendidas por otras vistas, evitando repetir código (como headers/footers).Ejemplo de layout (
resources/views/layouts/app.blade.php):<html> <head><title>@yield('title')</title></head> <body> @section('sidebar') Contenido del sidebar @show <div class="container"> @yield('content') </div> </body> </html>Extender el layout:
@extends('layouts.app') @section('title', 'Página de inicio') @section('content') <h1>Contenido principal</h1> @endsection
Inclusión de Subvistas
Usa@includepara reutilizar componentes:@include('shared.header')Mostrar Datos
Escapa automáticamente variables para prevenir XSS:<p>{{ $user->name }}</p> <!-- Escapado --> <p>{!! $rawHtml !!}</p> <!-- Sin escapar (usar con cuidado) -->Bucles y Condicionales
Similar a PHP pero más legible:@foreach($users as $user) <p>{{ $user->email }}</p> @endforeach @for($i = 0; $i < 10; $i++) {{ $i }} @endforComponentes y Slots
Ideal para elementos reutilizables (ej. alertas, cards):<!-- resources/views/components/alert.blade.php --> <div class="alert alert-{{ $type }}"> {{ $slot }} <!-- Contenido dinámico --> </div> <!-- Uso --> <x-alert type="success"> ¡Operación exitosa! </x-alert>Stacks y Push
Para agregar CSS/JS específicos en layouts:@push('scripts') <script src="/js/custom.js"></script> @endpush <!-- En el layout --> @stack('scripts')Directivas Personalizadas
Puedes crear tus propias directivas conBlade::directive():// En AppServiceProvider::boot() Blade::directive('datetime', function ($expression) { return "<?php echo ($expression)->format('d/m/Y H:i'); ?>"; }); <!-- Uso --> @datetime($post->created_at)
Ventajas de Blade
Seguridad: Escapa variables automáticamente.
Rendimiento: Las vistas son compiladas a código PHP y cacheadas.
Legibilidad: Sintaxis más clara que PHP puro en HTML.
Seguridad: Escapa variables automáticamente.
Rendimiento: Las vistas son compiladas a código PHP y cacheadas.
Legibilidad: Sintaxis más clara que PHP puro en HTML.
Ejemplo Completo
<!-- resources/views/welcome.blade.php -->
@extends('layouts.app')
@section('title', 'Inicio')
@section('content')
<h1>Bienvenido, {{ Auth::user()->name }}</h1>
@include('partials.notification')
<ul>
@foreach($items as $item)
<li>{{ $item->name }}</li>
@endforeach
</ul>
@endsection
<!-- resources/views/welcome.blade.php -->
@extends('layouts.app')
@section('title', 'Inicio')
@section('content')
<h1>Bienvenido, {{ Auth::user()->name }}</h1>
@include('partials.notification')
<ul>
@foreach($items as $item)
<li>{{ $item->name }}</li>
@endforeach
</ul>
@endsection1. @yield
¿Qué hace?
Define un "hueco" en una plantilla maestra (layout) que será rellenado por otras vistas.
Ejemplo:
<!-- layout.blade.php (plantilla maestra) -->
<head>
<title>@yield('title')</title> <!-- Aquí irá el título -->
</head><!-- vista_hija.blade.php -->
@extends('layout')
@section('title', 'Página de inicio') <!-- Rellena el hueco -->
¿Qué hace?
Define un "hueco" en una plantilla maestra (layout) que será rellenado por otras vistas.Ejemplo:
<!-- layout.blade.php (plantilla maestra) --> <head> <title>@yield('title')</title> <!-- Aquí irá el título --> </head><!-- vista_hija.blade.php --> @extends('layout') @section('title', 'Página de inicio') <!-- Rellena el hueco -->
2. @section + @endsection
¿Qué hace?
Define un bloque de contenido que puede ser inyectado en @yield o usado con @parent (para añadir contenido a una sección existente).
Ejemplo:
<!-- layout.blade.php -->
<body>
@yield('content') <!-- Aquí irá el contenido -->
</body><!-- vista_hija.blade.php -->
@section('content')
<p>Este es el contenido principal.</p>
@endsection
¿Qué hace?
Define un bloque de contenido que puede ser inyectado en@yieldo usado con@parent(para añadir contenido a una sección existente).Ejemplo:
<!-- layout.blade.php --> <body> @yield('content') <!-- Aquí irá el contenido --> </body><!-- vista_hija.blade.php --> @section('content') <p>Este es el contenido principal.</p> @endsection
3. @stack + @push
¿Qué hace?
@stack define un lugar donde se apilarán múltiples bloques de contenido (como scripts o estilos), y @push añade contenido a esa pila.
Ejemplo:
<!-- layout.blade.php -->
<head>
@stack('scripts') <!-- Aquí se acumularán los scripts -->
</head><!-- vista_hija.blade.php -->
@push('scripts')
<script>alert('Hola!');</script>
@endpush
¿Qué hace?
@stackdefine un lugar donde se apilarán múltiples bloques de contenido (como scripts o estilos), y@pushañade contenido a esa pila.Ejemplo:
<!-- layout.blade.php --> <head> @stack('scripts') <!-- Aquí se acumularán los scripts --> </head><!-- vista_hija.blade.php --> @push('scripts') <script>alert('Hola!');</script> @endpush
4. <x-slot> (en componentes)
¿Qué hace?
Permite pasar bloques de HTML a componentes de Blade. Es como un @section pero para componentes.
Ejemplo:
<!-- Componente 'alert.blade.php' -->
<div class="alert">
{{ $slot }} <!-- Aquí va el contenido por defecto -->
<x-slot name="extra">Contenido extra</x-slot>
</div><!-- Uso del componente -->
<x-alert>
Este es el contenido principal.
<x-slot name="extra">Más info...</x-slot>
</x-alert>
¿Qué hace?
Permite pasar bloques de HTML a componentes de Blade. Es como un@sectionpero para componentes.Ejemplo:
<!-- Componente 'alert.blade.php' --> <div class="alert"> {{ $slot }} <!-- Aquí va el contenido por defecto --> <x-slot name="extra">Contenido extra</x-slot> </div><!-- Uso del componente --> <x-alert> Este es el contenido principal. <x-slot name="extra">Más info...</x-slot> </x-alert>
Resumen rápido:
@yield: "Hueco" en el layout.
@section: Bloque de contenido para rellenar el hueco.
@stack/@push: Para acumular cosas (como scripts).
<x-slot>: Bloques de HTML en componentes.
@yield: "Hueco" en el layout.@section: Bloque de contenido para rellenar el hueco.@stack/@push: Para acumular cosas (como scripts).<x-slot>: Bloques de HTML en componentes.
Migraciones en Laravel
Las migraciones en Laravel son como un sistema de control de versiones para tu base de datos. Permiten definir y modificar la estructura de la base de datos de forma programática y colaborativa.
Las migraciones en Laravel son como un sistema de control de versiones para tu base de datos. Permiten definir y modificar la estructura de la base de datos de forma programática y colaborativa.
Conceptos clave
Qué son: Archivos PHP que describen cambios en la estructura de la base de datos (crear tablas, añadir columnas, etc.)
Para qué sirven:
Mantener un historial de cambios en la estructura de la BD
Compartir fácilmente cambios de estructura entre equipos
Deshacer cambios si es necesario
Mantener sincronizados los entornos de desarrollo
Qué son: Archivos PHP que describen cambios en la estructura de la base de datos (crear tablas, añadir columnas, etc.)
Para qué sirven:
Mantener un historial de cambios en la estructura de la BD
Compartir fácilmente cambios de estructura entre equipos
Deshacer cambios si es necesario
Mantener sincronizados los entornos de desarrollo
Comandos básicos
// Crear una nueva migración
php artisan make:migration create_nombre_table
// Ejecutar migraciones pendientes
php artisan migrate
// Revertir la última migración
php artisan migrate:rollback
// Revertir todas las migraciones
php artisan migrate:reset
// Revertir y volver a ejecutar
php artisan migrate:refresh
// Ver estado de las migraciones
php artisan migrate:status
// Crear una nueva migración php artisan make:migration create_nombre_table // Ejecutar migraciones pendientes php artisan migrate // Revertir la última migración php artisan migrate:rollback // Revertir todas las migraciones php artisan migrate:reset // Revertir y volver a ejecutar php artisan migrate:refresh // Ver estado de las migraciones php artisan migrate:status
Estructura de una migración
Una migración típica tiene dos métodos principales:
public function up()
{
// Código para aplicar la migración
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps(); // created_at y updated_at
});
}
public function down()
{
// Código para revertir la migración
Schema::dropIfExists('posts');
}
Una migración típica tiene dos métodos principales:
public function up() { // Código para aplicar la migración Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('content'); $table->timestamps(); // created_at y updated_at }); } public function down() { // Código para revertir la migración Schema::dropIfExists('posts'); }
Tipos comunes de columnas
$table->string('name'); // VARCHAR
$table->text('description'); // TEXT
$table->integer('quantity'); // INTEGER
$table->bigInteger('votes'); // BIGINT
$table->boolean('active'); // BOOLEAN
$table->dateTime('created_at'); // DATETIME
$table->decimal('amount'); // DECIMAL
$table->float('price'); // FLOAT
$table->json('options'); // JSON
$table->string('name'); // VARCHAR $table->text('description'); // TEXT $table->integer('quantity'); // INTEGER $table->bigInteger('votes'); // BIGINT $table->boolean('active'); // BOOLEAN $table->dateTime('created_at'); // DATETIME $table->decimal('amount'); // DECIMAL $table->float('price'); // FLOAT $table->json('options'); // JSON
Modificaciones de tablas
Para modificar una tabla existente:
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique(); // Añadir columna
$table->dropColumn('votes'); // Eliminar columna
$table->renameColumn('from', 'to'); // Renombrar
});
Para modificar una tabla existente:
Schema::table('users', function (Blueprint $table) { $table->string('email')->unique(); // Añadir columna $table->dropColumn('votes'); // Eliminar columna $table->renameColumn('from', 'to'); // Renombrar });
Buenas prácticas
Cada migración debería representar un cambio lógico único
Usar nombres descriptivos para las migraciones
Siempre implementar el método down() para poder revertir
Ejecutar migraciones en producción con precaución (hacer backups)
Las migraciones son una herramienta poderosa que facilita el trabajo en equipo y el despliegue de aplicaciones Laravel
Modelos y Migraciones en Laravel: Guía Completa
En Laravel, los modelos y las migraciones son esenciales para interactuar con la base de datos. A continuación, te explico cómo usarlos eficientemente, incluyendo comandos clave como rollback, refresh y fresh.
Cada migración debería representar un cambio lógico único
Usar nombres descriptivos para las migraciones
Siempre implementar el método
down()para poder revertirEjecutar migraciones en producción con precaución (hacer backups)
Las migraciones son una herramienta poderosa que facilita el trabajo en equipo y el despliegue de aplicaciones Laravel
Modelos y Migraciones en Laravel: Guía Completa
En Laravel, los modelos y las migraciones son esenciales para interactuar con la base de datos. A continuación, te explico cómo usarlos eficientemente, incluyendo comandos clave como rollback, refresh y fresh.
1. Modelos en Laravel
Los modelos representan tablas en la base de datos y permiten interactuar con ellas usando Eloquent ORM.
Los modelos representan tablas en la base de datos y permiten interactuar con ellas usando Eloquent ORM.
Crear un Modelo
php artisan make:model Product -m📌 Explicación:
-m crea automáticamente una migración asociada al modelo.
php artisan make:model Product -m📌 Explicación:
-mcrea automáticamente una migración asociada al modelo.
Estructura básica de un Modelo
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $table = 'products'; // Nombre de la tabla (opcional si sigue convención)
protected $fillable = ['name', 'price']; // Campos asignables masivamente
protected $guarded = ['id']; // Campos protegidos (no asignables)
}📌 Uso común:
$fillable: Permite asignación masiva (ej: Product::create($request->all())).
$guarded: Campos que no se pueden asignar masivamente.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $table = 'products'; // Nombre de la tabla (opcional si sigue convención)
protected $fillable = ['name', 'price']; // Campos asignables masivamente
protected $guarded = ['id']; // Campos protegidos (no asignables)
}📌 Uso común:
$fillable: Permite asignación masiva (ej:Product::create($request->all())).$guarded: Campos que no se pueden asignar masivamente.
2. Migraciones en Laravel
Las migraciones son como "control de versiones" para tu base de datos. Definen la estructura de las tablas.
Las migraciones son como "control de versiones" para tu base de datos. Definen la estructura de las tablas.
Crear una Migración
php artisan make:migration create_products_table📌 Ubicación: database/migrations/XXXX_XX_XX_create_products_table.php
php artisan make:migration create_products_table📌 Ubicación: database/migrations/XXXX_XX_XX_create_products_table.php
Estructura de una Migración
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id(); // Auto-incremental ID
$table->string('name');
$table->decimal('price', 8, 2);
$table->timestamps(); // created_at y updated_at
});
}
public function down()
{
Schema::dropIfExists('products'); // Elimina la tabla al hacer rollback
}
}📌 Tipos de columnas comunes:
string() → VARCHAR.
integer() → INT.
text() → TEXT.
boolean() → TINYINT(1).
timestamps() → Agrega created_at y updated_at.
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id(); // Auto-incremental ID
$table->string('name');
$table->decimal('price', 8, 2);
$table->timestamps(); // created_at y updated_at
});
}
public function down()
{
Schema::dropIfExists('products'); // Elimina la tabla al hacer rollback
}
}📌 Tipos de columnas comunes:
string()→ VARCHAR.integer()→ INT.text()→ TEXT.boolean()→ TINYINT(1).timestamps()→ Agregacreated_atyupdated_at.
3. Comandos Artisan para Migraciones
Comando Explicación php artisan migrateEjecuta migraciones pendientes. php artisan migrate:rollbackDeshace la última migración. php artisan migrate:rollback --step=3Deshace las últimas 3 migraciones. php artisan migrate:refreshRollback + migrate (recrea tablas). php artisan migrate:freshElimina todas las tablas y vuelve a migrar (sin rollback). php artisan migrate:statusMuestra el estado de las migraciones.
📌 ¿Cuándo usar refresh vs fresh?
refresh: Útil si tienes seeders y quieres reinsertar datos.
fresh: Más rápido, pero borra todo sin ejecutar down().
| Comando | Explicación |
|---|---|
php artisan migrate | Ejecuta migraciones pendientes. |
php artisan migrate:rollback | Deshace la última migración. |
php artisan migrate:rollback --step=3 | Deshace las últimas 3 migraciones. |
php artisan migrate:refresh | Rollback + migrate (recrea tablas). |
php artisan migrate:fresh | Elimina todas las tablas y vuelve a migrar (sin rollback). |
php artisan migrate:status | Muestra el estado de las migraciones. |
📌 ¿Cuándo usar refresh vs fresh?
refresh: Útil si tienes seeders y quieres reinsertar datos.fresh: Más rápido, pero borra todo sin ejecutardown().
4. Relaciones entre Modelos
Laravel permite definir relaciones fácilmente:
Laravel permite definir relaciones fácilmente:
Ejemplo: Un Producto pertenece a una Categoría
// En el modelo Product
public function category()
{
return $this->belongsTo(Category::class);
}
// En el modelo Category
public function products()
{
return $this->hasMany(Product::class);
}📌 Tipos de relaciones comunes:
hasOne() → Uno a uno.
hasMany() → Uno a muchos.
belongsTo() → Inversa de hasMany.
belongsToMany() → Muchos a muchos (con tabla pivote).
// En el modelo Product
public function category()
{
return $this->belongsTo(Category::class);
}
// En el modelo Category
public function products()
{
return $this->hasMany(Product::class);
}📌 Tipos de relaciones comunes:
hasOne()→ Uno a uno.hasMany()→ Uno a muchos.belongsTo()→ Inversa dehasMany.belongsToMany()→ Muchos a muchos (con tabla pivote).
5. Seeders (Datos de Prueba)
Genera datos falsos para testing:
Genera datos falsos para testing:
Crear un Seeder
php artisan make:seeder ProductSeeder
php artisan make:seeder ProductSeederEjemplo de Seeder
use App\Models\Product;
use Illuminate\Database\Seeder;
class ProductSeeder extends Seeder
{
public function run()
{
Product::factory()->count(50)->create(); // Usando Factory
// O manualmente:
Product::create(['name' => 'Laptop', 'price' => 999.99]);
}
}📌 Ejecutar Seeders:
php artisan db:seed --class=ProductSeeder
# O para ejecutar todos:
php artisan db:seed
use App\Models\Product;
use Illuminate\Database\Seeder;
class ProductSeeder extends Seeder
{
public function run()
{
Product::factory()->count(50)->create(); // Usando Factory
// O manualmente:
Product::create(['name' => 'Laptop', 'price' => 999.99]);
}
}📌 Ejecutar Seeders:
php artisan db:seed --class=ProductSeeder
# O para ejecutar todos:
php artisan db:seedConclusión
Modelos: Gestionan datos y relaciones con Eloquent.
Migraciones: Controlan la estructura de la base de datos.
Comandos clave: migrate, rollback, refresh, fresh.
Seeders: Poblar la base de datos con datos de prueba
Laravel Tinker: Comandos y Ejemplos Prácticos
Laravel Tinker es una potente herramienta REPL (Read-Eval-Print Loop) que te permite interactuar con tu aplicación Laravel directamente desde la terminal. Es ideal para probar rápidamente código, depurar y manipular datos.
Modelos: Gestionan datos y relaciones con Eloquent.
Migraciones: Controlan la estructura de la base de datos.
Comandos clave:
migrate,rollback,refresh,fresh.Seeders: Poblar la base de datos con datos de prueba
Laravel Tinker: Comandos y Ejemplos Prácticos
Laravel Tinker es una potente herramienta REPL (Read-Eval-Print Loop) que te permite interactuar con tu aplicación Laravel directamente desde la terminal. Es ideal para probar rápidamente código, depurar y manipular datos.
1. Iniciar Tinker
php artisan tinker
php artisan tinker2. Comandos Básicos
A. Manipulación de Modelos
Comando Descripción Ejemplo all()Obtener todos los registros App\Models\User::all()find()Buscar por ID App\Models\User::find(1)where()Consulta con condición App\Models\User::where('age', '>', 18)->get()first()Primer registro App\Models\User::first()count()Contar registros App\Models\User::count()create()Crear nuevo registro App\Models\User::create(['name' => 'Juan', 'email' => 'juan@example.com'])save()Guardar cambios $user = User::find(1); $user->name = 'Pedro'; $user->save()delete()Eliminar registro User::find(1)->delete()
| Comando | Descripción | Ejemplo |
|---|---|---|
all() | Obtener todos los registros | App\Models\User::all() |
find() | Buscar por ID | App\Models\User::find(1) |
where() | Consulta con condición | App\Models\User::where('age', '>', 18)->get() |
first() | Primer registro | App\Models\User::first() |
count() | Contar registros | App\Models\User::count() |
create() | Crear nuevo registro | App\Models\User::create(['name' => 'Juan', 'email' => 'juan@example.com']) |
save() | Guardar cambios | $user = User::find(1); $user->name = 'Pedro'; $user->save() |
delete() | Eliminar registro | User::find(1)->delete() |
B. Relaciones entre Modelos
// Obtener posts de un usuario
$user = App\Models\User::find(1);
$user->posts;
// Obtener autor de un post
$post = App\Models\Post::first();
$post->user;
// Obtener posts de un usuario
$user = App\Models\User::find(1);
$user->posts;
// Obtener autor de un post
$post = App\Models\Post::first();
$post->user;C. Ejecutar Funciones y Helpers
// Generar hash de contraseña
bcrypt('mi-contraseña');
// Generar URL
url('/dashboard');
// Configuración
config('app.name');
// Generar hash de contraseña
bcrypt('mi-contraseña');
// Generar URL
url('/dashboard');
// Configuración
config('app.name');3. Ejemplos Prácticos
Ejemplo 1: Crear y Actualizar Usuario
// Crear usuario
$user = new App\Models\User;
$user->name = 'Carlos';
$user->email = 'carlos@example.com';
$user->password = bcrypt('secret');
$user->save();
// Actualizar usuario
$user = App\Models\User::find(1);
$user->name = 'Carlos Actualizado';
$user->save();
// Crear usuario
$user = new App\Models\User;
$user->name = 'Carlos';
$user->email = 'carlos@example.com';
$user->password = bcrypt('secret');
$user->save();
// Actualizar usuario
$user = App\Models\User::find(1);
$user->name = 'Carlos Actualizado';
$user->save();Ejemplo 2: Consultas Avanzadas
// Usuarios con más de 10 posts
App\Models\User::has('posts', '>', 10)->get();
// Posts ordenados por fecha
App\Models\Post::orderBy('created_at', 'desc')->take(5)->get();
// Usuarios con más de 10 posts
App\Models\User::has('posts', '>', 10)->get();
// Posts ordenados por fecha
App\Models\Post::orderBy('created_at', 'desc')->take(5)->get();Ejemplo 3: Usar Factories
// Crear 5 usuarios falsos
App\Models\User::factory()->count(5)->create();
// Crear post con usuario asociado
$user = App\Models\User::first();
$user->posts()->create(['title' => 'Nuevo post']);
// Crear 5 usuarios falsos
App\Models\User::factory()->count(5)->create();
// Crear post con usuario asociado
$user = App\Models\User::first();
$user->posts()->create(['title' => 'Nuevo post']);4. Comandos Útiles Adicionales
Comando Descripción exit o quitSalir de Tinker clearLimpiar la pantalla dump($var)Mostrar variable con formato \Log::info('mensaje')Escribir en logs cache()->put('key', 'value', 60)Guardar en caché cache()->get('key')Obtener de caché
| Comando | Descripción |
|---|---|
exit o quit | Salir de Tinker |
clear | Limpiar la pantalla |
dump($var) | Mostrar variable con formato |
\Log::info('mensaje') | Escribir en logs |
cache()->put('key', 'value', 60) | Guardar en caché |
cache()->get('key') | Obtener de caché |
5. Consejos de Productividad
Autocompletado: Presiona Tab para autocompletar nombres de clases y métodos.
Historial: Usa las flechas ↑ y ↓ para navegar por el historial.
Multilínea: Presiona Shift + Enter para escribir código en múltiples líneas.
Reutilizar variables: Asigna resultados a variables para usarlos después ($users = User::all()).
Autocompletado: Presiona
Tabpara autocompletar nombres de clases y métodos.Historial: Usa las flechas
↑y↓para navegar por el historial.Multilínea: Presiona
Shift + Enterpara escribir código en múltiples líneas.Reutilizar variables: Asigna resultados a variables para usarlos después (
$users = User::all()).
6. Salir de Tinker
exit
// o
quit
🔹 Tinker es tu mejor aliado para:
✔ Probar consultas Eloquent rápidamente
✔ Depurar relaciones entre modelos
✔ Generar datos de prueba
1. Del Controlador a la Vista
El controlador envía datos a la vista usando el método view() junto con un array asociativo.
exit
// o
quit🔹 Tinker es tu mejor aliado para:
✔ Probar consultas Eloquent rápidamente
✔ Depurar relaciones entre modelos
✔ Generar datos de prueba
1. Del Controlador a la Vista
El controlador envía datos a la vista usando el método view() junto con un array asociativo.
Ejemplo:
Controlador (TaskController.php)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function index()
{
// Datos que queremos pasar a la vista (ej: lista de tareas)
$tasks = [
'Lavar los platos',
'Hacer la compra',
'Estudiar Laravel'
];
// Pasamos las tareas a la vista 'tasks.index'
return view('tasks.index', ['tasks' => $tasks]);
}
}Vista (resources/views/tasks/index.blade.php)
<!DOCTYPE html>
<html>
<head>
<title>Lista de Tareas</title>
</head>
<body>
<h1>Mis Tareas</h1>
<ul>
@foreach($tasks as $task)
<li>{{ $task }}</li>
@endforeach
</ul>
</body>
</html>Resultado en el navegador:
Mis Tareas
- Lavar los platos
- Hacer la compra
- Estudiar Laravel
Controlador (TaskController.php)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function index()
{
// Datos que queremos pasar a la vista (ej: lista de tareas)
$tasks = [
'Lavar los platos',
'Hacer la compra',
'Estudiar Laravel'
];
// Pasamos las tareas a la vista 'tasks.index'
return view('tasks.index', ['tasks' => $tasks]);
}
}Vista (resources/views/tasks/index.blade.php)
<!DOCTYPE html>
<html>
<head>
<title>Lista de Tareas</title>
</head>
<body>
<h1>Mis Tareas</h1>
<ul>
@foreach($tasks as $task)
<li>{{ $task }}</li>
@endforeach
</ul>
</body>
</html>Resultado en el navegador:
Mis Tareas
- Lavar los platos
- Hacer la compra
- Estudiar Laravel2. De la Vista al Controlador (Formulario)
Para enviar datos desde la vista al controlador (ej: añadir una nueva tarea), usamos un formulario y recibimos los datos con $request.
Para enviar datos desde la vista al controlador (ej: añadir una nueva tarea), usamos un formulario y recibimos los datos con $request.
Ejemplo:
Vista (resources/views/tasks/index.blade.php)
<!-- Añadimos un formulario para nuevas tareas -->
<form action="{{ route('tasks.store') }}" method="POST">
@csrf <!-- Token de seguridad -->
<input type="text" name="task" placeholder="Nueva tarea">
<button type="submit">Guardar</button>
</form>Ruta (routes/web.php)
use App\Http\Controllers\TaskController;
Route::get('/tasks', [TaskController::class, 'index'])->name('tasks.index');
Route::post('/tasks', [TaskController::class, 'store'])->name('tasks.store');Controlador (TaskController.php)
public function store(Request $request)
{
// Obtenemos la tarea enviada desde el formulario
$newTask = $request->input('task');
// Aquí podríamos guardarla en una base de datos, etc.
return redirect()->route('tasks.index')->with('success', 'Tarea añadida!');
}
Vista (resources/views/tasks/index.blade.php)
<!-- Añadimos un formulario para nuevas tareas -->
<form action="{{ route('tasks.store') }}" method="POST">
@csrf <!-- Token de seguridad -->
<input type="text" name="task" placeholder="Nueva tarea">
<button type="submit">Guardar</button>
</form>Ruta (routes/web.php)
use App\Http\Controllers\TaskController;
Route::get('/tasks', [TaskController::class, 'index'])->name('tasks.index');
Route::post('/tasks', [TaskController::class, 'store'])->name('tasks.store');Controlador (TaskController.php)
public function store(Request $request)
{
// Obtenemos la tarea enviada desde el formulario
$newTask = $request->input('task');
// Aquí podríamos guardarla en una base de datos, etc.
return redirect()->route('tasks.index')->with('success', 'Tarea añadida!');
}Resumen
✅ Controlador → Vista:
El controlador pasa datos con return view('vista', ['clave' => $valor]).
La vista los recibe como variables (ej: $tasks).
✅ Vista → Controlador:
La vista envía datos mediante un formulario (POST/GET).
El controlador los recibe con $request->input('nombre_campo').
¡Así de fácil! 😊 Con esto ya puedes enviar y recibir datos básicos en Laravel.
✅ Controlador → Vista:
El controlador pasa datos con
return view('vista', ['clave' => $valor]).La vista los recibe como variables (ej:
$tasks).
✅ Vista → Controlador:
La vista envía datos mediante un formulario (POST/GET).
El controlador los recibe con
$request->input('nombre_campo').
¡Así de fácil! 😊 Con esto ya puedes enviar y recibir datos básicos en Laravel.
Componentes en Blade con Slots (Laravel)
Los componentes en Blade permiten crear elementos reutilizables. Los slots son espacios dentro del componente que pueden ser llenados con contenido personalizado cuando se usa el componente. Vamos a adaptar nuestro ejemplo de tareas.
Los componentes en Blade permiten crear elementos reutilizables. Los slots son espacios dentro del componente que pueden ser llenados con contenido personalizado cuando se usa el componente. Vamos a adaptar nuestro ejemplo de tareas.
1. Crear un componente simple (card)
Componente (resources/views/components/card.blade.php)
<div style="border: 1px solid #ccc; padding: 10px; margin: 10px;">
<h2>{{ $title }}</h2>
<div class="content">
{{ $slot }}
</div>
@isset($footer)
<div class="footer">
{{ $footer }}
</div>
@endisset
</div>
<div style="border: 1px solid #ccc; padding: 10px; margin: 10px;">
<h2>{{ $title }}</h2>
<div class="content">
{{ $slot }}
</div>
@isset($footer)
<div class="footer">
{{ $footer }}
</div>
@endisset
</div>2. Modificar la vista para usar componentes
Vista actualizada (resources/views/tareas/index.blade.php)
@extends('layouts.app')
@section('title', 'Lista de Tareas')
@section('content')
<x-card title="Gestión de Tareas">
<form method="POST" action="{{ route('tareas.store') }}">
@csrf
<input type="text" name="nombre" placeholder="Nueva tarea" required>
<button type="submit">Agregar</button>
</form>
<ul>
@foreach($tareas as $tarea)
<li>{{ $tarea->nombre }}</li>
@endforeach
</ul>
<x-slot name="footer">
Total: {{ count($tareas) }} tareas
</x-slot>
</x-card>
@endsection
@extends('layouts.app')
@section('title', 'Lista de Tareas')
@section('content')
<x-card title="Gestión de Tareas">
<form method="POST" action="{{ route('tareas.store') }}">
@csrf
<input type="text" name="nombre" placeholder="Nueva tarea" required>
<button type="submit">Agregar</button>
</form>
<ul>
@foreach($tareas as $tarea)
<li>{{ $tarea->nombre }}</li>
@endforeach
</ul>
<x-slot name="footer">
Total: {{ count($tareas) }} tareas
</x-slot>
</x-card>
@endsectionExplicación de los elementos
Componente principal (<x-card>)
Se llama con title como atributo
El contenido entre las etiquetas va al $slot principal
Slot principal ($slot)
Recibe todo el contenido interno automáticamente
En nuestro caso: el formulario y la lista
Slot con nombre (footer)
Definido con <x-slot name="footer">
Opcional (se verifica con @isset en el componente)
Componente principal (
<x-card>)Se llama con
titlecomo atributoEl contenido entre las etiquetas va al
$slotprincipal
Slot principal (
$slot)Recibe todo el contenido interno automáticamente
En nuestro caso: el formulario y la lista
Slot con nombre (
footer)Definido con
<x-slot name="footer">Opcional (se verifica con
@isseten el componente)
Tipos de slots
Tipo Descripción Ejemplo Slot principal Contenido por defecto {{ $slot }}Slot con nombre Contenido específico {{ $footer }}Slot con atributos Datos adicionales {{ $user->name }}
| Tipo | Descripción | Ejemplo |
|---|---|---|
| Slot principal | Contenido por defecto | {{ $slot }} |
| Slot con nombre | Contenido específico | {{ $footer }} |
| Slot con atributos | Datos adicionales | {{ $user->name }} |
Beneficios de usar componentes
Reutilización: Puedes usar el componente card en cualquier vista
Consistencia: Mantiene el mismo estilo en toda la aplicación
Organización: Separa la lógica de presentación
Flexibilidad: Permite contenido dinámico con slots
Los componentes pueden ser aún más potentes cuando se combinan con:
Props (atributos)
Clases condicionales
Slots con datos
Componentes anónimos
El resto de la aplicación (rutas, controlador, modelo) sigue exactamente igual que en los ejemplos anteriores.
Reutilización: Puedes usar el componente card en cualquier vista
Consistencia: Mantiene el mismo estilo en toda la aplicación
Organización: Separa la lógica de presentación
Flexibilidad: Permite contenido dinámico con slots
Los componentes pueden ser aún más potentes cuando se combinan con:
Props (atributos)
Clases condicionales
Slots con datos
Componentes anónimos
El resto de la aplicación (rutas, controlador, modelo) sigue exactamente igual que en los ejemplos anteriores.
Usando el componente Layout
Para utilizar nuestro componente en la vista welcome.blade.php:
Dejamos solo el <h1> en la vista
Tenemos dos opciones para usar el componente:
Opción 1: Directiva @component
@component('components.layout')
<!-- Contenido que irá en el $slot -->
@endcomponentOpción 2: Etiqueta de componente (recomendada)
<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.
Para utilizar nuestro componente en la vista welcome.blade.php:
Dejamos solo el
<h1>en la vistaTenemos dos opciones para usar el componente:
Opción 1: Directiva @component
@component('components.layout')
<!-- Contenido que irá en el $slot -->
@endcomponentOpción 2: Etiqueta de componente (recomendada)
<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:
En el layout:
@isset($sidebar)
<div id="sidebar">{{ $sidebar }}</div>
@endisset
<!-- Alternativa más corta: -->
@isset($sidebar)
{{ $sidebar }}
@endissetEn la vista:
<x-layout>
<x-slot name="sidebar">
<!-- Contenido del sidebar -->
</x-slot>
</x-layout>
Si queremos agregar un sidebar opcional:
En el layout:
@isset($sidebar)
<div id="sidebar">{{ $sidebar }}</div>
@endisset
<!-- Alternativa más corta: -->
@isset($sidebar)
{{ $sidebar }}
@endissetEn la vista:
<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:
En el layout:
<title>{{ $metaTitle ?? 'Título por defecto' }}</title>
<meta name="description" content="{{ $metaDescription ?? 'Descripción por defecto' }}">En la vista (como atributos):
<x-layout
:meta-title="Título personalizado"
:meta-description="Descripción personalizada"
>
<!-- Nota: usamos kebab-case en atributos pero camelCase en propiedades -->
</x-layout>
Para modificar metadatos como título y descripción:
En el layout:
<title>{{ $metaTitle ?? 'Título por defecto' }}</title>
<meta name="description" content="{{ $metaDescription ?? 'Descripción por defecto' }}">En la vista (como atributos):
<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:
<x-navigation.main /> <!-- Para components/navigation/main.blade.php -->
Si tenemos componentes en subcarpetas:
<x-navigation.main /> <!-- Para components/navigation/main.blade.php -->Evaluando código PHP en propiedades
Si necesitamos evaluar código PHP en las propiedades:
<x-component :prop=":2 + 2" /> <!-- Evaluará a 4 -->
<x-component prop="2 + 2" /> <!-- Mostrará el string "2 + 2" -->
Si necesitamos evaluar código PHP en las propiedades:
<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)
Componentes en Laravel: Reutiliza tu Código de Forma Elegante
En Laravel, los componentes son una forma poderosa de estructurar y reutilizar bloques de código en tus vistas. Con ellos, puedes encapsular lógica y diseño en piezas independientes, haciendo tu aplicación más mantenible y escalable.
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)
Componentes en Laravel: Reutiliza tu Código de Forma Elegante
En Laravel, los componentes son una forma poderosa de estructurar y reutilizar bloques de código en tus vistas. Con ellos, puedes encapsular lógica y diseño en piezas independientes, haciendo tu aplicación más mantenible y escalable.
Tipos de Componentes en Laravel
1. Componentes de Clase
Permiten encapsular lógica y vista en una clase PHP y una plantilla Blade.
Crear un componente:
php artisan make:component AlertEsto genera:
app/View/Components/Alert.php (clase)
resources/views/components/alert.blade.php (vista)
Ejemplo:
// Alert.php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component {
public $type;
public function __construct($type = 'info') {
$this->type = $type;
}
public function render() {
return view('components.alert');
}
}<!-- alert.blade.php -->
<div class="alert alert-{{ $type }}">
{{ $slot }}
</div>Uso en Blade:
<x-alert type="success">
¡Operación exitosa!
</x-alert>
Permiten encapsular lógica y vista en una clase PHP y una plantilla Blade.
Crear un componente:
php artisan make:component AlertEsto genera:
app/View/Components/Alert.php(clase)resources/views/components/alert.blade.php(vista)
Ejemplo:
// Alert.php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component {
public $type;
public function __construct($type = 'info') {
$this->type = $type;
}
public function render() {
return view('components.alert');
}
}<!-- alert.blade.php -->
<div class="alert alert-{{ $type }}">
{{ $slot }}
</div>Uso en Blade:
<x-alert type="success">
¡Operación exitosa!
</x-alert>2. Componentes Anónimos (Inline)
Si no necesitas lógica compleja, puedes definirlos directamente en Blade.
Creación:
php artisan make:component forms.input --inlineEjemplo:
// app/View/Components/Forms/Input.php
namespace App\View\Components\Forms;
use Illuminate\View\Component;
class Input extends Component {
public function render() {
return <<<'blade'
<input {{ $attributes->merge(['class' => 'form-control']) }}>
blade;
}
}Uso:
<x-forms.input type="email" name="email" placeholder="Tu correo" />
Si no necesitas lógica compleja, puedes definirlos directamente en Blade.
Creación:
php artisan make:component forms.input --inlineEjemplo:
// app/View/Components/Forms/Input.php
namespace App\View\Components\Forms;
use Illuminate\View\Component;
class Input extends Component {
public function render() {
return <<<'blade'
<input {{ $attributes->merge(['class' => 'form-control']) }}>
blade;
}
}Uso:
<x-forms.input type="email" name="email" placeholder="Tu correo" />3. Componentes Dinámicos
Permiten renderizar diferentes componentes según una condición.
Ejemplo:
@php
$component = auth()->user()->isAdmin() ? 'admin-alert' : 'user-alert';
@endphp
<x-dynamic-component :component="$component" message="Bienvenido" />
Permiten renderizar diferentes componentes según una condición.
Ejemplo:
@php
$component = auth()->user()->isAdmin() ? 'admin-alert' : 'user-alert';
@endphp
<x-dynamic-component :component="$component" message="Bienvenido" />Ventajas de Usar Componentes
✅ Reutilización – Evita repetir código.
✅ Organización – Separa lógica y presentación.
✅ Personalización – Aceptan atributos y slots.
✅ Legibilidad – Mejora la claridad de tus vistas.
✅ Reutilización – Evita repetir código.
✅ Organización – Separa lógica y presentación.
✅ Personalización – Aceptan atributos y slots.
✅ Legibilidad – Mejora la claridad de tus vistas.
Conclusión
Los componentes en Laravel son una herramienta esencial para construir aplicaciones modernas y mantenibles. Empieza a usarlos para simplificar tu código y mejorar la estructura de tus proyectos.
¿Ya usas componentes en Laravel? ¡Cuéntanos tu experiencia!
En Laravel, los Componentes y Slots son una característica poderosa de Blade que te permite crear elementos reutilizables y modularizar tu interfaz de usuario. Son especialmente útiles para evitar repetir código HTML en diferentes partes de tu aplicación (como cards, modales, alertas, etc.).
Los componentes en Laravel son una herramienta esencial para construir aplicaciones modernas y mantenibles. Empieza a usarlos para simplificar tu código y mejorar la estructura de tus proyectos.
¿Ya usas componentes en Laravel? ¡Cuéntanos tu experiencia!
En Laravel, los Componentes y Slots son una característica poderosa de Blade que te permite crear elementos reutilizables y modularizar tu interfaz de usuario. Son especialmente útiles para evitar repetir código HTML en diferentes partes de tu aplicación (como cards, modales, alertas, etc.).
1. ¿Qué son los Componentes y Slots?
Componentes: Bloques de UI reutilizables (ejemplo: una alerta, un card, un modal).
Slots: Espacios dentro de un componente donde puedes inyectar contenido dinámico.
Slot por defecto: Contenido principal.
Slots con nombre: Contenido específico para ciertas secciones del componente.
Componentes: Bloques de UI reutilizables (ejemplo: una alerta, un card, un modal).
Slots: Espacios dentro de un componente donde puedes inyectar contenido dinámico.
Slot por defecto: Contenido principal.
Slots con nombre: Contenido específico para ciertas secciones del componente.
2. Tipos de Componentes
a) Componentes Anónimos (Archivos de Vista)
Se definen como archivos .blade.php en resources/views/components/.
Se definen como archivos .blade.php en resources/views/components/.
Ejemplo: Crear una Alert Box
Crear el componente:
<!-- resources/views/components/alert.blade.php -->
<div class="alert alert-{{ $type }}">
{{ $slot }} <!-- Slot principal (contenido dinámico) -->
</div>Usar el componente:
<x-alert type="success">
¡Éxito! La operación se completó correctamente.
</x-alert>Resultado:
<div class="alert alert-success">
¡Éxito! La operación se completó correctamente.
</div>
Crear el componente:
<!-- resources/views/components/alert.blade.php --> <div class="alert alert-{{ $type }}"> {{ $slot }} <!-- Slot principal (contenido dinámico) --> </div>Usar el componente:
<x-alert type="success"> ¡Éxito! La operación se completó correctamente. </x-alert>Resultado:
<div class="alert alert-success"> ¡Éxito! La operación se completó correctamente. </div>
b) Componentes con Slots Nombrados
Útil cuando necesitas múltiples secciones dentro de un componente.
Útil cuando necesitas múltiples secciones dentro de un componente.
Ejemplo: Un Card con Título y Cuerpo
Definir el componente (resources/views/components/card.blade.php):
<div class="card">
<div class="card-header">
{{ $title }} <!-- Slot con nombre: 'title' -->
</div>
<div class="card-body">
{{ $slot }} <!-- Slot principal (cuerpo) -->
</div>
</div>Usar el componente:
<x-card>
<x-slot name="title">Título del Card</x-slot>
Contenido principal del card aquí...
</x-card>Resultado:
<div class="card">
<div class="card-header">Título del Card</div>
<div class="card-body">Contenido principal del card aquí...</div>
</div>
Definir el componente (
resources/views/components/card.blade.php):<div class="card"> <div class="card-header"> {{ $title }} <!-- Slot con nombre: 'title' --> </div> <div class="card-body"> {{ $slot }} <!-- Slot principal (cuerpo) --> </div> </div>Usar el componente:
<x-card> <x-slot name="title">Título del Card</x-slot> Contenido principal del card aquí... </x-card>Resultado:
<div class="card"> <div class="card-header">Título del Card</div> <div class="card-body">Contenido principal del card aquí...</div> </div>
c) Componentes de Clase (Más Avanzados)
Si necesitas lógica más compleja, puedes generar un componente con Artisan:
php artisan make:component AlertEsto crea:
app/View/Components/Alert.php (Clase del componente).
resources/views/components/alert.blade.php (Vista del componente).
Si necesitas lógica más compleja, puedes generar un componente con Artisan:
php artisan make:component AlertEsto crea:
app/View/Components/Alert.php(Clase del componente).resources/views/components/alert.blade.php(Vista del componente).
Ejemplo: Componente con Lógica
Definir la clase (app/View/Components/Alert.php):
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component {
public $type;
public function __construct($type = 'info') {
$this->type = $type;
}
public function render() {
return view('components.alert');
}
}Definir la vista (resources/views/components/alert.blade.php):
<div class="alert alert-{{ $type }}">
{{ $slot }}
</div>Usar el componente:
<x-alert type="danger">
¡Error! Algo salió mal.
</x-alert>
Definir la clase (
app/View/Components/Alert.php):<?php namespace App\View\Components; use Illuminate\View\Component; class Alert extends Component { public $type; public function __construct($type = 'info') { $this->type = $type; } public function render() { return view('components.alert'); } }Definir la vista (
resources/views/components/alert.blade.php):<div class="alert alert-{{ $type }}"> {{ $slot }} </div>Usar el componente:
<x-alert type="danger"> ¡Error! Algo salió mal. </x-alert>
3. Ventajas de Usar Componentes y Slots
✅ Reutilización: Evita repetir código HTML.
✅ Modularidad: Separa la lógica y el diseño.
✅ Mantenibilidad: Cambios en un componente se reflejan en todas sus instancias.
✅ Flexibilidad: Slots permiten contenido dinámico sin sacrificar estructura.
✅ Reutilización: Evita repetir código HTML.
✅ Modularidad: Separa la lógica y el diseño.
✅ Mantenibilidad: Cambios en un componente se reflejan en todas sus instancias.
✅ Flexibilidad: Slots permiten contenido dinámico sin sacrificar estructura.
4. Ejemplo Avanzado: Modal Reutilizable
Componente (resources/views/components/modal.blade.php):
<div class="modal">
<div class="modal-header">
{{ $title }}
<button class="close">×</button>
</div>
<div class="modal-body">
{{ $slot }}
</div>
<div class="modal-footer">
{{ $footer ?? 'Botón por defecto' }}
</div>
</div>Uso:
<x-modal title="Confirmar acción">
¿Estás seguro de eliminar este registro?
<x-slot name="footer">
<button class="btn btn-danger">Eliminar</button>
</x-slot>
</x-modal>
Componente (
resources/views/components/modal.blade.php):<div class="modal"> <div class="modal-header"> {{ $title }} <button class="close">×</button> </div> <div class="modal-body"> {{ $slot }} </div> <div class="modal-footer"> {{ $footer ?? 'Botón por defecto' }} </div> </div>Uso:
<x-modal title="Confirmar acción"> ¿Estás seguro de eliminar este registro? <x-slot name="footer"> <button class="btn btn-danger">Eliminar</button> </x-slot> </x-modal>
Conclusión
Los Componentes y Slots en Laravel Blade son esenciales para crear interfaces modulares y mantenibles. Puedes usarlos para:
Alertas, cards, modales, formularios reutilizables.
Evitar duplicar HTML.
Mejorar la organización del código
w
Los Componentes y Slots en Laravel Blade son esenciales para crear interfaces modulares y mantenibles. Puedes usarlos para:
Alertas, cards, modales, formularios reutilizables.
Evitar duplicar HTML.
Mejorar la organización del código
Comentarios
Publicar un comentario