O framework PHP por trás do SitioYa

Documentação do Koshkil

Núcleo

Roteamento e reescrita de URLs

Da URL ao controlador

Route::parseURI() decompõe a URL sem necessidade de declarar rotas:

  1. Converte tudo para minúsculas e troca - por _ (/reset-passwordreset_password).
  2. Se o primeiro segmento for admin e houver mais segmentos, remove-o e marca a rota como do painel (buscada em Controllers/Admin/).
  3. Se o próximo segmento for o nome de um plugin ativo, remove-o e busca os controladores em plugins/<plugin>/src/Controllers/.
  4. Enquanto os segmentos coincidirem com subpastas de Controllers/, são consumidos como pasta.
  5. O que sobra é controlador/ação/argumentos….
URL Controlador Ação 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

Os argumentos chegam como parâmetros da ação, em ordem:

public function ver($id = null, $color = null) {
    $producto = TMProductos::find(intval($id));
    if (!$producto) {
        $this->Response->setCode(404);
        return;
    }
    $this->set(['producto' => $producto]);
}

Nomes de ação

A ação é convertida para camelCase (reset_passwordresetPassword). O template, por outro lado, usa o nome original em minúsculas: cuentas/reset_password.tpl.

Parâmetros especiais

  • ?action=nome na query string (ou no POST) substitui a ação da URL.
  • ?subaction=nome fica disponível em Route::get()['subaction'].

Consultar a rota atual

$route = Route::get();
// ['uri'=>'productos/ver/15', 'qs'=>'', 'plugin'=>'', 'controller'=>'Productos',
//  'action'=>'ver', 'raw_action'=>'ver', 'arguments'=>['15']]

Route::getDomain();     // 'https://meusite.com'
Route::setAction('outra');

Arquivos estáticos de plugins

Se a URL começa com o nome de um plugin e termina em .js, .css, .map ou uma extensão de imagem, o Koshkil entrega o arquivo diretamente de plugins/<plugin>/webroot/. Um .js que não existe como arquivo é tratado como a ação javascript do controlador, útil para gerar JavaScript a partir do PHP.

Regras de reescrita

Para URLs que não seguem a convenção, defina regras em config/rewrite.php (ou no do domínio) em System.Web.Rewrite. Elas são avaliadas antes do roteamento, em ordem, contra a URL sem a barra inicial.

<?php
$CONFIG = [
    'System' => [
        'Web' => [
            'Rewrite' => [
                // /negocios/padaria-lopes  ->  /negocios?nombre=padaria-lopes
                ['rule' => '^negocios/([a-z\-0-9]*)$', 'target' => '/negocios?nombre=$1', 'flags' => 'L,NC'],
                // apelido de uma seção do painel
                ['rule' => '^admin/usuarios/(editar|listado)$', 'target' => '/admin/sistema/usuarios/$1?subusuarios=1', 'flags' => 'L,NC'],
            ],
        ],
    ],
];
Parte Significado
rule Expressão regular (delimitador ~).
target Nova URL. $1, $2… são substituídos pelos grupos capturados. A query string do destino é adicionada a $_GET.
flags L: última regra, para de avaliar. NC: não diferencia maiúsculas. RW: continua avaliando as regras seguintes sobre a URL já reescrita.

As regras também podem ser adicionadas por código, antes do roteamento:

RewriteManager::addRule('^ofertas$', '/productos/listado?oferta=1', 'L,NC');
RewriteManager::addRule('^promo$', '/productos/promo', 'L', true); // true: no início

Os plugins declaram suas regras em plugins/<plugin>/config/rewrite.php (array $RULES), adicionadas depois das globais. Com Debug.Rewrite em 5 ou mais, cada avaliação é registrada em tmp/logs/rewrite.log.

Nunca escreva caminhos absolutos à mão: o projeto pode estar em uma subpasta.

Método Retorna
Koshkil::getLink('/productos/ver/15') URL de uma página (antepõe Web.Path).
Koshkil::getPath('/css/app.css') Caminho web de um arquivo. Com true como segundo argumento, o caminho físico em disco.
Koshkil::getThemePath('css/theme.css') Arquivo dentro do tema ativo.
Koshkil::redirect('/cuentas') Redireciona e encerra a execução.
<a href="{Koshkil::getLink('/productos/ver/'|cat:$producto->prd_codigo)}">Ver</a>
<link rel="stylesheet" href="{Koshkil::getThemePath('css/theme.css')}">