Routes and Controllers in Drupal

Drupal's routing system and controllers define and manage URL paths and the corresponding logic to handle requests, enabling the creation of custom pages and functionality within a Drupal site.

This course covers how to map URLs to controller classes, handle dynamic parameters, set dynamic titles, and implement access control for routes. You’ll learn how to use parameter value upcasting to simplify route definitions, and how Drupal’s routing system builds on top of the Symfony framework. Additionally, you will learn about how Drupal turns an HTTP request into an HTML response.

Key topics

  • Overview of routes, controllers, and responses
  • Creating a route and controller
  • Using parameters in a route
  • Setting a dynamic title for a route
  • Adding access checking to a route
  • Overview of parameters and value upcasting in routes
  • Understanding how Drupal turns a request into a response
Tutorials in this course
More information

Do you know some PHP and want to learn how to create a custom page at a custom URL in Drupal? You're in the right place.

Every web framework has the same job: provide a way for developers to map user-accessible URLs with code that builds the page. Routes, controllers, and responses are what module developers use to create pages at custom URLs in a Drupal site.

In this tutorial, we'll:

  • Define what routes, controllers, and responses are.
  • Explain the routing workflow that Drupal uses to match a URL to a route.
  • Define routing system-related terms like parameter and upcasting.

By the end of this tutorial, you should be able to explain how a developer uses routes, controllers, and responses to create custom pages in a module.

Drupal 8, 9, and 10
More information

Before you can create a path or link to another page on your site, you'll need to know the route (unless there is already a variable available for the URL you need). Finding a route can be a tricky task unless you have the right tools. In this tutorial, we'll show how tools like Webprofiler, Drush, and Grep can be used to get route information for a page, so that you can use functions that need a route as a function parameter.

In this tutorial we'll:

  • Learn how to determine the route or path of an internal page.
Categories
Drupal 8, 9, and 10
More information

If you want to define a new URL that a user can navigate to, and custom PHP code that will generate the content of the page, you need a route and a controller. Most of the time you'll want to do something more complex than hard code the content of the page. This will require using services in your controller. This can be accomplished in different ways.

In this tutorial we'll:

  • Provide the definition for a new route which maps a path to the callback method of a controller class.
  • Create a controller that returns a hard coded string.
  • Look at examples of using both ControllerBase and dependency injection to access services from a controller, and discuss the benefits of both approaches.

By the end of this tutorial, you should be able to define a new route that maps to a controller and displays content on the page as a result of your custom logic.

More information

The routing system can get dynamic values from the URL and pass them as arguments to the controller. This means a single route with a path of /node/{node} can be used to display any node entity. Route parameters can be validated, and upcast to complex data types via parameter conversion. If you ever want to pass arguments to the controller for a route, you'll use parameters to do so.

In this tutorial we'll:

  • Define what parameters (slugs, placeholders) are and what they are used for in a route definition.
  • Explain how URL parameters are passed to a controller.
  • Define parameter upcasting.

By the end of this tutorial, you should be able to explain how to define a route that uses parameters to pass dynamic values to the route controller, and explain how parameter upcasting works.

Categories
Drupal 8, 9, and 10
More information

Let's write some code that will allow us to see route parameters in action. We'll define a new route with a path like /journey/42/full but where 42 can be any node ID, and full can be any view mode. When a user accesses the path we'll pass the dynamic parameters from the URL to the controller. The controller will then load the corresponding node and render it using the provided view mode, and return that to display on the page.

By the end of this tutorial you should be able to:

  • Use dynamic slugs in a route to pass parameters to the route controller.
  • See how Drupal will upcast a value like the node ID, 42, to a Node object automatically.
  • Explain what happens when you visit a URL that matches a route but the parameters don't pass validation.

By the end of this tutorial, you should be able to pass dynamic values from the URL to a route's controller.

More information

When defining a route and subsequently displaying the page, often we need to calculate the page title based on route parameters or other logic. In these cases, we can't just hard code the value into the _title configuration of the route. To set a dynamic title for a page, we'll use the route's _title_callback option, and point to a PHP callback that contains the logic that computes the title of the page.

In this tutorial we'll:

  • Learn how to use the _title_callback route configuration option to dynamically set a page title
  • Explain how arguments are provided to the title callback method
  • Update the route and controller from a previous tutorial to use a dynamic title callback

By the end of this tutorial, you should be able to configure a route so that its title can be set dynamically using route parameters, instead of hard-coding the title with a static string of text.

More information

If you've ever built or administered a Drupal site, the permissions page (/admin/people/permissions) is probably quite familiar.

If you're new to module development, you may wonder where these permissions come from, and how you can specify your own permissions. In this tutorial we'll answer those questions.

First, we'll look at how to define permissions from within a custom module. We'll examine techniques that enable you to provide specific (static) permissions as well as dynamic permissions, which depend on another piece of data, such as the name of a content type. By the end of this tutorial you will understand how to add both static and dynamic permissions to a custom module.

Categories
Drupal 8, 9, and 10
More information

Every route should define its access control parameters. When you define routes in a module, you can limit who has access to those routes via different access control options. Route-level access control applies to the path. If your route defines a path like /journey/example, the access control configuration will determine whether to show the current user the page at the path defined by the route, or to have Drupal serve an "HTTP 403 Access Denied" message instead.

In this tutorial we'll look at different ways of adding access control to a route including:

  • Access based on the current user's roles and permissions
  • Access based on custom logic in a callback method
  • Logic in an access checker service

By the end of this tutorial, you should be able to add access control logic to your custom routes that will meet any requirement.

More information

Every web framework, including Drupal, has basically the same job: provide a way for developers to map URLs to the code that builds the corresponding pages. Drupal uses Symfony's HTTPKernel component. Kernel events are dispatched to coordinate the following tasks:

  • Process the incoming request
  • Figure out what to put on the page
  • Create a response
  • Deliver that response to the user's browser

Knowing a bit more about how Drupal handles the request-to-response workflow will help you better understand how to use routes and controllers to create your own custom pages or deal with authentication, access checking, and error handling in a Drupal module.

In this tutorial we'll:

  • Walk through the process that Drupal uses to convert an incoming request into HTML that a browser can read
  • See how the Symfony HTTPKernel helps orchestrate this process
  • Learn about how the output from a custom controller gets incorporated into the final page

By the end of this tutorial, you should be able to describe the process that Drupal goes through to convert an incoming request for a URL into an HTML response displayed by the browser.

More information

Sometimes we need the response returned from a controller to be something other than HTML content wrapped with the rest of a Drupal theme. Maybe we need to return plain text, or JSON structured data for an application to consume. Perhaps we need greater control over the HTTP headers sent in the response. This is possible by building on the fact that controllers can return generic Response objects instead of renderable arrays, allowing you to gain complete control over what is sent to the requesting agent.

In this tutorial we'll:

  • Look at how to return a plain text response, and JSON data
  • Show how to make your responses cacheable by adding cacheability metadata
  • Learn about how to use a generic Symfony Response to gain greater control over what gets returned

By the end of this tutorial, you should be able to return responses from a controller in a Drupal module that are not HTML content wrapped in a Drupal theme.

This course appears in the following guides:
Module Development
Create custom pages and navigation in code with routes, controllers, and menu links.

Develop Custom Pages