---
title: "Inicio Rápido"
description: "Construye una página mínima de Productos en cinco minutos — controlador, vista, entrada de navegación."
---

Al final de esta página tendrás una página `/products` funcional renderizada por Smarty, alimentada por un controlador y listada en el menú lateral.

## 1. Generar un controlador
```bash
./nibiru -c products
```
Esto crea dos archivos:
```
application/controller/productsController.php
application/view/templates/products.tpl
```
## 2. Conectar el controlador

Abre `productsController.php` y reemplaza el cuerpo con:
```php
<?php
namespace Nibiru;
use Nibiru\Adapter\Controller;

class productsController extends Controller
{
    public function pageAction()
    {
        View::assign([
            'title'    => 'Products — Nibiru',
            'products' => [
                ['id' => 1, 'name' => 'Marduk Gold Plating', 'price' => 99.0],
                ['id' => 2, 'name' => 'Tiamat Hull Sealant', 'price' => 49.0],
                ['id' => 3, 'name' => 'Anu Stardust Polish', 'price' => 19.5],
            ],
            'css' => Config::getInstance()->getConfig()[View::NIBIRU_SETTINGS]['smarty.css'],
            'js'  => Config::getInstance()->getConfig()[View::NIBIRU_SETTINGS]['smarty.js'],
        ]);
    }

    public function navigationAction()
    {
        JsonNavigation::getInstance()->loadJsonNavigationArray();
    }
}
```
Dos métodos son convencionales y **siempre llamados** por el [despachador](/core/dispatcher/):

- `navigationAction()` — llena el menú de navegación global.
- `pageAction()` — renderiza la página en sí misma.

Cualquier cosa que coincida con `?_action=foo` llamará además al método `fooAction()` entre ellos.

## 3. Escribe la vista

Abre `application/view/templates/products.tpl`:
```smarty
{include 'shared/header.tpl'}
<body>
{include file="navigation.tpl"}

<main class="container">
  <h1>{$title}</h1>

  <table class="table">
    <thead>
      <tr><th>#</th><th>Name</th><th>Price</th></tr>
    </thead>
    <tbody>
      {foreach $products as $p}
        <tr>
          <td>{$p.id}</td>
          <td><a href="/products/detail/{$p.id}">{$p.name|escape}</a></td>
          <td>{$p.price|string_format:"%.2f"} €</td>
        </tr>
      {/foreach}
    </tbody>
  </table>
</main>

{include 'shared/footer.tpl'}
</body>
```
Las variables pasadas a `View::assign()` aparecen como `{$variable}` en Smarty.

## 4. Agregar una entrada de navegación

Edite `application/settings/config/navigation/main.json` y agregue:
```json
{
  "label": "Products",
  "href":  "/products",
  "icon":  "shopping-bag"
}
```
La navegación se carga mediante `JsonNavigation` y se renderiza mediante `navigation.tpl`.

## 5. Ejecútalo

Si tienes el servidor integrado de PHP a mano:
```bash
APPLICATION_ENV=development php -S localhost:8080 -t .
```
Visite <http://localhost:8080/products/>. Debería ver sus tres productos con el tema cósmico de su CSS.

## Agregar una página de detalles

En el mismo controlador:
```php
public function detailAction()
{
    $id = (int) ($_REQUEST['id'] ?? 0);
    View::assign([
        'title' => "Product #$id",
        'id'    => $id,
    ]);
}
```
El `Router` ya entiende `/products/detail/42` y `/products/marduk-gold-plating/42` (forma de URL SEO — el `id` y el `slug` se llenan automáticamente en `$_REQUEST`).

Cree `application/view/templates/products/detail.tpl` con cualquier marcado que desee, y tendrá una aplicación de dos páginas.

## ¿Dónde vamos a continuación?

- [Arquitectura (MMVC)](/core/architecture/) — cómo se encajan todos los componentes móviles.
- [Módulos](/core/modules/) — cuándo pasar de controladores + rasgos a un módulo real.
- [Base de datos y migraciones](/core/database/) — conectar la página a una tabla `products` real.
