4.3.1: Controllers and routes - Overview
4.3: A new page
What we've done so far is manipulate content on an existing page. We now need to create a page that doesn't currently exist, so it's time to talk about controllers and routes.
Technical Blueprint: “Export Details” should link to a dedicated “Order Export Details” page for a specific order in My Account.
Controllers and routes
Controllers are the "C" in the common MVC (Model-View-Controller) design pattern. A controller is a PHP class that tells
the application what to do with a request and what output (if any) to render. In Magento, the existence of controllers
must be registered with a URL pattern to match, using a routes.xml
file.
routes.xml
The nature of our "Export Details" page makes considering a new controller in the existing sales
route a legitimate
option. But let's practice creating a route of our own. Create the file etc/frontend/routes.xml
in the
SwiftOtter_OrderExport
module. (Naturally, this is a config file that affects only the frontend
area.)
You can use any number of existing routes.xml
files as a reference for the schema definition. What we need to define our router
is basic:
<router id="standard">
<route id="order_export" frontName="order_export">
<module name="SwiftOtter_OrderExport" />
</route>
</router>
What this tells Magento when it loads and processes all routes files is, essentially, "When a request is received with
'order_export' as the first URL segment (frontName
), look for a controller matching the rest of the path in the
Controller
directory of SwiftOtter_Export
(<module>
)." The id
attribute simply needs to be unique, but if we want
to keep our sanity, we'll make it the same as frontName
. This is nested under the standard
router because the pattern
of the URL path and the controller file we will create follows the normal pattern. (There are other routers with different
logic, such as one for web API requests.)
Mapping a request to a controller
So Magento finds the correct module to handle a request by matching the first URL segment to the frontName
of a router.
Where does it go from there?
Typical URL paths have two further segments after frontName
. The right controller class is found by mapping those two
segments to the class name, starting after Controller
. We're trying to create a controller to respond to this URL path:
order_export/view/index
The URL segments after the "front name" (view
and index
) thus tell us we should create the class
SwiftOtter\OrderExport\Controller\View\Index
.
Believe it or not, there is no base or abstract class a controller must extend. But it must implement
Magento\Framework\App\ActionInterface
. It's also advisable to implement the appropriate interface for the HTTP request
type this controller expects, which Magento will enforce. In this case, it is
Magento\Framework\App\Action\HttpGetActionInterface
.
ActionInterface
requires one method, execute
, which does not require any parameters. We'll soon look at what execute
is expected to return, but if you'd like to at least see your handiwork in action, try a good ol' echo
and die
for now!