Tutorial Jobeet con Symfony2 Día 5: Routing

De WikiSalud
Saltar a: navegación, buscar
Este artículo es parte del proyecto Tutorial Jobeet con Symfony2

Contenido

URLs

Si haces clich en una oferta de trabajo de la página principal de Jobeet, la URL luce como esto: /job/1/show. Si ya has desarrolado sitios con php, probablemente estés acostumbrado más a URL como /job.php?id=1. ¿Como hace Symfony que funcione? ¿Como determina Symfony la acción a llamar basado en esta URL? ¿Por qué esta el id de la oferta de trabajo se obtiene con el parametro $id del controlador? Aquí responderemos todas estas interrogantes.

Ya has visto el siguiente código en la plantilla src/Ens/JobeetBundle/Resources/views/Job/index.html.twig

{{ path('job_show', { 'id': entity.id }) }}

Este código usa la función helper path template para generar la URL del trabajo que tenga el id 1. El job_show es el nombre de la ruta usada, definida en la configuración que se verá más adelante.

Configuración de Routing

En Symfony2, la configuración de Routing se encuentra hace generalmente en app/config/routing.yml. Este archivo importa configuraciones de routing especificas del bundle. En nuestro caso, es importado el fichero src/Ens/JobeetBundle/Resources/config/routing.yml

app/config/routing.yml
# app/config/routing.yml
 
EnsJobeetBundle:
    resource: "@EnsJobeetBundle/Resources/config/routing.yml"
    prefix:   /

Ahora, si miras en el JobeetBundle routing.yml, verás que importa otra archivo de routing, el archivo para el controlador Job y define una ruta llamada EnsJobeetBundle_homepage para el patrón URL /hello/{name}

src/Ens/JobeetBundle/Resources/config/routing.yml
# src/Ens/JobeetBundle/Resources/config/routing.yml
 
EnsJobeetBundle_job:
    resource: "@EnsJobeetBundle/Resources/config/routing/job.yml"
    prefix: /job
 
EnsJobeetBundle_homepage:
    pattern:  /hello/{name}
    defaults: { _controller: EnsJobeetBundle:Default:index }
src/Ens/JobeetBundle/Resources/config/routing/job.yml
# src/Ens/JobeetBundle/Resources/config/routing/job.yml
 
job:
    pattern:  /
    defaults: { _controller: "EnsJobeetBundle:Job:index" }
 
job_show:
    pattern:  /{id}/show
    defaults: { _controller: "EnsJobeetBundle:Job:show" }
 
job_new:
    pattern:  /new
    defaults: { _controller: "EnsJobeetBundle:Job:new" }
 
job_create:
    pattern:  /create
    defaults: { _controller: "EnsJobeetBundle:Job:create" }
    requirements: { _method: post }
 
job_edit:
    pattern:  /{id}/edit
    defaults: { _controller: "EnsJobeetBundle:Job:edit" }
 
job_update:
    pattern:  /{id}/update
    defaults: { _controller: "EnsJobeetBundle:Job:update" }
    requirements: { _method: post }
 
job_delete:
    pattern:  /{id}/delete
    defaults: { _controller: "EnsJobeetBundle:Job:delete" }
    requirements: { _method: post }

