Creación de Controladores y Rutas en Symfony

Clase 8 de 17Curso de Symfony Framework

¿Qué puede hacer el administrador?

El administrador debe ser capaz de velar por el correcto funcionamiento del sistema, con lo cual, deberá tener acceso a ver todo lo que ocurre.

En particular, deberá tener acceso a ver todas las ofertas registradas, todos los postulantes, etc.

Para que el sistema pueda comenzar a funcionar será necesario que existan algunas empresas registradas y, siendo el administrador el único habilitado a crearlas, vamos a comenzar por darle esa funcionalidad.

El controlador de empresas

Symfony está basado en el patrón MVC (Model View Controller).

En este esquema existen clases que definen el modelo de datos (Las que vimos antes, que maneja Doctrine), otras que se encargan de recibir y responder a las peticiones de los usuarios (Los controladores) y otras que permiten generar las pantallas (Vistas).

El primer paso para crear un controlador es usar el comando php bin/console make:controller

La primera pregunta que debemos responder es qué nombre llevará este controller.

En general es una buena práctica definir los controladores en función de los objetos o entidades que manejarán.

En nuestro caso, ya que estaremos trabajando sobre empresas, le llamaremos CompanyController.

Al finalizar contaremos con dos archivos:

  • src/Controller/CompanyController.php
  • templates/Company/index.html.twig

Como te imaginarás, el que contendrá el código php será el primero, el segundo dejémoslo para dentro de un ratito.

Veamos el contenido de CompanyController:

<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Routing\Annotation\Route; class CompanyController extends AbstractController { /** * @Route("/Company", name="Company") */ public function index() { return $this->render('Company/index.html.twig', [ 'controller_name' => 'CompanyController', ]); } }
Hay bastante para decir, ¿cierto?

Comencemos viendo que tenemos un método llamado index que lo único que hace es llamar a $this->render pasando dos parámetros: una cadena que contiene una ruta al otro archivo creado y un arreglo.

El método render es heredado (Nota que la clase CompanyController extiende a AbstractController).

Su función es tomar una plantilla y convertirla en una respuesta que pueda ser enviada al cliente (por general HTML, aunque podría ser de otro tipo).

¿Te da curiosidad ver qué generó esto? Ok, date el gusto :)

Si abres tu navegador en http://homestead.test/Company te encontrarás con una pantalla similar a:

Ejemplo de como se ve la app en el navegador

¿Cómo es eso posible? Es parte de la magia de Symfony :)

Lo que está sucediendo es que se está creando una ruta (/company) y mapeándose al método CompanyController::index()

¿Cómo?

Simplemente gracias al annotation:

/** * @Route("/company", name="company") */

Symfony cuenta con un poderoso sistema de ruteo que permite que cada petición sea “atrapada” por un script que actúa como único punto de entrada a la aplicación y, de acuerdo a su URL sea derivada hacia el controlador que corresponde para generar una respuesta.

Eso responde a la pregunta de cómo se interpreta la URL que usaste… ahora queda la otra pregunta: ¿por qué ves ese HTML?

Ese HTML es el resultado de renderizar el template templates/company/index.html.twig.

El hecho de que el nombre del archivo finalice en .twig tampoco es casual.

Twig es un motor de templates muy potente (el usado por defecto en Symfony).

La idea de Twig es dar una sintaxis simple (lo más parecida a HTML que se pueda) para que personas sin amplios conocimientos de programación (léase diseñadores) puedan encargarse de los temas de FrontEnd.

Démosle una mirada al template:

{% extends 'base.html.twig' %} {% block title %}Hello CompanyController!{% endblock %} {% block body %} <style> .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } </style> <div class="example-wrapper"> <h1>Hello {{ controller_name }}!</h1> This friendly message is coming from: <ul> <li>Your controller at <code><a href="{{ '/home/mauro/jobboard/src/Controller/CompanyController.php'|file_link(0) }}">src/Controller/CompanyController.php</a></code></li> <li>Your template at <code><a href="{{ '/home/mauro/jobboard/templates/company/index.html.twig'|file_link(0) }}">templates/company/index.html.twig</a></code></li> </ul> </div> {% endblock %}

A simple vista nos encontramos con algo de HTML y algunos tags de otro tipo… por si no los notaste, se trata de tags {{ }} y {% %}

Te los muestro de nuevo resaltados en color:

{% extends 'base.html.twig' %} {% block title %}Hello CompanyController!{% endblock %} {% block body %} <style> .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; } .example-wrapper code { background: #F5F5F5; padding: 2px 6px; } </style> <div class="example-wrapper"> <h1>Hello {{ controller_name }}!</h1> This friendly message is coming from: <ul> <li>Your controller at <code><a href="{{ '/home/mauro/jobboard/src/Controller/CompanyController.php'|file_link(0) }}">src/Controller/CompanyController.php</a></code></li> <li>Your template at <code><a href="{{ '/home/mauro/jobboard/templates/company/index.html.twig'|file_link(0) }}">templates/company/index.html.twig</a></code></li> </ul> </div> {% endblock %}

Los bloques {{ }} son el equivalente a llamadas a la función echo de php, se utilizan para mostrar, por ejemplo, el contenido de variables.

Los bloques {% %} son bloques de control. A través de ellos es posible realizar comparaciones, bucles y demás herramientas de lógica.

Y ahora, para completar quiero que notes un detalle: en la llamada a $this->render que se realiza en CompanyController::index() se envía como segundo parámetro este arreglo:

[ 'controller_name' => 'CompanyController', ]

Y dentro del template encontramos una línea que dice:

<h1>Hello {{ controller_name }}!</h1>

Y en la vista obtenida vemos:

Titulo de la app "Hello CompanyController"

¿Coincidencia? ¡Claro que no!

El arreglo que se pasa como segundo parámetro a la llamada a render es, precisamente, un conjunto de asignaciones de variables que el template podrá utilizar como requiera.

¡Genial!

Ya sabes:

  1. Cómo crear un nuevo controlador.
  2. Cómo vincular un método a una ruta.
  3. Cómo pasar variables a un template.

Con todo esto, no falta mucho para crear la primera funcionalidad: el listado de empresas.

Acompáñame a la próxima clase donde lo veremos en detalle.