Núcleo
Ruteo y reescritura de URLs
De la URL al controlador
Route::parseURI() descompone la URL sin necesidad de declarar rutas:
- Pasa todo a minúsculas y reemplaza
-por_(/reset-password→reset_password). - Si el primer segmento es
adminy hay más segmentos, lo quita y marca la ruta como del panel (se busca enControllers/Admin/). - Si el siguiente segmento es el nombre de un plugin activo, lo quita y busca los controladores en
plugins/<plugin>/src/Controllers/. - Mientras los segmentos coincidan con subcarpetas de
Controllers/, los consume como carpeta. - Lo que queda es
controlador/acción/argumentos….
| URL | Controlador | Acción | Argumentos |
|---|---|---|---|
/ |
IndexController |
index |
|
/cuentas |
CuentasController |
index |
|
/cuentas/reset-password |
CuentasController |
resetPassword |
|
/productos/ver/15/rojo |
ProductosController |
ver |
15, rojo |
/ajax/cuentas/login |
Ajax/CuentasController |
login |
|
/admin/sistema/usuarios/editar/7 |
Admin/Sistema/UsuariosController |
editar |
7 |
/noticias/listado (plugin noticias) |
plugins/noticias/…/ListadoController |
index |
Los argumentos llegan como parámetros de la acción, en orden:
public function ver($id = null, $color = null) {
$producto = TMProductos::find(intval($id));
if (!$producto) {
$this->Response->setCode(404);
return;
}
$this->set(['producto' => $producto]);
}
Nombres de acción
La acción se pasa a camelCase (reset_password → resetPassword). La plantilla, en cambio, usa el nombre original en minúsculas: cuentas/reset_password.tpl.
Parámetros especiales
?action=nombreen la consulta (o en el POST) reemplaza la acción de la URL.?subaction=nombrequeda disponible enRoute::get()['subaction'].
Consultar la ruta actual
$route = Route::get();
// ['uri'=>'productos/ver/15', 'qs'=>'', 'plugin'=>'', 'controller'=>'Productos',
// 'action'=>'ver', 'raw_action'=>'ver', 'arguments'=>['15']]
Route::getDomain(); // 'https://misitio.com'
Route::setAction('otra');
Archivos estáticos de plugins
Si la URL empieza con el nombre de un plugin y termina en .js, .css, .map o una imagen, Koshkil entrega el archivo desde plugins/<plugin>/webroot/ directamente. Un .js que no existe como archivo se trata como la acción javascript del controlador, útil para generar JavaScript desde PHP.
Reglas de reescritura
Para URLs que no siguen la convención, se definen reglas en config/rewrite.php (o la del dominio) bajo System.Web.Rewrite. Se evalúan antes del ruteo, en orden, contra la URL sin la barra inicial.
<?php
$CONFIG = [
'System' => [
'Web' => [
'Rewrite' => [
// /negocios/panaderia-lopez -> /negocios?nombre=panaderia-lopez
['rule' => '^negocios/([a-z\-0-9]*)$', 'target' => '/negocios?nombre=$1', 'flags' => 'L,NC'],
// alias de una sección del panel
['rule' => '^admin/usuarios/(editar|listado)$', 'target' => '/admin/sistema/usuarios/$1?subusuarios=1', 'flags' => 'L,NC'],
],
],
],
];
| Parte | Significado |
|---|---|
rule |
Expresión regular (delimitador ~). |
target |
Nueva URL. $1, $2… se reemplazan por los grupos capturados. La consulta del destino se agrega a $_GET. |
flags |
L: última regla, deja de evaluar. NC: no distingue mayúsculas. RW: sigue evaluando las siguientes reglas sobre la URL ya reescrita. |
Las reglas también se pueden agregar desde código, antes del ruteo:
RewriteManager::addRule('^ofertas$', '/productos/listado?oferta=1', 'L,NC');
RewriteManager::addRule('^promo$', '/productos/promo', 'L', true); // true: al principio
Los plugins declaran sus reglas en plugins/<plugin>/config/rewrite.php (arreglo $RULES), y se agregan después de las globales. Con Debug.Rewrite en 5 o más, cada evaluación se registra en tmp/logs/rewrite.log.
Generar enlaces
Nunca escribas rutas absolutas a mano: el proyecto puede estar en una subcarpeta.
| Método | Devuelve |
|---|---|
Koshkil::getLink('/productos/ver/15') |
URL de una página (antepone Web.Path). |
Koshkil::getPath('/css/app.css') |
Ruta web de un archivo. Con true como segundo argumento, la ruta física en disco. |
Koshkil::getThemePath('css/theme.css') |
Archivo dentro del theme activo. |
Koshkil::redirect('/cuentas') |
Redirige y termina la ejecución. |
<a href="{Koshkil::getLink('/productos/ver/'|cat:$producto->prd_codigo)}">Ver</a>
<link rel="stylesheet" href="{Koshkil::getThemePath('css/theme.css')}">