What we’ll cover
- What are controller actions, and how are they used?
- Create a controller action to render a DataObject
- Rendering a DataObject as a page
- Adding pseudo-page behaviour to a DataObject
How controller actions work
Up to this point in our project, for the most part, every page has been on a single URL, which that URL points to a single controller, which renders a single
$Layout template. However, if you think back to our lesson on forms, you may remember that we were able to extend the URL route for our controller in order to generate and render a form. We did this using a controller action. Forms are just one of many use cases for a controller action.
Using controller actions is simple. All we’re talking about is appending a URL part to an existing URL that matches the name of a publicly accessible method on the controller. Let’s give it a try.
For this example, we’re going to look at our Regions page. You’ll see that it resolves to
http://[your base url]/regions. Try appending a new segment to the URL, like
http://[your base url]/regions/test. Not surprisingly, we get a 404.
Breaking down the request
The reason why we get a 404 might surprise you. Let’s take a look behind the scenes and see how SilverStripe is resolving this. Using the same URL, append
Let’s take a look at what’s going on here.
Testing '$Action//$ID/$OtherID' with 'test' on RegionsPage_Controller
Right out of the gate, we can see that SilverStripe resolved our URL to
RegionsPage_Controller, which may come as a surprise, since the URL for this page does not include
/test/, but what has happened is that the request handler has found a match for the URL and will assume that from this point forward, everything in the URL is a parameter being passed to the controller. By default, a controller gives you three extra parameters to pass beyond its base url, as we can see in our debug output.
$Action: Immediately follows the URL. In this case our action is
$ID: An ID that the controller action may want to use. This value does not have to be numeric. It’s arbitrary, and just named
IDbecause that’s a common use case.
$OtherID: Same as
ID. You get two.
You’re not limited to this signature of parameters. In future lessons, we’ll look at creating custom URL rules, but by default, this is what you get, and it’s often all you need.
Let’s look at the next line of debug output.
Rule '$Action//$ID/$OtherID' matched to action 'handleAction' on RegionsPage_Controller. Latest request params: array ( 'Action' => 'test', 'ID' => NULL, 'OtherID' => NULL, )
So here we are. The request handler actually did match the
$Action/$ID/$OtherID pattern, and it’s trying to resolve our action,
test. In the rest of the output, you can see that it fails to do that, and it renders an ErrorPage.
Why did it fail? As we said before, the
$Action parameter should represent a publicly accessible function on the controller. We have no method called
test right now.
Let’s add that controller method now.