我有以下路由配置:
# Resources/config/routing.yml
AcmeBundle_article:
resource: "@AcmeBundle/Resources/config/routing/article.yml"
prefix: /article
# Resources/config/routing/article.yml
acme_article:
path: /{page}
defaults: { _controller: AcmeBundle:Article:index, page: 1 }
每当我调用$this->redirect($this->generateUrl('acme_article'))
或{{ path('acme_article') }}
时,URL都没有尾部斜杠/
,例如example.com/article
。我希望它像
example.com/article/
<=默认首页example.com/article/1
example.com/article/2
当我在没有{page}
参数的情况下更改路线时,如下
# Resources/config/routing/article.yml
acme_article:
path: /
defaults: { _controller: AcmeBundle:Article:index }
然后,按照我的预期添加尾部斜线:
example.com/article/
example.com/article/?page=1
example.com/article/?page=2
然而,我想在路由中保留{page}
,只想在没有页面参数的情况下添加尾部斜杠。是否可以在Symfony 2中进行路由?
您可以这样做:
# Resources/config/routing/article.yml
acme_article:
pattern: /{page}
defaults: { _controller: AcmeBundle:Article:index, page: 1 }
requirements:
page: ".*"
在你的控制器中:
// ArticleController.php
public function indexAction($page)
{
if (!$page) {
$page = 1;
}
}
现在您可以使用访问路线
/article # page = 1
/article/ # page = 1
/article/2 # page = 2
编辑
要保留参数的类型提示,只需在方法中添加一个check即可。示例:
// Article:index
if ($page && intval($page) < 1) {
return $this->redirect('/article/');
}
由于未设置page
,因此保留了尾部斜杠。
编辑2
下面的解决方案似乎更清洁。
# Resources/config/routing/article.yml
acme_article:
pattern: /{page}
defaults: { _controller: AcmeBundle:Article:index, page: 1 }
requirements:
page: d*
此选项允许使用尾部斜线,并且page
参数必须是一个数字(如果已设置)。
它可以解决您在URL中允许斜杠的问题,但如果您不在生成的URL末尾手动添加尾部斜杠,则不会自动重定向(我知道它不是很干净,但找不到其他选择:/)。
我一直在寻找一种使用路由配置来解决这个问题的方法,但我认为这是不可能的。然而,我通过一些调整使它发挥了作用。
(1)我在路由中添加了一个变量trailingSlash
,默认值为/
。我使用KnpPaginator进行分页。当对第一页进行分页时,默认值/
是必需的,否则URL中不会附加尾部斜杠。
acme_article:
path: /{trailingSlash}{page}
defaults: { _controller: AcmeBundle:Article:index, trailingSlash: /, page: 1 }
requirements:
trailingSlash : '/?'
(2)我在Article:index
控制器中添加了一些参数处理。如果找不到尾部斜杠,则抛出一个错误。
public function indexAction($trailingSlash = null, $page = 1)
{
$request = $this->container->get('request');
// if there is $page, $trailingSlash will be empty
if (($trailingSlash == '/' && $page >= 1) || !is_numeric($page)) {
throw new NotFoundHttpException(sprintf('No route found for "%s"', $request->getPathInfo()));
}
// ...
return $this->render('AcmeBundle:Article:index.html.twig', array(
'articles' => $articles,
'pagination' => $pagination,
'totalArticles' => $pagination->getTotalItemCount(),
'trailingSlash' => $trailingSlash
));
}
(3)我不得不在控制器和细枝中的每个URL生成中添加一个尾随斜杠。
// Controller
$this->redirect($this->generateUrl('acme_article').'/');
// Twig
{{ path('acme_article') }}/
(4)从SEO的角度来看,我强制在rel="canonical"
中为page=1
添加尾部斜线
{% block canonical %}
<!-- trailingSlash is / when page = 1 -->
<!-- trailingSlash is empty when page > 1 -->
<link rel="canonical" href="{{ url(app.request.get('_route'), app.request.get('_route_params')) }}{{ trailingSlash }}" />
{% endblock %}
它解决了这个问题,但我觉得这是一个变通办法。我们欢迎更好的解决方案。