Two weeks ago I wrote about routes and controllers in the introduction to namespaces. This week we are going to take a much closer look at routes and controllers. 

If you missed out on the namespace introduction, check it out here: A gentle introduction to namespaces.

So, what exactly is a route and a controller?

When you create a custom page in Drupal with code, you need both a route and a controller. You define the URL for the page with the route. And then you create a controller for that page. This will be responsible for building and returning the content for the page.

Routes

A route determines which code should be run to generate the response when a URI is requested. It does this by mapping a URI to a controller class and method. This defines how Drupal deals with a specific URI.

Routes are stored in a YAML file (check out last week’s tutorials on YAML files) in the root of the module and use the following naming convention:

modulename.routing.yml

Here is the example from the namespace tutorial:

hello.content:
  path: '/hello'
  defaults:
    _controller: 'Drupal\hello\Controller\HelloController::content'
    _title: 'Hello world'
  requirements:
    _permission: 'access content'

The name of the route is hello.content. The path is /hello, which is the registered URL path. So when a user enters sitename.com/hello, this route will decide which code should be run to generate a response.

We then have two default configurations specified, the controller and the title.

The controller tells Drupal which method to call when someone goes to the URL for the page (which is defined in the route).

Let’s take a closer look at the path included in _controller.

'Drupal\hello\Controller\FirstController::content’

This comprises of a namespaces class, a double colon and then the method to call.

Drupal route with a namespace, class and method

The title is the default page title. So when a user goes to /hello, the page title will be ‘Hello world’.

Route title maps to the page title

Controllers

Controllers take requests or information from the user and decide how to handle the request. For this module, the controller is responsible generating the content (the ‘Hello world’ message) and returning it for the page.

A controller that returns a simple Hello world message looks like this:

<?php
/**
 * @file
 * Contains \Drupal\hello\Controller\HelloController.
 */
namespace Drupal\hello\Controller;

use Drupal\Core\Controller\ControllerBase;

class HelloController extends ControllerBase {
  public function content() {
    return array(
      '#type' => 'markup',
      '#markup' => t('Hello world'),
    );
  }
}

The controller is returning a renderable array with “Hello world”. So if you hit /hello once all this is in place, you will get a Drupal page with a Hello world message.

Drupal 8 controller content method maps to content on the page

Drupal 8 module route and controller

The controller lives in a Controller directory within the the src directory of a module.

The controller class in the src controller directory

Putting all of this together

To see this in action, you’re going to combine this all in a new module.

  1. In the /module directory, create a directory called hello
  2. Create hello.info.yml in the root of the hello directory
  3. Add the following to hello.info.yml:
name: Hello
description: An experimental module to build our first Drupal 8 module
package: Custom
type: module
version: 1.0
core: 8.x
  1. Create a directory inside the hello module directory called src, which is short for source
  2. Create a directory within src called Controller
  3. Within the Controller directory, create a file called HelloController.php
  4. Add the following to HelloController.php:
<?php
/**
 * @file
 * Contains \Drupal\hello\Controller\HelloController.
 */
namespace Drupal\hello\Controller;

use Drupal\Core\Controller\ControllerBase;

class HelloController extends ControllerBase {
  public function content() {
    return array(
      '#type' => 'markup',
      '#markup' => t('Hello world'),
    );
  }
}
  1. Create a file called hello.routing.yml in the root of the hello module directory
  2. Add the following code to hello.routing.yml:
hello.content:
  path: '/hello'
  defaults:
    _controller: 'Drupal\hello\Controller\HelloController::content'
    _title: 'Hello world'
  requirements:
    _permission: 'access content'
  1. Enable the hello module
  2. Visit /hello to see the Hello world message

It is good practice to complete these steps manually when you are first learning the concepts in Drupal 8 development, but you can save time by using the Drupal Console to create most of the code in the above steps. To find out how, check out my 7 day email course on the Drupal Console.