Capítulo 5.2: Creación de vistas sencillas para la API
Tiempo de estudio: 45 minutos
1. Tarea: Visualizar datos
Nuestra API en el Capítulo 2 puede entregar datos en formato JSON. Esto es excelente para máquinas, pero las personas prefieren ver la información en páginas web bellamente diseñadas. Nuestro objetivo es crear dos de esas páginas:
- Lista de todos los planetas (
/planets
) - Página de un solo planeta (
/planets/{id}
)
Para ello, utilizaremos la combinación "Ruta → Controlador → Vista".
💡 Analogía espacial:
Imagine que el JSON de la API son datos de telemetría sin procesar, simplemente un flujo de números. Nuestra tarea hoy es crear dos pantallas (dos "vistas") en el Centro de Control de la Misión:
- Pantalla general: muestra el estado de todos los objetos en el sistema (lista de planetas).
- Pantalla detallada: al hacer clic en un objeto, muestra toda la información sobre él (página de un solo planeta).
2. Paso 1: Creación de un controlador para páginas web
Para la limpieza de la arquitectura, no conviene mezclar la lógica de la API y la lógica de las páginas web en un solo controlador. Crearemos un nuevo controlador específicamente para mostrar nuestras vistas Blade.
Ejecute en la terminal:
Lo creamos en la subcarpetaWeb
para separarlo de los controladores de API.
Abra el archivo creado app/Http/Controllers/Web/PlanetPageController.php
.
Paso 2: Página con la lista de todos los planetas
1. Crear un método en el controlador:
En PlanetPageController
, añada el método index
, que obtendrá todos los planetas de la base de datos y los pasará a la vista.
<?php
namespace App\Http\Controllers\Web;
use App\Http\Controllers\Controller;
use App\Models\Planet; // No olvide importar el modelo
class PlanetPageController extends Controller
{
/**
* Muestra la página con la lista de todos los planetas.
*/
public function index()
{
// 1. Obtenemos todos los planetas de la DB
$planets = Planet::all();
// 2. Devolvemos la vista y le pasamos los datos
return view('planets.index', ['planets' => $planets]);
}
}
2. Crear una vista Blade:
Cree el archivo resources/views/planets/index.blade.php
. Usaremos el layout creado en el capítulo anterior.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Planetas</title>
<style>
body {
font-family: sans-serif;
background-color: #f4f4f9;
color: #333;
margin: 0;
padding: 2em;
}
.container {
max-width: 960px;
margin: 0 auto;
}
h2 {
color: #1a202c;
}
hr {
border: none;
border-top: 1px solid #e2e8f0;
margin: 1.5em 0;
}
.planet-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5em;
}
.planet-card {
background-color: #fff;
border: 1px solid #e2e8f0;
border-radius: 0.5em;
padding: 1.5em;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
transition: transform 0.2s;
}
.planet-card:hover {
transform: translateY(-5px);
}
.planet-card h3 {
margin-top: 0;
color: #2d3748;
}
.planet-card p {
margin-bottom: 0.5em;
color: #4a5568;
}
.planet-card a {
color: #4299e1;
text-decoration: none;
font-weight: bold;
}
.planet-card a:hover {
text-decoration: underline;
}
.no-planets {
color: #718096;
}
</style>
</head>
<body>
<div class="container">
<h2>Lista de todos los planetas conocidos</h2>
<hr>
<div class="planet-list">
@forelse($planets as $planet)
<div class="planet-card">
<h3>{{ $planet->name }}</h3>
<p>Sistema solar: {{ $planet->solar_system }}</p>
<p>Diámetro: {{ number_format($planet->size_km, 0, '.', ' ') }} km</p>
<a href="/planets/{{ $planet->id }}">Saber más →</a>
</div>
@empty
<p class="no-planets">No hay planetas en la base de datos. Por favor, ejecute los seeders.</p>
@endforelse
</div>
</div>
</body>
</html>
number_format(...)
— es una función PHP común para formatear números de forma agradable. Se puede usar directamente en Blade.
3. Crear una ruta en routes/web.php
:
use App\Http\Controllers\Web\PlanetPageController;
// ...
Route::get('/planets', [PlanetPageController::class, 'index']);
/planets
en su navegador, verá la página con la lista de planetas!
4. Paso 3: Página de un solo planeta
1. Crear un método en el controlador:
En PlanetPageController
, añadiremos el método show
. Gracias al Route Model Binding, Laravel encontrará automáticamente el planeta por ID y lo pasará al método.
<?php
// Dentro de la clase PlanetPageController
/**
* Muestra la página de un planeta específico.
*/
public function show(Planet $planet)
{
// Laravel ya ha encontrado el planeta para nosotros.
// Si no se encuentra, devolverá automáticamente un error 404.
return view('planets.show', ['planet' => $planet]);
}
2. Crear una vista Blade:
Cree el archivo resources/views/planets/show.blade.php
.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $planet->name }}</title>
<style>
body {
font-family: sans-serif;
background-color: #f4f4f9;
color: #333;
margin: 0;
padding: 2em;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
max-width: 600px;
width: 100%;
}
.planet-detail {
background-color: #fff;
border: 1px solid #e2e8f0;
border-radius: 0.5em;
padding: 2em;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}
.planet-detail h1 {
margin-top: 0;
color: #2d3748;
}
.planet-detail p {
margin-bottom: 1em;
color: #4a5568;
font-size: 1.1em;
}
.back-link {
display: inline-block;
margin-top: 1.5em;
color: #4299e1;
text-decoration: none;
font-weight: bold;
}
.back-link:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<div class="planet-detail">
@if($planet->image_url)
<img src="{{ $planet->image_url }}" alt="Imagen de {{ $planet->name }}" style="max-width: 100%; height: auto; border-radius: 0.5em; margin-bottom: 1em;">
@endif
<h1>{{ $planet->name }}</h1>
@if($planet->description)
<p>{{ $planet->description }}</p>
@endif
<p><strong>Sistema solar:</strong> {{ $planet->solar_system }}</p>
<p><strong>Diámetro:</strong> {{ number_format($planet->size_km, 0, '.', ' ') }} km</p>
<a href="/planets" class="back-link">← Volver a la lista de planetas</a>
</div>
</div>
</body>
</html>
3. Crear una ruta en routes/web.php
:
// Добавьте этот маршрут после маршрута для /planets
Route::get('/planets/{planet}', [PlanetPageController::class, 'show']);
{planet}
debe coincidir con el nombre de la variable en el método del controlador (show(Planet $planet)
) para que Route Model Binding funcione correctamente.
Ahora, al hacer clic en el enlace "Saber más" en la página de la lista, accederá a la página de detalles de un planeta específico.
Cuestionario de consolidación
🚀 Resumen del capítulo:
Has creado con éxito un "escaparate" para tu API, utilizando la arquitectura Laravel MVC. Ahora tienes:
- Un controlador separado para la lógica de las páginas web.
- Una página dinámica con una lista de todos los planetas, que obtiene datos de la DB.
- Una página de detalles para cada planeta, utilizando Route Model Binding.
- Dos rutas web en
routes/web.php
para acceder a estas páginas.
Has transformado los datos brutos en información comprensible y útil para el usuario. En el siguiente capítulo, añadiremos interactividad, incrustando JavaScript en nuestras vistas Blade para interactuar con la API sin recargar la página.