Demos un vistazo más de cerca a la ruta ens_job_show. El patrón definido por la ruta ens_job_show actua como /*/show donde la máscara es dada por el id. Para la URL /1/show, la variable id obtiene un valor de 1, el cuál es disponible para que lo uses en tu controlador. El _controller parameter es una llave especial que le dice a Symfony que controller/action debería se ejecutada cuando una URL coíncide con esta ruta, en nuestro caso debe ejecutar showAction del controlador JobController en el bundle EnsJobeetBundle

Los parametos de ruta ({id} por ejemplo) son especilamente importantes porque cada uno es disponible como una argumento al metodo controlador:

public function showAction($id)
{
    // ...
}

Configuración de rutas en ambientes de desarrollo

El ambiente de desarrollo carga el archivo app/config/routing_dev.yml que contiene las rutas usadas por el Web Debug Toolbar, entre otros. Este archivo carga, hacia el final, el archivo principal de configuración de rutas routing.yml Si vas a http://<dominio>/app_dev.php en tu navegador, verás la página por defecto de Symfony. Vamos a cambiar eso, para que el entorno de desarrollo muestre las mismas páginas tanto en producción como en el futuro. Abre tu archivo app/config/routing_dev.yml y remueve las rutas sobre los bundles incluidos, en nuestro caso Acme. Ahora el routing_dev.yml debe lucir de esta forma:

app/config/routing_dev.yml
# app/config/routing_dev.yml
 
_assetic:
    resource: .
    type:     assetic
 
_wdt:
    resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml"
    prefix:   /_wdt
 
_profiler:
    resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml"
    prefix:   /_profiler
 
_configurator:
    resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml"
    prefix:   /_configurator
 
_main:
    resource: routing.yml

No olvides limpiar tu caché después de estas modificaciones

Personalización de las rutas

Por ahora, cuando solicitas la URL / en un navegador, obtendrás un error 404 Not Found. Esto se debe a que esta URL no coincide con ninguna ruta definida. Tenemos una ruta EnsJobeetBundle_homepage que coincide con la URL /hello/jobeet y nos envía la acción index DefaultController. Vamos a cambiarlo para que coincida la URL / y llame a la acción índex del JobController. Para hacer los cambios, lo modificaremos agregando la siguiente ruta en el archivo src/Ens/JobeetBundle/Resources/config/routing.yml

src/Ens/JobeetBundle/Resources/config/routing.yml
# src/Ens/JobeetBundle/Resources/config/routing.yml
# ...
 
EnsJobeetBundle_homepage:
    pattern:  /
    defaults: { _controller: EnsJobeetBundle:Job:index }

Ahora, si limpias la caché y vas a http://jobeet.local en tu navegador, verás la Página de inicio de Job. Ahora podemos cambiar el enlace del logo Jobeet en el layout para usar la ruta EnsJobeetBundle_homepage:

src/Ens/JobeetBundle/Resources/views/layout.html.twig
<!-- src/Ens/JobeetBundle/Resources/views/layout.html.twig -->
<!-- ... -->
<h1><a href="{{ path('EnsJobeetBundle_homepage') }}">
  <img src="{{ asset('bundles/ensjobeet/images/logo.jpg') }}" alt="Jobeet Job Board" />
</a></h1>
<!-- ... -->

Para algo más comprometido, cambiaremos la URL page de Job a algo más significativo:

/job/sensio-labs/paris-france/1/web-developer

Sin saber nada sobre Jobeet, y sin ver la página, puedes entender de la URL que Sensio Labs esta buscando a Desarrolador Web para trabajar en París, Francia El siguiente patrón coincide con tal URL:

/job/{company}/{location}/{id}/{position}


Edita la ruta job_show de archivo job.yml

src/Ens/JobeetBundle/Resources/config/routing/job.yml
# src/Ens/JobeetBundle/Resources/config/routing/job.yml
# ...
 
job_show:
    pattern:  /{company}/{location}/{id}/{position}
    defaults: { _controller: "EnsJobeetBundle:Job:show" }

Ahora, necesitamos pasar todos los parametros para que la ruta cambiada trabaje.

src/Ens/JobeetBundle/Resources/views/Job/index.html.twig
<!-- src/Ens/JobeetBundle/Resources/views/Job/index.html.twig -->
<!-- ... -->
<a href="{{ path('job_show', { 'id': entity.id, 'company': entity.company, 'location': entity.location, 'position': entity.position }) }}">
  {{ entity.position }}
</a>
<!-- ... -->

Si echas un vistazo a las URLs generadas, no son todavía tan amigables como queremos que sean:

http://<dominio>/job/Sensio Labs/Paris, France/1/Web Developer

Necesitamos "slugify " los valores de la columna reemplazando todos los caracteres no ASCII por un -. Abre el archivo Job.php y añade los siguientes métodos a la clase

src/Ens/JobeetBundle/Entity/Job.php
// src/Ens/JobeetBundle/Entity/Job.php
// ...
 
use Ens\JobeetBundle\Utils\Jobeet as Jobeet;
class Job
{
    // ...
    public function getCompanySlug()
    {
        return Jobeet::slugify($this->getCompany());
    }
 
    public function getPositionSlug()
    {
        return Jobeet::slugify($this->getPosition());
    }
 
    public function getLocationSlug()
    {
        return Jobeet::slugify($this->getLocation());
    }
}

Luego, crea el archivo src/Ens/JobeetBundle/Utils/Jobeet.php, y añade el método slugify en el

src/Ens/JobeetBundle/Utils/Jobeet.php
// src/Ens/JobeetBundle/Utils/Jobeet.php
 
namespace Ens\JobeetBundle\Utils;
class Jobeet
{
    static public function slugify($text)
    {
        // replace all non letters or digits by -
        $text = preg_replace('/\W+/', '-', $text);
 
        // trim and lowercase
        $text = strtolower(trim($text, '-'));
 
        return $text;
    }
}

Tenemos definidos tres nuevos métodos virtuales: getCompanySlug(), getPositionSlug(), and getLocationSlug(). Retornan su correspondiente valor de columna después de aplicarle el método slugify. Ahora, puedes reemplazar el nombre real de las columnas por estos virtuales con esta plantilla:

src/Ens/JobeetBundle/Resources/views/Job/index.html.twig
<!-- src/Ens/JobeetBundle/Resources/views/Job/index.html.twig -->
<!-- ... -->
<a href="{{ path('job_show', { 'id': entity.id, 'company': entity.companyslug, 'location': entity.locationslug, 'position': entity.positionslug}) }}">
  {{ entity.position }}
</a>
<!-- ... -->

Ahora tenemos las URL esperadas

http://jobeet.local/app_dev.php/job/sensio-labs/paris-france/1/web-developer

Requisitos para rutas

El sistemas de rutas tiene caracteristicas de validacion incorporadas. Cada patrón variable puede ser validado por una expresión regular definida usando la entrada requirements de una definifición de rutas

src/Ens/JobeetBundle/Resources/config/routing/job.yml
# src/Ens/JobeetBundle/Resources/config/routing/job.yml
# ...
 
job_show:
    pattern:  /{company}/{location}/{id}/{position}
    defaults: { _controller: "EnsJobeetBundle:Job:show" }
    requirements:
        id:  \d+

Los entrada requirements fuerza al id a ser un valor númerico. Si no lo es, la ruta no coincide

Depuración de Rutas

Mientras añadimos y personalizamos rutas, es útil ser capaz de visualizar y obtener información detallada sobre tus rutas. A gran forma para ver cada rutas en tu aplicación es por medio del comando de consola router:debug. Ejecuta el comando corriendo lo siguiente desde la raíz de tu aplicación:

php app/console router:debug

El comando imprimirá una lista útil de todas las rutas configuradas en tu aplicación. También puedes obtener información muy específica en una sola ruta incluyendo el nombre de la ruta después del comando:

php app/console router:debug job_show
Herramientas personales
Espacios de nombres

Variantes
Acciones
Navegación
Herramientas