Enrutamiento y Creación de URLS
===============================

Cuando una aplicación Yii empieza a procesar una URL solicitada, lo primero que hace es convertir la URL en una 
[ruta](structure-controllers.md#routes). Luego se usa la ruta para instanciar la 
[acción de controlador](structure-controllers.md) correspondiente para gestionar la petición. A este proceso se 
le llama *enrutamiento*.

El proceso inverso se llama *creación de URLs*, y crea una URL a partir de una ruta dada y unos parámetros de consulta (query) asociados. Cuando posteriormente se solicita la URL creada, el proceso de enrutamiento puede resolverla y 
convertirla en la ruta original con los parámetros asociados.

La principal pieza encargada del enrutamiento y de la creación de URLs es [[yii\web\UrlManager|URL manager]], que se 
registra como el componente de aplicación `urlManager`. El [[yii\web\UrlManager|URL manager]] proporciona el método 
[[yii\web\UrlManager::parseRequest()|parseRequest()]] para convertir una petición entrante en una ruta y sus 
parámetros asociados y el método [yii\web\UrlManager::createUrl()|createUrl()]] para crear una URL a partir de una 
ruta dada y sus parámetros asociados.

Configurando el componente `urlManager` en la configuración de la aplicación, se puede dotar a la aplicación de 
reconocimiento arbitrario de formatos de URL sin modificar el código de la aplicación existente.  Por ejemplo, se 
puede usar el siguiente código para crear una URL para la acción `post/view`:

``` php 
use yii\helpers\Url;

// Url::to() llama a UrlManager::createUrl() para crear una URL
$url = Url::to(['post/view', 'id' => 100]);
```

Dependiendo de la configuración de `urlManager`, la URL generada puede asemejarse a alguno de los siguientes (u otro) 
formato. Y si la URL creada se solicita posteriormente, se seguirá convirtiendo en la ruta original y los valores de 
los parámetros.

```
/index.php?r=post/view&id=100
/index.php/post/100
/posts/100
```


## Formatos de URL <a name="url-formats"></a>

El [[yii\web\UrlManager|URL manager]] soporta dos formatos de URL: el formato predeterminado de URL y el formato URL 
amigable (pretty URL).

El formato de URL predeterminado utiliza un parámetro de consulta llamado `r` para representar la ruta y los 
parámetros normales de la petición para representar los parámetros asociados con la ruta. Por ejemplo, la URL 
`/index.php?r=post/view&id=100` representa la ruta `post/view` y 100 es el valor del parámetro `id` de la consulta. 
El formato predeterminado de URL no requiere ningún tipo de configuración para [[yii\web\UrlManager|URL manager]] y 
funciona en cualquier configuración de servidor Web.

El formato de URL amigable utiliza la ruta adicional a continuación del nombre del script de entrada (entry script) 
para representar la ruta y los parámetros de consulta. Por ejemplo, La ruta en la URL `/index.php/post/100` es 
`/post/100` que puede representar la ruta `post/view` y el parámetro de consulta `id` 100 con una 
[[yii\web\UrlManager::rules|URL rule]] apropiada. Para poder utilizar el formato de URL amigable, se tendrán que 
diseñar una serie de [[yii\web\UrlManager::rules|URL rules]] de acuerdo con el requerimiento actual acerca de como 
deben mostrarse las URLs.

Se puede cambiar entre los dos formatos de URL conmutando la propiedad 
[[yii\web\UrlManager::enablePrettyUrl|enablePrettyUrl]] del [[yii\web\UrlManager|URL manager]] sin cambiar ningún 
otro código de aplicación.

## Enrutamiento <a name="routing"></a>

El Enrutamiento involucra dos pasos. El primero, la petición (request) entrante se convierte en una ruta y sus 
parámetros de consulta asociados. En el segundo paso, se crea la correspondiente 
[acción de controlador](structure-controllers.md) para la ruta convertida para que gestione la petición.

Cuando se usa el formato predefinido de URL, convertir una petición en una ruta es tan simple como obtener los valores 
del parámetro de consulta `GET` llamado `r`.

