2012-01-16 43 views
9

我有2個參數的路線:Symfony2的:使用對象來設置路由參數

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

兩個PARAMS是對象博客的性質。

我想建立一個自定義映射器(路線發生器),這樣我就可以這樣寫:

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

,而不是這樣的:

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

我很想看到這個(肯定會清理我的代碼位),但據我所知這是不可能的。 – MrGlass 2012-01-16 14:05:04

回答

7

這是我想出了最終:

我通過自己的生成器基類實現,查找'對象'參數並嘗試從該對象獲取所需的參數。

//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; 
    } 

} 

現在我可以這樣寫:從對象,並會得到所需要的參數(ID,蛞蝓):{} {路徑(博客} 'BBBundle_blog_show',{ '對象')} 。

+1

你能分享你的路線配置嗎? – drupality 2012-01-29 19:09:52

+0

你的意思是routing.yml?這與沙箱項目中的相同。 – Dziamid 2012-01-30 10:42:11

+0

我在這裏擴展了這個答案:https://gist.github.com/3226510,你現在可以傳遞對象而不是數組,即'path('route',entity)'(應該是BC) 。同樣,在檢查一個匹配鍵後,路由器將用'_'來爆炸鍵以檢查關係,即'parent_slug'將解析爲'$ object-> getParent() - > getSlug()'。 – Steve 2012-08-01 12:47:13

0

前段時間,我決定讓我感到惱火,因爲無法傳遞對象作爲路由參數。我不得不關注路線知識以及模板中的確切參數值以及其他生成這些路線的事情。

我已經爲symfony構建了這個包,它允許你使用和擴展這個能力(Symfony 2.7和更高版本)。請看看:https://github.com/iltar/http-bundle。它也可以在Packagist上作爲iltar/http-bundle使用。

這個包最好的事情是你不需要使用另一個路由器對象或生成器。它只是打開捆綁包,根據需要調整配置,如果默認設置不適合您的偏好,那麼您就可以走了。自述應該解釋一切,你需要知道,但這裏有一個片段:

舊風格:

/** 
* @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] }) }} 

新風格:

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

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