A path like /examples/page-example/simple only ever matches that one exact URL. But most real pages need to react to something in the URL itself — a user ID, a node number, a search term. Rather than writing a separate route for every possible value, Drupal lets you carve out a placeholder in the path and hand whatever the visitor typed straight to your controller as a real PHP argument.
What you'll learn in this lesson
- How curly-brace placeholders in a
pathcapture part of the URL - How placeholder names map directly onto your controller method's parameters
- What happens when a visitor requests a URL that doesn't match any defined path
A route with dynamic segments
Here's a real route from Drupal's Examples module that accepts two values straight from the URL:
page_example.arguments:
path: '/examples/page-example/arguments/{first}/{second}'
defaults:
_controller: '\Drupal\page_example\Controller\PageExampleController::arguments'
requirements:
_permission: 'access arguments page'
Visiting /examples/page-example/arguments/5/10 matches this route, with {first} capturing 5 and {second} capturing 10.
The placeholder names must match your method's parameter names
public function arguments($first, $second) {
// $first is '5', $second is '10'.
}
This is the detail that trips people up the first time: {first} and {second} in the YAML aren't arbitrary labels — Drupal's routing system matches them by name to the parameters of your controller method. Name a placeholder {uid} in the path and your method needs a $uid parameter to receive it, in whatever position it appears.
What if the URL doesn't match anything?
If a visitor requests a path that doesn't correspond to any defined route — with or without placeholders — Drupal returns a standard 404 page. There's no partial matching: either every static segment lines up and every placeholder has a value, or the route simply isn't considered a match.
/. If you need to capture something that might contain slashes, you need a different approach entirely (a wildcard route or query parameters), not a bigger placeholder.Quick check: your route path is
/report/{year}/{month}and your controller method is declared aspublic function report($month, $year)— parameter order reversed from the path. Does this still work? Yes — Drupal matches placeholders to parameters by name, not by position, so$yearand$monthstill receive the correct values regardless of which order they're declared in.
Key takeaways
- Curly braces in a
path(like{first}) mark a dynamic segment that Drupal captures from the URL. - Placeholder names must exactly match the corresponding parameter names in your controller method — matching is by name, not position.
- Each placeholder captures exactly one URL segment; it can never contain a literal
/. - A URL that doesn't match any route's static text and placeholders returns a standard 404 — there's no fuzzy matching.
Coming up next
Capturing a value from the URL is only half the story — often you also need to validate or constrain what that value can be before your controller ever runs. The next lesson, Defining Route Requirements, covers exactly that.