Cuando se usa el formato de URL amigable, el [[yii\web\UrlManager|URL manager]] examinará las 
[[yii\web\UrlManager::rules|URL rules]] registradas para encontrar alguna que pueda convertir la petición en una ruta. 
Si no se encuentra tal regla, se lanzará una excepción de tipo [[yii\web\NotFoundHttpException]].

Una vez que la petición se ha convertido en una ruta, es el momento de crear la acción de controlador identificada 
por la ruta. La ruta se desglosa en múltiples partes a partir de las barras que contenga. Por ejemplo, `site/index` 
será desglosado en `site` e `index`. Cada parte is un ID que puede hacer referencia a un modulo, un controlador o una 
acción. Empezando por la primera parte de la ruta, la aplicación, sigue los siguientes pasos para generar 
(si los hay), controladores y acciones:

1. Establece la aplicación como el modulo actual.
2. Comprueba si el [[yii\base\Module::controllerMap|controller map]] del modulo actual contiene un ID actual. Si lo 
   tiene, se creará un objeto controlador de acuerdo con la configuración del controlador encontrado en el mapa, y 
   se seguirá el Paso 5 para gestionar la parte restante de la ruta. 
3. Comprueba si el ID hace referencia a un modulo listado en la propiedad [[yii\base\Module::modules|modules]] del 
   módulo actual. Si está listado, se crea un modulo de acuerdo con la configuración encontrada en el listado de 
   módulos, y se seguirá el Paso 2 para gestionar la siguiente parte de la ruta bajo el contexto de la creación de un 
   nuevo módulo.
4. Trata el ID como si se tratara de un ID de controlador y crea un objeto controlador. Sigue el siguiente paso con la    parte restante de la ruta.
5. El controlador busca el ID en su [[yii\base\Controller::actions()|action map]]. Si lo encuentra, crea una acción de    acuerdo con la configuración encontrada en el mapa. De otra forma, el controlador intenta crear una acción en linea    definida por un método de acción correspondiente al ID actual.

Si ocurre algún error entre alguno de los pasos anteriores, se lanzará una excepción de tipo 
[[yii\web\NotFoundHttpException]], indicando el fallo de proceso de enrutamiento.

### Ruta Predeterminada <a name="default-route"></a>

Cuando una petición se convierte en una ruta vacía, se usa la llamada *ruta predeterminada*. Por defecto, la ruta 
predeterminada es `site/index`, que hace referencia a la acción `index` del controlador `site`. Se puede personalizar 
configurando la propiedad [[yii\web\Application::defaultRoute|defaultRoute]] de la aplicación en la configuración de 
aplicación como en el siguiente ejemplo:

```php
[
    // ...
    'defaultRoute' => 'main/index',
];
```


### Ruta `catchAll` <a name="catchall-route"></a>

A veces, se puede querer poner la aplicación Web en modo de mantenimiento temporalmente y mostrar la misma pagina de 
información para todas las peticiones. Hay varias maneras de lograr este objetivo. Pero una de las maneras más simples 
es configurando la propiedad [[yii\web\Application::catchAll]] como en el siguiente ejemplo de configuración de 
aplicación:

```php
[
    // ...
	'catchAll' => ['site/offline'],
];
```

Con la anterior configuración, se usar la acción `site/offline` para gestionar todas las peticiones entrantes.

