title: Routing summary: A more in depth look at how to map requests to particular controllers and actions. # Routing Routing is the process of mapping URL's to [Controller](api:SilverStripe\Control\Controller) and actions. In the introduction we defined a new custom route for our `TeamController` mapping any `teams` URL to our `TeamController`
If you're using the `cms` module with and dealing with `Page` objects then for your custom `Page Type` controllers you would extend `ContentController` or `PageController`. You don't need to define the routes value as the `cms` handles routing.
These routes by standard, go into a `routes.yml` file in your applications `_config` folder alongside your other [Configuration](../configuration) information. **mysite/_config/routes.yml** ```yml --- Name: mysiteroutes After: framework/routes#coreroutes --- SilverStripe\Control\Director: rules: 'teams//$Action/$ID/$Name': 'TeamController' 'player/': 'PlayerController' '': 'HomeController' ```
To understand the syntax for the `routes.yml` file better, read the [Configuration](../configuration) documentation.
## Parameters ```yml 'teams//$Action/$ID/$Name': 'TeamController' ``` This route has defined that any URL beginning with `team` should create, and be handled by a `TeamController` instance. It also contains 3 `parameters` or `params` for short. `$Action`, `$ID` and `$Name`. These variables are placeholders which will be filled when the user makes their request. Request parameters are available on the `HTTPRequest` object and able to be pulled out from a controller using `$this->getRequest()->param($name)`.
All Controllers have access to `$this->getRequest()` for the request object and `$this->getResponse()` for the response.
Here is what those parameters would look like for certain requests ```php // GET /teams/ print_r($this->getRequest()->params()); // Array // ( // [Action] => null // [ID] => null // [Name] => null // ) // GET /teams/players/ print_r($this->getRequest()->params()); // Array // ( // [Action] => 'players' // [ID] => null // [Name] => null // ) // GET /teams/players/1 print_r($this->getRequest()->params()); // Array // ( // [Action] => 'players' // [ID] => 1 // [Name] => null // ) ``` You can also fetch one parameter at a time. ```php // GET /teams/players/1/ echo $this->getRequest()->param('ID'); // returns '1' ``` ## URL Patterns The [RequestHandler](api:SilverStripe\Control\RequestHandler) class will parse all rules you specify against the following patterns. The most specific rule will be the one followed for the response.
A rule must always start with alphabetical ([A-Za-z]) characters or a $Variable declaration
| Pattern | Description | | ----------- | --------------- | | `$` | **Param Variable** - Starts the name of a paramater variable, it is optional to match this unless ! is used | | `!` | **Require Variable** - Placing this after a parameter variable requires data to be present for the rule to match | | `//` | **Shift Point** - Declares that only variables denoted with a $ are parsed into the $params AFTER this point in the regex | ```yml 'teams/$Action/$ID/$OtherID': 'TeamController' # /teams/ # /teams/players/ # /teams/ ``` Standard URL handler syntax. For any URL that contains 'team' this rule will match and hand over execution to the matching controller. The `TeamsController` is passed an optional action, id and other id parameters to do any more decision making. ```yml 'teams/$Action!/$ID!/': 'TeamController' ``` This does the same matching as the previous example, any URL starting with `teams` will look at this rule **but** both `$Action` and `$ID` are required. Any requests to `team/` will result in a `404` error rather than being handed off to the `TeamController`. ```yml 'admin/help//$Action/$ID: 'AdminHelp' ``` Match an url starting with `/admin/help/`, but don't include `/help/` as part of the action (the shift point is set to start parsing variables and the appropriate controller action AFTER the `//`). ## URL Handlers
You **must** use the **$url_handlers** static array described here if your URL pattern does not use the Controller class's default pattern of `$Action//$ID/$OtherID`. If you fail to do so, and your pattern has more than 2 parameters, your controller will throw the error "I can't handle sub-URLs of a *class name* object" with HTTP status 404.
In the above example the URLs were configured using the [Director](api:SilverStripe\Control\Director) rules in the **routes.yml** file. Alternatively you can specify these in your Controller class via the **$url_handlers** static array. This array is processed by the [RequestHandler](api:SilverStripe\Control\RequestHandler) at runtime once the `Controller` has been matched. This is useful when you want to provide custom actions for the mapping of `teams/*`. Say for instance we want to respond `coaches`, and `staff` to the one controller action `payroll`. **mysite/code/controllers/TeamController.php** ```php use SilverStripe\Control\Controller; class TeamController extends Controller { private static $allowed_actions = [ 'payroll' ]; private static $url_handlers = [ 'staff/$ID/$Name' => 'payroll', 'coach/$ID/$Name' => 'payroll' ]; ``` The syntax for the `$url_handlers` array users the same pattern matches as the `YAML` configuration rules. Now let’s consider a more complex example from a real project, where using **$url_handlers** is mandatory. In this example, the URLs are of the form `http://example.org/feed/go/`, followed by 5 parameters. The PHP controller class specifies the URL pattern in `$url_handlers`. Notice that it defines 5 parameters. ```php use SilverStripe\CMS\Controllers\ContentController; class FeedController extends ContentController { private static $allowed_actions = ['go']; private static $url_handlers = [ 'go/$UserName/$AuthToken/$Timestamp/$OutputType/$DeleteMode' => 'go' ]; public function go() { $this->validateUser( $this->getRequest()->param('UserName'), $this->getRequest()->param('AuthToken') ); /* more processing goes here */ } } The YAML rule, in contrast, is simple. It needs to provide only enough information for the framework to choose the desired controller. ```yml Director: rules: 'feed': 'FeedController' ``` ## Related Lessons * [Creating filtered views](https://www.silverstripe.org/learn/lessons/v4/creating-filtered-views-1) * [Controller actions / DataObjects as pages](https://www.silverstripe.org/learn/lessons/v4/controller-actions-dataobjects-as-pages-1) ## Links * [Controller](api:SilverStripe\Control\Controller) API documentation * [Director](api:SilverStripe\Control\Director) API documentation * [Example routes: framework](https://github.com/silverstripe/silverstripe-framework/blob/master/_config/routes.yml) * [Example routes: cms](https://github.com/silverstripe/silverstripe-cms/blob/master/_config/routes.yml)