我有以下路由配置:
# 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') }}
时,网址都不会跟踪斜杠/
,例如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}
,只想在没有page参数时添加尾部斜杠。是否可以在Symfony 2路由中进行?
答案 0 :(得分: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
修改强>
要保留参数的类型提示,只需在方法中添加一个检查。例如:
// 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 :(得分:1)
我一直在寻找一种可以使用路由配置解决这个问题的方法,但我认为这是不可能的。但是我通过一些调整得到了它。
(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 %}
它修复了问题,但我觉得这是一个解决方法。欢迎提供更好的解决方案。