La propiedad `catchAll` debe tener un array cuyo primer elemento especifique una ruta, y el resto de elementos 
(pares nombre-valor) especifiquen los parámetros [ligados a la acción](structure-controllers.md#action-parameters).

## Creación de URLs <a name="creating-urls"></a>

Yii proporciona un método auxiliar (helper method) [[yii\helpers\Url::to()]] para crear varios tipos de URLs a partir 
de las rutas dadas y sus parámetros de consulta asociados. Por ejemplo, 

```php
use yii\helpers\Url;

// crea una URL para la ruta: /index.php?r=post/index
echo Url::to(['post/index']);

// crea una URL para la ruta con parámetros: /index.php?r=post/view&id=100
echo Url::to(['post/view', 'id' => 100]);

// crea una URL interna: /index.php?r=post/view&id=100#contentecho 
Url::to(['post/view', 'id' => 100, '#' => 'content']);

// crea una URL absoluta: http://www.example.com/index.php?r=post/index
echo Url::to(['post/index'], true);

// crea una URL absoluta usando el esquema https: https://www.example.com/index.php?r=post/index
echo Url::to(['post/index'], 'https');
```

Hay que tener en cuenta que en el anterior ejemplo, asumimos que se está usando el formato de URL predeterminado. 
Si habilita el formato de URL amigable, las URLs creadas serán diferentes, de acuerdo con las 
[[yii\web\UrlManager::rules|URL rules] que se usen.

La ruta que se pasa al método [[yii\helpers\Url::to()]] es context sensitive. Esto quiere decir que puede ser una ruta 
*relativa* o una ruta *absoluta* que serán tipificadas de acuerdo con las siguientes reglas:

- Si una ruta es una cadena vacía, se usará la [yii\web\Controller::route|route]] solicitada actualmente. 
- Si la ruta no contiene ninguna barra `/`, se considerará que se trata de un ID de acción del controlador actual y se 
  le antepondrá el valor [[\yii\web\Controller::uniqueId|uniqueId]] del controlador actual. 
- Si la ruta no tiene barra inicial, se considerará que se trata de una ruta relativa al modulo actual y se le 
  antepondrá el valor [[\yii\base\Module::uniqueId|uniqueId]] del modulo actual.

Por ejemplo, asumiendo que el modulo actual es `admin` y el controlador actual es `post`,

```php
use yii\helpers\Url;

// la ruta solicitada: /index.php?r=admin/post/index
echo Url::to(['']);

// una ruta relativa solo con ID de acción: /index.php?r=admin/post/index
echo Url::to(['index']);

// una ruta relativa: /index.php?r=admin/post/index
echo Url::to(['post/index']);

// una ruta absoluta: /index.php?r=post/index
echo Url::to(['/post/index']);
```

El método [[yii\helpers\Url::to()]] se implementa llamando a los métodos 
[[yii\web\UrlManager::createUrl()|createUrl()]] y [[yii\web\UrlManager::createAbsoluteUrl()|createAbsoluteUrl()]] del 
[[yii\web\UrlManager|URL manager]]. En las próximas sub-secciones, explicaremos como configurar el 
[[yii\web\UrlManager|URL manager]] para personalizar el formato de las URLs generadas.

El método [[yii\helpers\Url::to()]] también soporta la creación de URLs NO relacionadas con rutas particulares. 
En lugar de pasar un array como su primer paramento, se debe pasar una cadena de texto. Por ejemplo,

```php
use yii\helpers\Url;

// la URL solicitada actualmente: /index.php?r=admin/post/index
echo Url::to();

// una URL con alias: http://example.comYii::setAlias('@example', 'http://example.com/');
echo Url::to('@example');

// una URL absoluta: http://example.com/images/logo.gif
echo Url::to('/images/logo.gif', true);```
```

Además del método `to()`, la clase auxiliar [[yii\helpers\Url]] también proporciona algunos otros métodos de creación 
de URLs. Por ejemplo,

```php
use yii\helpers\Url;

// URL de la página inicial: /index.php?r=site/index
echo Url::home();

// la URL base, útil si la aplicación se desarrolla en una sub-carpeta de la carpeta raíz (root) Web
echo Url::base();

// la URL canónica de la actual URL solicitada// visitar https://en.wikipedia.org/wiki/Canonical_link_element
echo Url::canonical();

// recuerda la actual URL solicitada y la recupera más tarde requestsUrl::remember();
echo Url::previous();
```


## Uso de URLs Amigables <a name="using-pretty-urls"></a>

Para utilizar URLs amigables, hay que configurar el componente `ulrManager` en la configuración de la aplicación como 
en el siguiente ejemplo:

```php
[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => true,
            'rules' => [
                // ...
            ],
        ],
    ],
]
```

La propiedad [[yii\web\UrlManager::enablePrettyUrl|enablePrettyUrl]] es obligatoria ya que alterna el formato de URL 
amigable. El resto de propiedades son opcionales. Sin embargo, la anterior configuración es la más común.

* [[yii\web\UrlManager::showScriptName|showScriptName]]: esta propiedad determina si el script de entrada debe ser 
  incluido en las URLs generadas. Por ejemplo, en lugar de crear una URL `/index.php/post/100`, estableciendo la 
  propiedad con valor true, la URL que se generará sera `/post/100`.
* [[yii\web\UrlManager::enableStrictParsing|enableStrictParsing]]: esta propiedad determina si se habilita la 
  conversión de petición estricta, si se habilita, la URL solicitada tiene que encajar al menos con uno de las 
  [[yii\web\UrlManager::rules|rules]] para poder ser tratada como una petición valida, o se lanzará una 
  [[yii\web\NotFoundHttpException]]. Si la conversión estricta esta deshabilitada, cuando ninguna de las 
  [[yii\web\UrlManager::rules|rules]] coincida con la URL solicitada, la parte de información de la URL se tratará 
  como si fuera la ruta solicitada.
* [[yii\web\UrlManager::rules|rules]]: esta propiedad contiene una lista de las reglas que especifican como convertir 
  y crear URLs. Esta es la propiedad principal con la que se debe trabajar para crear URLs que satisfagan el formato 
  de un requerimiento particular de la aplicación.

> Nota: Para ocultar el nombre del script de entrada en las URLs generadas, además de establecer el 
  [[yii\web\UrlManager::showScriptName|showScriptName]] a falso, puede ser necesaria la configuración del servidor Web 
  para que identifique correctamente que script PHP debe ejecutarse cuando se solicita una URL que no lo especifique. 
  Si se usa el servidor Web Apache, se puede utilizar la configuración recomendada descrita en la sección de 
  [Instalación](start-installation.md#recommended-apache-configuration).


### Regalas de URL <a name="url-rules"></a>

Una regla de URL es una instancia de [[yii\web\UrlRule]] o de una clase hija. Cada URL consiste en un patrón utilizado 
para cotejar la parte de información de ruta de las URLs, una ruta, y algunos parámetros de consulta. Una URL puede 
usarse para convertir una petición si su patrón coincide con la URL solicitada y una regla de URL pude usarse para 
crear una URL si su ruta y sus nombres de parámetros coinciden con los que se hayan dado.

Cuando el formato de URL amigables está habilitado, el [[yii\web\UrlManager|URL manager]] utiliza las reglas de URL 
declaradas en su propiedad [[yii\web\UrlManager::rules|rules]] para convertir las peticiones entrantes y crear URLs. 
En particular, para convertir una petición entrante, el [[yii\web\UrlManager|URL manager]] examina las reglas en el 
orden que se han declarado y busca la *primera* regla que coincida con la URL solicitada. La regla que coincide es la 
que se usa para convertir la URL en una ruta y sus parámetros asociados. De igual modo, para crear una URL, el 
[[yii\web\UrlManager|URL manager]] busca la primera regla que coincida con la ruta dad y los parámetros y la utiliza 
para crear una URL.

Se pueden configurar las [[yii\web\UrlManager::rules]] como un array con claves, siendo los patrones y las reglas sus 
correspondientes rutas. Cada pareja patrón-ruta construye una regla de URL. Por ejemplo, la siguiente configuración de 
configuración de [[yii\web\UrlManager::rules|rules]] declara dos reglas de URL. La primera regla coincide con una URL 
`posts` y la mapea a la ruta `post/index`. La segunda regla coincide con una URL que coincida con la expresión regular 
`post/(\d+)` y la mapea a la ruta `post/view` y el parámetro llamado `id`.

```php
[
    'posts' => 'post/index', 
    'post/<id:\d+>' => 'post/view',
]
```

> Información; El patrón en una regla se usa para encontrar coincidencias en la parte de información de la URL. 
  Por ejemplo, la parte de información de la ruta `/index.php/post/100?source=ad` es `post/100` 
  (la primera barra y la ultima son ignoradas) que coincide con el patrón `post/(\d+)`.

Entre la declaración de reglas de URL como pares de patrón-ruta, también se pueden declarar como arrays de 
configuración. Cada array de configuración se usa para configurar un único objeto de tipo regla de URL. Este proceso 
se necesita a menudo cuando se quieren configurar otras propiedades de la regla de URL. Por ejemplo,

```php
[
    // ... otras reglas de URL ...
    
    [
        'pattern' => 'posts',
        'route' => 'post/index',
        'suffix' => '.json',
    ],
]
```

De forma predeterminada si no se especifica la opción `class` en la configuración de una regla, se utilizará la clase 
predeterminada [[yii\web\UrlRule]].


### Parameters Asociativos <a name="named-parameters"></a>

Una regla de URL puede asociarse a una determinado grupo de parámetros de consulta que se hayan sido especificados en 
el patrón con el formato `<ParamName:RegExp>`, donde `ParamName` especifica el nombre del parámetro y `RegExp` es una 
expresión regular opcional que se usa para encontrara los valores de los parámetros. Si no se especifica `RegExp` 
significa que el parámetro debe ser una cadena de texto sin ninguna barra.

> Nota: Solo se pueden especificar expresiones regulares para los parámetros. La parte restante del patrón se 
  considera texto plano.

Cuando se usa una regla para convertir una URL, esta rellenara los parámetros asociados con los valores que coincidan 
con las partes correspondientes de la URL, y estos parámetros serán accesibles posteriormente mediante `$_GET` por el 
componente de aplicación `request`. Cuando se usa una regla para crear una URL, esta obtendrá los valores de los 
parámetros proporcionados y los insertara donde se hayan declarado los parámetros.

Vamos a utilizar algunos ejemplos para ilustrar como funcionan los parámetros asociativos. Asumiendo que hemos 
declarado las siguientes tres URLs:

```php
[
    'posts' => 'post/index',
    'post/<id:\d+>' => 'post/view',
    'posts/<year:\d{4}>/<category>' => 'post/index',
]
```

Cuando se usen las reglas para convertir URLs:

- `/index.php/posts` se convierte en la ruta `post/index` usando la primera regla;
- `/index.php/posts/2014/php` se convierte en la ruta `post/index`, el parámetro `year` cuyo valor es 2014 y el 
  parámetro `category` cuyo valor es `php` usando la tercera regla;
- `/index.php/post/100` se convierte en la ruta `post/view` y el parámetro `id` cuyo valor es 100 usando la segunda 
  regla;
- `/index.php/posts/php` provocara una [[yii\web\NotFoundHttpException]] cuando 
  [[yii\web\UrlManager::enableStrictParsing]] sea true, ya que no coincide ninguno de los parámetros . Si 
  [[yii\web\UrlManager::enableStrictParsing]] es false (valor predeterminado), se devolverá como ruta la parte de 
  información `posts/php`.

Y cuando las se usen las reglas para crear URLs:

- `Url::to(['post/index'])` genera `/index.php/posts` usando la primera regla;
- `Url::to(['post/index', 'year' => 2014, 'category' => 'php'])` genera `/index.php/posts/2014/php` usando la tercera 
  regla;
- `Url::to(['post/view', 'id' => 100])` genera `/index.php/post/100` usando la segunda regla;
- `Url::to(['post/view', 'id' => 100, 'source' => 'ad'])` genera `/index.php/post/100?source=ad` usando la segunda 
   regla. Debido a que el parámetro `source` no se especifica en la regla, se añade como un parámetro de consulta en 
   la URL generada.
- `Url::to(['post/index', 'category' => 'php'])` genera `/index.php/post/index?category=php` no usa ninguna de las 
   reglas. Hay que tener en cuenta que si no se aplica ninguna de las reglas, la URL se genera simplemente añadiendo 
   la parte de información de la ruta y todos los parámetros como parte de la consulta.


### Parametrización de Rutas <a name="parameterizing-routes"></a>

Se pueden incrustar nombres de parámetros en la ruta de una regla de URL. Esto permite a la regla de URL poder ser 
usada para que coincida con varias rutas. Por ejemplo, la siguiente regla incrusta los parámetros `controller` y 
`action` en las rutas.

```php
[
    '<controller:(post|comment)>/<id:\d+>/<action:(create|update|delete)>' => '<controller>/<action>',
    '<controller:(post|comment)>/<id:\d+>' => '<controller>/view',
    '<controller:(post|comment)>s' => '<controller>/index',
]
```

Para convertir una URL `index.php/comment/100/create`, se aplicará la primera regla, que establece el parámetro 
`controller` a `comment` y el parámetro `action` a `create`. Por lo tanto la ruta `<controller>/<action>` se resuelve 
como `comment/create`.

Del mismo modo, para crear una URL para una ruta `comment/index`, se aplicará la tercera regla, que crea una URL 
`/index.php/comments`.

> Información: Mediante la parametrización de rutas es posible reducir el numero de reglas de URL e incrementar 
  significativamente el rendimiento del [[yii\web\UrlManager|URL manager]].

De forma predeterminada, todos los parámetros declarados en una regla son requeridos. Si una URL solicitada no 
contiene un parámetro en particular, o si se esta creando una URL sin un parámetro en particular, la regla no se 
aplicará. Para establecer algunos parámetros como opcionales, se puede configurar la propiedad de 
[[yii\web\UrlRule::defaults|defaults]] de una regla. Los parámetros listados en esta propiedad son opcionales y se 
usarán los parámetros especificados cuando estos no se proporcionen.

En la siguiente declaración de reglas, los parámetros `page` y `tag` son opcionales y cuando no se proporcionen, se 
usarán los valores 1 y cadena vacía respectivamente.

```php
[
    // ... otras reglas ...
    [
        'pattern' => 'posts/<page:\d+>/<tag>',
        'route' => 'post/index',
        'defaults' => ['page' => 1, 'tag' => ''],
    ],
]
```

La regla anterior puede usarse para convertir o crear cualquiera de las siguientes URLs:

* `/index.php/posts`: `page` es 1, `tag` es ''.
* `/index.php/posts/2`: `page` es 2, `tag` es ''.
* `/index.php/posts/2/news`: `page` es 2, `tag` es `'news'`.
* `/index.php/posts/news`: `page` es 1, `tag` es `'news'`.

Sin usar ningún parámetro opcional, se tendrían que crear 4 reglas para lograr el mismo resultado.


### Reglas con Nombres de Servidor <a name="rules-with-server-names"></a>

Es posible incluir nombres de servidores Web en los parámetros de las URLs. Esto es practico principalmente cuando una 
aplicación debe tener distintos comportamientos paro diferentes nombres de servidores Web. Por ejemplo, las siguientes 
reglas convertirán la URL `http://admin.example.com/login` en la ruta `admin/user/login` y 
`http://www.example.com/login` en `site/login`.

