---
title: "Enrutamiento"
description: "Cómo Nibiru asigna URLs a controladores, acciones y parámetros — incluyendo formas de URL amigables para el SEO."
---

El enrutamiento de Nibiru es **basado en convenciones** con rutas regex opcionales desde `settings.<env>.ini` para casos especiales. No hay un gran archivo de rutas que mantener.

## La convención predeterminada
```
/<controller>/<action>/<param1>/<param2>/...
```
Ejemplos:

| URL | Controlador | Acción | $_REQUEST |
|---|---|---|---|
| `/` | `indexController` | (ninguna) | — |
| `/productos` | `productsController` | (ninguna) | — |
| `/productos/detalle` | `productsController` | `detailAction` | — |
| `/productos/detalle/42` | `productsController` | `detailAction` | `id => 42` |
| `/usuarios/editar/42` | `usersController` | `editAction` | `id => 42` |

Sin un `_action`, solo se ejecutan `navigationAction()` y `pageAction()`. Con `_action`, la acción nombrada se ejecuta en medio.

## URLs para SEO

Nibiru detecta automáticamente URL amigables para motores de búsqueda sin ninguna configuración. El patrón:
```
/<controller>/<slug>/<numeric-id>
```
Si el segundo segmento **no** es un nombre de método en el controlador y el tercer segmento es numérico, Nibiru reescribe la solicitud internamente a:
```
/<controller>/detail/?id=<numeric-id>&slug=<slug>
```
Así que una URL como `/maschine/marduk-gold-plating/42` llega a `maschineController::detailAction()` con `$_REQUEST['id'] === '42'` y `$_REQUEST['slug'] === 'marduk-gold-plating'`. Esto es exactamente cómo el sitio web de comercio electrónico de producción `prod.maschinen-stockert.de` produce URLs limpias sin un enrutador personalizado.

## Leyendo parámetros

Cualquier cosa después del segmento de acción se convierte en una clave `$_REQUEST` asociada por posición:
```php
// /users/edit/42  →  $_REQUEST['id'] = '42'
public function editAction() {
    $id = (int) ($_REQUEST['id'] ?? 0);
    // ...
}
```
Para parámetros no numéricos o nombrados, prefiera cadenas de consulta:
```
/users/search?q=marduk&page=2
```
## Rutas personalizadas a través de INI

La sección `[NIBIRU_ROUTING]` en `settings.<env>.ini` te permite mapear patrones de URL regex a pares controlador/acción y parámetros nombrados:
```ini
[NIBIRU_ROUTING]
; Map /api/v1/products/42 to apiController::productsAction with id=42
api.v1.products.pattern    = "^/api/v1/products/(\d+)$"
api.v1.products.controller = "api"
api.v1.products.action     = "products"
api.v1.products.params[]   = "id"
```
Cuando una URL coincide con el patrón, los grupos capturados se asignan a las claves nombradas `params[]` (en orden) como entradas de `$_REQUEST`.

## Ayudantes de enrutamiento
```php
Router::getInstance()->currentPage();   // 'products'
Router::getInstance()->tplName();       // 'products'  (controller stem for templates)
Router::getInstance()->getController(); // alias for currentPage()
```
Estos son útiles dentro de los controladores y plantillas:
```smarty
<a href="/products" class="{if Router::currentPage() == 'products'}active{/if}">
  Products
</a>
```
(En Smarty usarías un complemento de Smarty o una variable preasignada; el ayudante mismo es para PHP.)

## Reenvío

Para redirigir a nivel del marco (establece los encabezados HTTP correctos y sale):
```php
View::forwardTo('/login');
```
Para una respuesta en formato JSON (establece `Content-Type: application/json`):
```php
View::forwardToJsonHeader();
View::assign(['data' => ['ok' => true]]);
```
Este patrón se utiliza intensamente por los puntos finales de la API en producción — consulte el `apiController` en `data.maschinen-stockert.de`.

## URLs de paginación

La paginación de Nibiru espera URLs del tipo:
```
/<controller>/<action>/page/<N>
```
La clase `Pageination` analiza el segmento final `page/N`, por lo que cualquier formato de ruta que lo conserve está bien.

## Barras finales y mayúsculas/minúsculas

Las URL se coinciden de manera ** sensible a mayúsculas y minúsculas **. `/Users/edit` y `/users/edit` alcanzarán diferentes controladores (la segunda existe, la primera da un error 404). Las barras finales son toleradas.

## Trampas comunes

- **Colisión de acción con URL SEO.** Si nombras un método `aboutAction()` e intentas usar `/products/about/42` como una URL SEO, la reescritura SEO *no* se disparará porque `about` es una acción conocida. Elige slugs que no colisionen con los nombres de las acciones.
- **Acción sin `_action`.** Simplemente escribir `/products/detail/` **no** llama a `detailAction()` — `_action` debe estar establecido. El despachador lo hace automáticamente cuando la URL tiene al menos dos segmentos, pero una cadena de consulta eliminada no lo hará.
- **`index` es el controlador raíz.** `/` → `indexController`. No hay una ruta "home" separada.
