New in Symfony 4.3: Always Include Route Default Values
January 2, 2019 • 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
Vladimir Luchaninov
in #29599.
In Symfony applications, you can give route placeholders a default value so
they can be omitted when generating the URL. Moreover, if the placeholder is at
the end of the route path, it will be removed entirely from the generated URL.
Consider this route definition where the page
route placeholder is at the
end of the route path and provides a default value via the method argument:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
class BlogController extends AbstractController
{
/**
* @Route("/blog/{page}", name="blog_list")
*/
public function list($page = 1)
{
// ...
}
}
If you don't provide the value of the page
variable when generating the URL
for the blog_list
route, the resulting URL will be /blog
and the value
of the page
placeholder will be 1
:
1 2 3 4 5
$router = ... // a UrlGeneratorInterface instance
$url = $router->generate('blog_list'); // $url = '/blog'
$url = $router->generate('blog_list', ['page' => 1]); // $url = '/blog/1'
$url = $router->generate('blog_list', ['page' => 7]); // $url = '/blog/7'
Although this is the desired behavior in most applications, sometimes you may prefer to always include the value of the placeholder, even when you don't provide it while generating the URL. In Symfony 4.3 we made this possible with a new syntax for route placeholders:
1 2 3 4 5 6 7
/**
* @Route("/blog/{!page}", name="blog_list")
*/
public function list($page = 1)
{
// ...
}
The !
character before the placeholder name tells Symfony to always include
its value in the generated URL, no matter if it's a default value:
1 2 3
$url = $router->generate('blog_list'); // $url = '/blog/1'
$url = $router->generate('blog_list', ['page' => 1]); // $url = '/blog/1'
$url = $router->generate('blog_list', ['page' => 7]); // $url = '/blog/7'
This new feature is also useful to always display the value of the special
_format
routing parameter. This allows for example to display the html
extension for all pages in a web application that supports multiple formats:
1 2 3 4 5 6 7
/**
* @Route("/blog/{page}.{!_format<html|json>?html}", name="blog_list")
*/
public function list($page = 1)
{
// ...
}
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.
In case to be more readable, it can be done by using old syntax?
Kind of:
default={"!page": "1"}
or smth longer:
always_include_route_default_values={"page"}
@Route("/blog/{!page?1}", name="blog_list")
But new "!" doesn't.
I think, if there are lots of placeholders, requirements and defaults, it would be difficult to understand at a glance how it all interacts.
e.g. last code block
https://symfony.com/blog/new-in-symfony-4-1-inlined-routing-configuration