```php
[
    'http://admin.example.com/login' => 'admin/user/login',
    'http://www.example.com/login' => 'site/login',
]
```

También se pueden incrustar parámetros en los nombres de servidor para extraer información dinámica de ellas. Por 
ejemplo, la siguiente regla convertirá la URL `http://en.example.com/posts` en la ruta `post/index` y el parámetro 
`language=en`.

```php
[
    'http://<language:\w+>.example.com/posts' => 'post/index',
]
```

> Nota: Las reglas con nombres de servidor NO deben incluir el subdirectorio del script de entrada (entry script) en 
  sus patrones. Por ejemplo, is la aplicación se encuentra en `http://www.example.com/sandbox/blog`, entonces se debe 
  usar el patrón `http://www.example.com/posts` en lugar de `http://www.example.com/sandbox/blog/posts`. Esto 
  permitirá que la aplicación se pueda desarrollar en cualquier directorio sin la necesidad de cambiar el código de la 
  aplicación.

### Sufijos de URL <a name="url-suffixes"></a>

Se puede querer añadir sufijos a las URLs para varios propósitos. Por ejemplo, se puede añadir `.html`a las URLs para 
que parezcan URLs para paginas HTML estáticas; también se puede querer añadir `.json` a las URLs para indicar el tipo 
de contenido que se espera encontrar en una respuesta (response). Se puede lograr este objetivo configurando la 
propiedad [[yii\web\UrlManager::suffix]] como en el siguiente ejemplo de configuración de aplicación:

