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!

SEE THE CODE

Complete and Continue