2012-01-16 31 views
9

Tôi có một con đường với 2 tham số:Symfony2: đối tượng sử dụng để thiết lập các thông số tuyến đường

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

Cả params là tài sản của một đối tượng blog của.

tôi muốn thiết lập một mapper tùy chỉnh (máy phát điện tuyến đường), vì vậy mà tôi có thể viết này:

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

thay vì điều này:

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

Tôi rất thích nhìn thấy này (chắc chắn sẽ làm sạch mã một của tôi bit) nhưng theo như tôi biết thì không thể. – MrGlass

Trả lời

7

Đây là những gì tôi đã đưa ra cuối cùng:

Tôi đã triển khai bởi lớp cơ sở của trình tạo riêng để tìm tham số 'đối tượng' và cố gắng lấy thông số bắt buộc từ đối tượng đó.

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

} 

Bây giờ tôi có thể viết: {{path ('BBBundle_blog_show', { 'đối tượng': blog})}} thông số và nó sẽ được yêu cầu (id, sên) từ đối tượng .

+1

Bạn có thể chia sẻ cấu hình tuyến đường của mình không? – drupality

+0

Bạn có nghĩa là routing.yml? Nó giống như trong dự án sandbox. – Dziamid

+0

Tôi đã mở rộng câu trả lời này ở đây: https://gist.github.com/3226510, bây giờ bạn có thể vượt qua chỉ đối tượng thông qua thay vì một mảng tức là 'path ('route', entity)' (nên là BC) . Ngoài ra, sau khi kiểm tra khóa khớp, router sẽ phát nổ khóa bằng '_' để kiểm tra các mối quan hệ, nghĩa là' parent_slug' sẽ giải quyết thành '$ object-> getParent() -> getSlug()'. – Steve

0

Một thời gian trước đây, tôi đã quyết định tôi đã bực mình vì không thể chuyển đối tượng dưới dạng tham số tuyến đường. Tôi đã phải quan tâm bản thân mình với kiến ​​thức về các tuyến đường và các giá trị tham số chính xác trong các mẫu và những thứ khác tạo ra các tuyến đường đó.

Tôi đã tạo gói này cho symfony, cho phép bạn sử dụng và mở rộng khả năng này (Symfony 2.7 trở lên). Xin hãy xem: https://github.com/iltar/http-bundle. Nó cũng có sẵn trên Packagist như iltar/http-bundle.

Điều tốt nhất về gói này là bạn không cần phải sử dụng một đối tượng hoặc trình tạo bộ định tuyến khác. Nó chỉ bật gói, điều chỉnh cấu hình theo nhu cầu của bạn nếu các cài đặt mặc định không hoạt động cho các tùy chọn của bạn và bạn nên sử dụng. Readme nên giải thích tất cả mọi thứ bạn cần biết nhưng đây là một đoạn:

Cũ phong cách:

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

phong cách mới:

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

// twig 
{{ path('app.view-profile', { 'user' : user }) }} 
Các vấn đề liên quan