```php
[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => true,
            'suffix' => '.html',
            'rules' => [
                // ...
            ],
        ],
    ],
]
```

La configuración anterior permitirá al [[yii\web\UrlManager|URL manager]] reconocer las URLs solicitadas y a su vez 
crear URLs con el sufijo `.html`.

> Consejo: Se puede establecer `/` como el prefijo de URL para que las URLs finalicen con una barra.

> Nota: Cuando se configura un sufijo de URL, si una URL solicitada no tiene el sufijo, se considerará como una URL 
  desconocida. Esta es una practica recomendada para SEO (optimización en motores de búsqueda).

A veces, se pueden querer usar sufijos diferentes para URLs diferentes. Esto se puede conseguir configurando la 
propiedad [[yii\web\UrlRule::suffix|suffix]] de una regla de URL individual. Cuando una regla de URL tiene la 
propiedad establecida, anulará el sufijo estableciendo a nivel de [[yii\web\UrlManager|URL manager]]. Por ejemplo, la 
siguiente configuración contiene una regla de URL personalizada que usa el sufijo `.json` en lugar del sufijo global 
`.html`.

```php
[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => true,
            'suffix' => '.html',
            'rules' => [
                // ...
                [
                    'pattern' => 'posts',
                    'route' => 'post/index',
                    'suffix' => '.json',
                ],
            ],
        ],
    ],
]
```


