New in Symfony 4.1: Internationalized routing
March 19, 2018 • Published by Javier Eguiluz
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Frank de Jonge
in #26143.
We recently improved the performance of the Routing component to make it the fastest PHP router available. Now, just in time for including it in Symfony 4.1, we added another amazing feature to it: support for internationalized routes.
This feature allows to define different paths for each route depending on the user locale. This feature is essential for internationalized apps and that's why third-party bundles like JMSI18nRoutingBundle have millions on downloads. In Symfony 4.1 we decided to integrate this into the routing component itself so you can use it out-of-the-box in Symfony apps.
In practice, when defining a route you can now provide an array in the path
option to define a different path per locale:
1 2 3 4 5
contact:
controller: App\Controller\ContactController::send
path:
en: /send-us-an-email
nl: /stuur-ons-een-email
This format is also supported for routes defined in XML and PHP annotations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use Symfony\Component\Routing\Annotation\Route;
class ContactController
{
/**
* @Route({
* "en": "/send-us-an-email",
* "nl": "/stuur-ons-een-email"
* }, name="contact")
*/
public function send()
{
// ...
}
}
Internally Symfony creates one route per locale (called contact.en
and
contact.nl
in this example) but you can still use the original route name to
generate URLs. When generating a URL, the request locale is used by default, but
you can pass the locale explicitly to generate any of the alternative URLs:
1 2 3 4 5 6 7 8
/** @var UrlGeneratorInterface $urlGenerator */
// uses the current request locale
$url = $urlGenerator->generate('contact');
// ignores the current request locale and generates '/stuur-ons-een-email'
$url = $urlGenerator->generate('contact', ['_locale' => 'nl']);
// this would also work, but it's not recommended:
// $url = $urlGenerator->generate('contact.nl');
The route prefix can also be translated (both in YAML/XML files and @Route
annotations defined at controller class level) and you can mix translated and
not translated paths too:
1 2 3 4 5 6 7
# config/routes/annotations.yaml
site:
resource: '../src/Controller/'
type: annotation
prefix:
en: '/site'
es: '/sitio'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class DefaultController extends Controller
{
/**
* @Route({"en": "/contact", "es": "/contacto"}, name="contact")
*/
public function contact()
{
// ...
}
/**
* @Route("/page/{slug}", name="page")
*/
public function page($slug)
{
// ...
}
}
The four resulting routes generated by Symfony will be:
Route name | Route path |
---|---|
contact.en |
/site/contact |
contact.es |
/sitio/contacto |
page.en |
/site/page/{slug} |
page.es |
/sitio/page/{slug} |
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
```
@Route({"en": "/site", "es": "/sitio"})
```