Skip to content

How to Define Optional Placeholders

Warning: You are browsing the documentation for Symfony 3.x, which is no longer maintained.

Read the updated version of this page for Symfony 7.1 (the current stable version).

To make things more exciting, add a new route that displays a list of all the available blog posts for this imaginary blog application:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/AppBundle/Controller/BlogController.php
use Symfony\Component\Routing\Annotation\Route;

class BlogController
{
    /**
     * @Route("/blog")
     */
    public function indexAction()
    {
        // ...
    }
    // ...
}

So far, this route is as simple as possible - it contains no placeholders and will only match the exact URL /blog. But what if you need this route to support pagination, where /blog/2 displays the second page of blog entries? Update the route to have a new {page} placeholder:

1
2
3
4
5
6
7
8
9
10
11
// src/AppBundle/Controller/BlogController.php

// ...

/**
 * @Route("/blog/{page}")
 */
public function indexAction($page)
{
    // ...
}

Like the {slug} placeholder before, the value matching {page} will be available inside your controller. Its value can be used to determine which set of blog posts to display for the given page.

But hold on! Since placeholders are required by default, this route will no longer match on /blog alone. Instead, to see page 1 of the blog, you'd need to use the URL /blog/1! Since that's no way for a rich web app to behave, modify the route to make the {page} parameter optional. This is done by including it in the defaults collection:

1
2
3
4
5
6
7
8
9
10
11
// src/AppBundle/Controller/BlogController.php

// ...

/**
 * @Route("/blog/{page}", defaults={"page"=1})
 */
public function indexAction($page)
{
    // ...
}

By adding page to the defaults key, the {page} placeholder is no longer required. The URL /blog will match this route and the value of the page parameter will be set to 1. The URL /blog/2 will also match, giving the page parameter a value of 2. Perfect.

URL Route Parameters
/blog blog {page} = 1
/blog/1 blog {page} = 1
/blog/2 blog {page} = 2

Caution

You can have more than one optional placeholder (e.g. /blog/{slug}/{page}), but everything after an optional placeholder must be optional. For example, /{page}/blog is a valid path, but page will always be required (i.e. /blog will not match this route).

Tip

Routes with optional parameters at the end will not match on requests with a trailing slash (i.e. /blog/ will not match, /blog will match).

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version