### Métodos HTTP <a name="http-methods"></a>

Cuando se implementan APIs RESTful, normalmente se necesita que ciertas URLs se conviertan en otras de acuerdo con el 
método HTTP que se esté usando. Esto se puede hacer fácilmente prefijando los métodos HTTP soportados como los 
patrones de las reglas. Si una regla soporta múltiples métodos HTTP, hay que separar los nombres de los métodos con 
comas. Por ejemplo, la siguiente regla usa el mismo patrón `post/<id:\d+>` para dar soporte a diferentes métodos HTTP. 
Una petición para `PUT post/100` se convertirá en `post/create`, mientras que una petición `GET post/100` se 
convertirá en `post/view`.

```php
[
    'PUT,POST post/<id:\d+>' => 'post/create',
    'DELETE post/<id:\d+>' => 'post/delete',
    'post/<id:\d+>' => 'post/view',
]
```

> Nota: Si una regla de URL contiene algún método HTTP en su patrón, la regla solo se usará para aplicar conversiones. 
  Se omitirá cuando se llame a [[yii\web\UrlManager|URL manager]] para crear URLs.

> Consejo: Para simplificar el enrutamiento en APIs RESTful, Yii proporciona una clase de reglas de URL 
  [[yii\rest\UrlRule]] especial que es bastante eficiente y soporta ciertas características como pluralización de IDs 
  de controladores. Para conocer más detalles, se puede visitar la sección [Enrutamiento](rest-routing.md) acerca de 
  el desarrollo de APIs RESTful.


