2012-01-16 10 views
9

tengo una ruta con 2 parámetros:Symfony2: el uso de objetos para establecer parámetros de la ruta

BBBundle_blog_show: 
    pattern: /{id}/{slug} 
    defaults: { _controller: BloggerBlogBundle:Blog:show } 
    requirements: 
     _method: GET 
     id: \d+ 

Ambos params son propiedades de un objeto el blog.

me gustaría establecer un asignador de costumbre (generador de ruta), por lo que puedo escribir esto:

{{ path('BBBundle_blog_show', {'blog': blog}) }} 

en lugar de esto:

{{ path('BBBundle_blog_show', {'id':blog.id, 'slug':blog.slug) }} 
+0

Me encantaría ver esto (sin duda limpiar mi código de una poco) pero hasta donde yo sé, no es posible. – MrGlass

Respuesta

7

Esto es lo que ocurrió con eventualmente:

Implementé por clase base de generador propio que busca el parámetro 'objeto' e intenta obtener los parámetros requeridos de ese objeto.

//src/Blogger/BlogBundle/Resources/config/services.yml 
parameters:  
    router.options.generator_base_class: Blogger\BlogBundle\Routing\Generator\UrlGenerator 
//src/Blogger/BlogBundle/Routing/Generator/UrlGenerator.php 

namespace Blogger\BlogBundle\Routing\Generator; 

use Symfony\Component\Routing\Generator\UrlGenerator as BaseUrlGenerator; 

use Doctrine\Common\Util\Inflector; 

/** 
* UrlGenerator generates URL based on a set of routes. 
* 
* @api 
*/ 
class UrlGenerator extends BaseUrlGenerator 
{ 
    protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) 
    { 
     if (isset($parameters['object']) && is_object($parameters['object'])) { 
      $object = $parameters['object']; 
      $parameters = array_replace($this->context->getParameters(), $parameters); 
      $tparams = array_replace($defaults, $parameters); 
      $requiredParameters = array_diff_key(array_flip($variables), $tparams); 

      $parameters = $this->getParametersFromObject(array_flip($requiredParameters), $object); 
     } 

     return parent::doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute); 
    } 

    protected function getParametersFromObject($keys, $object) 
    { 
     $parameters = array(); 
     foreach ($keys as $key) { 
      $method = 'get' . Inflector::classify($key); 
      if (method_exists($object, $method)) { 
       $parameters[$key] = $object->$method(); 
      } 
     } 

     return $parameters; 
    } 

} 

Ahora puedo escribir: {{ruta ('BBBundle_blog_show', { 'objeto': Blog})}} parámetros y va a requeridas (ID, babosas) del objeto .

+1

¿Podría compartir la configuración de sus rutas? – drupality

+0

¿Quieres decir routing.yml? Es lo mismo que en el proyecto de la caja de arena. – Dziamid

+0

He ampliado esta respuesta aquí: https://gist.github.com/3226510, ahora puede pasar solo el objeto en lugar de una matriz, es decir, 'ruta ('ruta', entidad)' (debería ser BC) . Además, después de buscar una clave coincidente, el enrutador explotará la clave mediante '_' para verificar las relaciones, es decir,' parent_slug' se resolverá en '$ object-> getParent() -> getSlug()'. – Steve

0

Hace un tiempo, decidí que me molestaba no poder pasar objetos como parámetros de ruta. Tenía que preocuparme por el conocimiento de las rutas y los valores exactos de los parámetros dentro de las plantillas y otras cosas que generan esas rutas.

He creado este paquete para Symfony, que le permite usar y ampliar esta capacidad (Symfony 2.7 y superior). Por favor, eche un vistazo: https://github.com/iltar/http-bundle. También está disponible en Packagist como iltar/http-bundle.

Lo mejor de este paquete es que no necesita usar otro objeto o generador de enrutadores. Simplemente está activando el paquete, ajustando la configuración a sus necesidades si los valores predeterminados no funcionan para sus preferencias y está listo para comenzar. El readme debe explicar todo lo que necesita saber, pero aquí hay un fragmento:

viejo estilo:

/** 
* @Route("/profile/{user}/", name="app.view-profile") 
*/ 
public function viewProfileAction(AppUser $user); 

// php 
$router->generate('app.view-profile', ['user' => $user->getId()]); 

// twig 
{{ path('app.view-profile', { 'user': user.id }) }} 
{{ path('app.view-profile', { 'user': user.getid }) }} 
{{ path('app.view-profile', { 'user': user.getId() }) }} 
{{ path('app.view-profile', { 'user': user[id] }) }} 

nuevo estilo:

// php 
$router->generate('app.view-profile', ['user' => $user]); 

// twig 
{{ path('app.view-profile', { 'user' : user }) }} 
Cuestiones relacionadas