Url Symfony2通过多个可选参数动态路由到一个控制器操作
我对Symfony2还是一个新手,很难解决以下问题 我在控制器中有一个主浏览操作,其中定义了以下路由(在控制器中): 上述路由工作没有问题 问题是从细枝视图或视图帮助程序生成URL 我希望能够在视图帮助器中执行以下操作:Url Symfony2通过多个可选参数动态路由到一个控制器操作,url,symfony,routing,Url,Symfony,Routing,我对Symfony2还是一个新手,很难解决以下问题 我在控制器中有一个主浏览操作,其中定义了以下路由(在控制器中): 上述路由工作没有问题 问题是从细枝视图或视图帮助程序生成URL 我希望能够在视图帮助器中执行以下操作: {{ url('browse', {'brand': '123'}) }} 这在routing.yml中适用于以下各项: browse: pattern: /browse/b/{brand} defaults: { _controller: MyCoreBundle:
{{ url('browse', {'brand': '123'}) }}
这在routing.yml中适用于以下各项:
browse:
pattern: /browse/b/{brand}
defaults: { _controller: MyCoreBundle:Browse:browse }
browse:
pattern: /browse
defaults: { _controller: MyCoreBundle:Browse:browse }
然后我试着:
browse:
pattern: /browse/b/{brand}
pattern: /browse/c/{category}/b/{brand}
defaults: { _controller: MyCoreBundle:Browse:browse }
但似乎只有最后一种模式适用,尝试使用以下模式将抛出错误:
{{ url('browse', {'brand': '123'}) }}
我意识到我可以在routing.yml中创建多个唯一命名的单独路由。但这意味着,根据将要使用的变量,我需要指定一个不同的路由名称,这将很快变得非常混乱
我还尝试:
browse:
pattern: /browse/c/{category}/b/{brand}/{page}
defaults: { _controller: MyCoreBundle:Browse:browse }
与:
但这引发了一个错误,即类别的格式不正确
我是不是遗漏了什么?谁能给我指一下正确的方向吗?我是否需要创建一个可以接受所有变量并基于输入构造URL的细枝扩展?调试路由,您将看到每个路由注释都有一个唯一的名称
php app/console router:debug
可以使用注释中的name参数设置单个名称。看一看这个
为您的案例创建专用的细枝扩展可能是另一个解决方案。或者这可能是一个有趣的例子
编辑:您可以最小化路由,因为页面参数可以是可选的
@Route("/browse/c/{category}/{categoryName}")
@Route("/browse/c/{category}/{categoryName}/{page}")
与相同,可以双向调用
@Route("/browse/c/{category}/{categoryName}/{page}", defaults={"page" = 1})
在控制台上测试,相同的路径应该匹配
php app:console router:match /browse/c/1/foobar
php app:console router:match /browse/c/1/foobar/2
我最终创建了一个细枝扩展。这是一个冗长的过程,需要传递route_参数和query_参数,但它可以工作 因此,在我的控制器中,我需要获取路由和查询参数:
$routeParams = $this->get('request')->attributes->get('_route_params');
$queryParams = $this->get('request')->query->all();
然后传递到视图:
return array('products' => $products, 'mfdFacets' => $mfdFacets, 'routeParams' => $routeParams, 'queryParams' => $queryParams);
然后在我的browse.html.twig中,我调用一个视图帮助器并传递路由和查询参数:
{% render controller("MyCoreBundle:Helper:menumfd", {'mfdFacets': mfdFacets, 'routeParams': routeParams, 'queryParams': queryParams }) %}
然后在辅助控制器中:
/**
* @Route("/browse")
* @Route("/browse/{page}")
* @Route("/browse/c/{category}/{categoryName}")
* @Route("/browse/c/{category}/{categoryName}/{page}")
* @Route("/browse/c/{category}/b/{brand}/{page}")
* @Route("/browse/b/{brand}")
* @Route("/browse/b/{brand}/{page}")
* @Template()
*/
public function browseAction($category = 0, $page = 1, $brand = 0) {
/**
* @Route("/helper/menu/module/mfd")
* @Template()
*/
public function menumfdAction($mfdFacets, $routeParams, $queryParams) {
$manufacturers = $this->get("my.manufacturers")->makeNamedArray($mfdFacets);
return array('manufacturers' => $manufacturers, 'routeParams' => $routeParams, 'queryParams' => $queryParams);
}
然后在助手视图中:
<ul>
{% for mfd in manufacturers %}
<li><a href="{{ mybrowseroute("brand", mfd.id, "brandName", mfd.name, routeParams, queryParams) }}">{{ mfd.name | raw }} ({{ mfd.count }})</a></li>
{% endfor %}
</ul>
和在services.yml中:
services:
my.router:
class: My\Bundle\ServiceBundle\Twig\Extension\MyRouterExtension
arguments: ['@service_container']
tags:
- { name: twig.extension }
如果只希望在视图辅助对象中传递1个键值对,则可以使用:
<li><a href="{{ mybrowseroute("brand", mfd.id, '', '', routeParams, queryParams) }}">{{ mfd.name | raw }} ({{ mfd.count }})</a></li>
首先,这不是动态路由。这是具有多个模式的静态路由。有一个明显的区别
其次,您需要为每个模式创建一个专门定义的路由,每个模式都有唯一的名称。但是,您可以将page参数默认为1以使其成为可选的,从而减少定义的模式数
第三,当您需要在twig中生成这些链接时,只需使用上面定义的唯一名称以及所需的参数
最后,在上一个示例中,category是一个必需的参数,您将向它传递一个空值。这将创建“/browse/c//b/123/1”,这对于Symfony2来说是一个无效的处理路径。感谢您的建议-我在上面添加了一个解决方案-我认为它允许非常动态的参数组合。您是否可以对此进行清理并作为捆绑包发布?;)
browse:
pattern: /browse
defaults: { _controller: MyCoreBundle:Browse:browse }
services:
my.router:
class: My\Bundle\ServiceBundle\Twig\Extension\MyRouterExtension
arguments: ['@service_container']
tags:
- { name: twig.extension }
<li><a href="{{ mybrowseroute("brand", mfd.id, '', '', routeParams, queryParams) }}">{{ mfd.name | raw }} ({{ mfd.count }})</a></li>