Skip to content

Commit 358f2e2

Browse files
committed
Merge pull request symfony#3180 from EmmanuelVella/redirect-trailing-slash
Add cookbook entry about url trailing slash redirect
2 parents 7b3b017 + e68d8d2 commit 358f2e2

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

cookbook/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
* :doc:`/cookbook/routing/method_parameters`
116116
* :doc:`/cookbook/routing/service_container_parameters`
117117
* :doc:`/cookbook/routing/custom_route_loader`
118+
* :doc:`/cookbook/routing/redirect_trailing_slash`
118119

119120
* :doc:`/cookbook/security/index`
120121

cookbook/routing/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ Routing
1010
method_parameters
1111
service_container_parameters
1212
custom_route_loader
13+
redirect_trailing_slash
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
.. index::
2+
single: Routing; Redirect URLs with a trailing slash
3+
4+
Redirect URLs with a Trailing Slash
5+
===================================
6+
7+
The goal of this cookbook is to demonstrate how to redirect URLs with
8+
trailing slash to the same URL without a trailing slash
9+
(for example ``/en/blog/`` to ``/en/blog``).
10+
11+
You have to create a controller that will match any URL with a trailing
12+
slash, remove the trailing slash (keeping query parameters if any) and
13+
redirect to the new URL with a 301 response status code::
14+
15+
// src/Acme/DemoBundle/Controller/RedirectingController.php
16+
namespace Acme\DemoBundle\Controller;
17+
18+
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
19+
use Symfony\Component\HttpFoundation\Request;
20+
21+
class RedirectingController extends Controller
22+
{
23+
public function removeTrailingSlashAction(Request $request)
24+
{
25+
$pathInfo = $request->getPathInfo();
26+
$requestUri = $request->getRequestUri();
27+
28+
$url = str_replace($pathInfo, rtrim($pathInfo, ' /'), $requestUri);
29+
30+
return $this->redirect($url, 301);
31+
}
32+
}
33+
34+
And after that, register this controller to be executed whenever a URL
35+
with a trailing slash is requested:
36+
37+
.. configuration-block::
38+
39+
.. code-block:: yaml
40+
41+
remove_trailing_slash:
42+
path: /{url}
43+
defaults: { _controller: AcmeDemoBundle:Redirecting:removeTrailingSlash }
44+
requirements:
45+
url: .*/$
46+
_method: GET
47+
48+
49+
.. code-block:: xml
50+
51+
<?xml version="1.0" encoding="UTF-8" ?>
52+
<routes xmlns="http://symfony.com/schema/routing">
53+
<route id="remove_trailing_slash" path="/{url}">
54+
<default key="_controller">AcmeDemoBundle:Redirecting:removeTrailingSlash</default>
55+
<requirement key="url">.*/$</requirement>
56+
<requirement key="_method">GET</requirement>
57+
</route>
58+
</routes>
59+
60+
.. code-block:: php
61+
62+
use Symfony\Component\Routing\RouteCollection;
63+
use Symfony\Component\Routing\Route;
64+
65+
$collection = new RouteCollection();
66+
$collection->add(
67+
'remove_trailing_slash',
68+
new Route(
69+
'/{url}',
70+
array(
71+
'_controller' => 'AcmeDemoBundle:Redirecting:removeTrailingSlash',
72+
),
73+
array(
74+
'url' => '.*/$',
75+
'_method' => 'GET',
76+
)
77+
)
78+
);
79+
80+
.. note::
81+
82+
Redirecting a POST request does not work well in old browsers.
83+
A 302 on a POST request will send a GET request after the
84+
redirection for legacy reasons.
85+
86+
.. caution::
87+
88+
Make sure to include this route in your routing configuration at
89+
the very end of your route listing. Otherwise, you risk to redirect
90+
Symfony2 core routes that natively do have a trailing slash.

0 commit comments

Comments
 (0)