04.

Anotaciones y Rutas con Comodín

|

Share this awesome video!

|

Es muy sencillo crear una ruta en YAML que apunte a una función del controlador. Pero hay una forma aun más simple de crear rutas... y me encanta. Se llama: anotaciones.

Primero, comenta la ruta en YAML. Básicamente, borrala. Para comprobar que no funciona, refresca la homepage. Asi es! Regresó a la página de bienvenida.

4 lines | config/routes.yaml
#index:
# path: /
# controller: App\Controller\QuestionController::homepage

Instalación Soporte a Anotaciones

Las anotaciones son un formato especial de configuración y el soporte a anotaciones no es un standard en nuestra pequeña aplicación de Symfony. Y... eso está bien! De hecho, esa es toda la filosofía de Symfony: empieza pequeño y agrega funcionalidades cuando las necesites.

Para agregar soporte a anotaciones, vamos a utilizar Composer para requerir una nueva librería. Si aun no tienes Composer instalado, ve a https://getcomposer.org.

Una vez que lo instales, corre:

composer require annotations

Si estás familiarizado con Composer, el nombre de la librería se te ha de hacer extraño. Y en realidad, instaló una librería totalmente diferente: sensio/framework-extra-bundle. Casi al final del comando, menciona algo sobre dos recetas. Hablaremos sobre ello próximamente: es parte de lo que hace especial a Symfony.

Agregando Rutas con Anotaciones

En fin, ya que el soporte a anotaciones está instalado, podemos agregar de vuelta nuestra ruta usando anotaciones. Que significa eso? Arriba de la función del controlador, escribe /** y presiona enter para crear una sección PHPDoc Luego escribe @Route y autocompleta la del componente Routing. Tal como la otra vez, PhpStorm agregó automáticamente el use statement en la parte de arriba de la clase.

Dentro de los paréntesis, escribe "/".

18 lines | src/Controller/QuestionController.php
// ... lines 1 - 5
use Symfony\Component\Routing\Annotation\Route;
class QuestionController
{
/**
* @Route("/")
*/
public function homepage()
{
// ... line 15
}
}

Eso es todo! Cuando el usuario vaya a la homepage, se va a ejecutar la función abajo de esto. Me encantan las anotaciones porque son simples de leer y mantienen la ruta y controlador uno junto del otro. Y si... las anotaciones son literalmente configuración dentro de comentarios de PHP. Si no te gustan, siempre puedes utilizar YAML o XML: Symfony es super flexible. Desde el punto de vista del rendimiento, todos los formatos son lo mismo.

Ahora cuando refrescamos la homepage... estamos de vuelta!

Una Segunda Ruta y Controlador

Esta página eventualmente va a listar algunas preguntas recientes. Cuando le das click a una pregunta en específico, necesitará su propia página. Vamos a crear una segunda ruta y controlador para ello. Como? creando un segundo metodo. Que tal: public function show().

26 lines | src/Controller/QuestionController.php
// ... lines 1 - 7
class QuestionController
{
// ... lines 10 - 20
public function show()
{
// ... line 23
}
}

Arriba de esto, agrega @Route() y asigna la URL a, que te parece, /questions/how-to-tie-my-shoes-with-magic. Eso seria grandioso!

26 lines | src/Controller/QuestionController.php
// ... lines 1 - 7
class QuestionController
{
// ... lines 10 - 17
/**
* @Route("/questions/how-to-tie-my-shoes-with-magic")
*/
public function show()
{
// ... line 23
}
}

Adentro, justo como la última vez, retorna una nueva respuesta: la de HttpFoundation.

La página futura para mostrar preguntas

26 lines | src/Controller/QuestionController.php
// ... lines 1 - 7
class QuestionController
{
// ... lines 10 - 17
/**
* @Route("/questions/how-to-tie-my-shoes-with-magic")
*/
public function show()
{
return new Response('Future page to show a question!');
}
}

Vamos a probarla! Copia la URL, ve a tu navegador, pega y... funciona! Acabamos de crear una segunda página... en menos de un minuto.

El Controlador Frontal: Trabajando Detrás De Cámaras

Por cierto, no importa a cual URL vayamos - como esta o la homepage - el archivo PHP que nuestro servidor web ejecuta es index.php. Es como si fuéramos a /index.php/questions /how-to-tie-my-shoes-with-magic. La única razón por la que no necesitas escribir index.php en la URL es porque nuestro servidor web local está configurado para ejecutar index.php automáticamente. En producción, tu configuración de Nginx o Apache debe de hacer lo mismo. Revisa la documentación de Symfony para aprender como hacerlo.

Rutas con Comodín

Eventualmente, vamos a tener una base de datos llena de preguntas. Y entonces, no, no vamos a crear manualmente una ruta por cada pregunta. En su lugar, podemos hacer más inteligente esta ruta. Reemplaza la parte how-to-tie-my-shoes-with-magic por {slug}.

Cuando pones algo entre llaves dentro de una ruta, se convierte en comodín. Esta ruta ahora aplica a /questions/LO-QUE-SEA. El nombre {slug} no es importante: pudimos haber puesto lo que sea... por ejemplo {slugulusErectus}! No hace ninguna diferencia.

Pero, como sea que llamemos a este comodín - ejemplo {slug} - ahora nos permite tener un argumento en nuestro controlador con el mismo nombre: $slug... el cual será asignado con el valor de esa parte de la URL.

29 lines | src/Controller/QuestionController.php
// ... lines 1 - 7
class QuestionController
{
// ... lines 10 - 17
/**
* @Route("/questions/{slug}")
*/
public function show($slug)
{
// ... lines 23 - 26
}
}

Utilicemoslo para hacer mas elegante a nuestra página! Usemos sprintf(), escribe " la pregunta" y agrega %s como comodín. Pasa $slug como comodín.

29 lines | src/Controller/QuestionController.php
// ... lines 1 - 7
class QuestionController
{
// ... lines 10 - 17
/**
* @Route("/questions/{slug}")
*/
public function show($slug)
{
return new Response(sprintf(
'Future page to show the question "%s"!',
$slug
));
}
}

Bien! Cambia al navegador, refresca y... me encanta! Cambia la URL a /questions /accidentally-turned-cat-into-furry-shoes y... eso también funciona!

En el futuro, vamos a utilizar el $slug para extraer la pregunta de la base de datos. Pero como aun no llegamos ahí, usaré str_replace() ... y ucwords() solo para hacerlo un poco mas elegante. Aun es pronto, pero la página ya comienza a estar viva!

29 lines | src/Controller/QuestionController.php
// ... lines 1 - 7
class QuestionController
{
// ... lines 10 - 20
public function show($slug)
{
return new Response(sprintf(
// ... line 24
ucwords(str_replace('-', ' ', $slug))
));
}
}

A continuación, nuestra aplicación esconde un secreto! Una pequeña línea de comandos ejecutable que está llena de beneficios.