### Personalización de Reglas <a name="customizing-rules"></a>

En los anteriores ejemplos, las reglas de URL se han declarado principalmente en términos de pares de patrón-ruta. 
Este es un método de acceso directo que se usa a menudo. En algunos escenarios, se puede querer personalizar la regla 
de URL configurando sus otras propiedades, tales como [[yii\web\UrlRule::suffix]]. Esto se puede hacer usando una 
array completo de configuración para especificar una regla. El siguiente ejemplo se ha extraído de la subsección 
[Sufijos de URL](#url-suffixes).

```php
[
    // ... otras reglas de URL ...
    
    [
        'pattern' => 'posts',
        'route' => 'post/index',
        'suffix' => '.json',
    ],
]
```

> Información: De forma predeterminada si no se especifica una opción `class` para una configuración de regla, se 
  usará la clase predeterminada [[yii\web\UrlRule]].


### Adición de Reglas Dinámicamente <a name="adding-rules"></a>

Las reglas de URL se pueden añadir dinámicamente en el [[yii\web\UrlManager|URL manager]]. A menudo se necesita por 
[módulos](structure-modules.md) redistribubles que se encargan de gestionar sus propias reglas de URL. Para que las 
reglas añadidas dinámicamente tenga efecto durante el proceso de enrutamiento, se deben añadir durante la etapa 
[bootstrapping](runtime-bootstrapping.md). Para los módulos, esto significa que deben implementar 
[[yii\base\BootstrapInterface]] y añadir las reglas en el método 
[[yii\base\BootstrapInterface::bootstrap()|bootstrap()]] como en el siguiente ejemplo:

```php
public function bootstrap($app)
{
    $app->getUrlManager()->addRules([
        // declaraciones de reglas aquí
    ], false);
}
```

Hay que tener en cuenta se deben añadir estos módulos en [[yii\web\Application::bootstrap]] para que puedan participar 
en el proceso de [bootstrapping](runtime-bootstrapping.md)

### Creación de Clases de Reglas <a name="creating-rules"></a>

A pesar del hecho de que de forma predeterminada la clase [[yii\web\UrlRule]] lo suficientemente flexible para la 
mayoría de proyectos, hay situaciones en las que se tiene que crear una clase de reglas propia. Por ejemplo, en un 
sitio Web de un concesionario de coches, se puede querer dar soporte a las URL con el siguiente formato 
`/Manufacturer/Model`, donde tanto `Manufacturer` como `Model` tengan que coincidir con algún dato almacenado una 
tabla de la base de datos. De forma predeterminada, la clase regla no puede gestionar estas reglas ya que se base en 
patrones estáticos declarados.

Podemos crear la siguiente clase de reglas de URL para solucionar el problema.

```php
namespace app\components;

use yii\web\UrlRuleInterface;
use yii\base\Object;

class CarUrlRule extends Object implements UrlRuleInterface
{

    public function createUrl($manager, $route, $params)
    {
        if ($route === 'car/index') {
            if (isset($params['manufacturer'], $params['model'])) {
                return $params['manufacturer'] . '/' . $params['model'];
            } elseif (isset($params['manufacturer'])) {
                return $params['manufacturer'];
            }
        }
        return false;  // no se aplica esta regla
    }

    public function parseRequest($manager, $request)
    {
        $pathInfo = $request->getPathInfo();
        if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) {
            // comprueba $matches[1] y $matches[3] para ver
            // si coincide con un *manufacturer* y un *model* en la base de datos
            // Si coinciden, establece $params['manufacturer'] y/o $params['model']
            // y devuelve ['car/index', $params]
        }
        return false;  // no se aplica la regla
    }
}
```

Y usa la nueva clase de regla en la configuración de [[yii\web\UrlManager::rules]]:

```php
[
    // ... otras reglas ...
    
    [
        'class' => 'app\components\CarUrlRule', 
        // ... configura otras propiedades ...
    ],
]
```

## Consideración del Rendimiento <a name="performance-consideration"></a>

Cuando se desarrolla una aplicación Web compleja, es importante optimizar las reglas de URL para que tarden el mínimo 
tiempo posible en convertir las peticiones y crear URLs.

Usando rutas parametrizadas se puede reducir el numero de reglas de URL que a su vez significa una mejor en el 
rendimiento.

Cuando se convierten o crean URLs, el [[yii\web\UrlManager|URL manager]] examina las reglas de URL en el orden en que 
han sido declaradas. Por lo tanto, se debe tener en cuenta el orden de las reglas de URL y anteponer las reglas más 
especificas y/o las que se usen más a menudo.

Si algunas URLs comparten el mismo prefijo en sus patrones o rutas, se puede considerar usar [[yii\web\GroupUrlRule]] 
ya que puede ser más eficiente al ser examinado por [[yii\web\UrlManager|URL manager]] como un grupo. Este suele ser 
el caso cuando una aplicación se compone por módulos, y cada uno tiene su propio conjunto de reglas con un ID de 
módulo para sus prefijos más comunes.
