Code Less in Drupal 8 with Drupal Console

Drupal Console brings a whole new developer experience (DX) to Drupal 8. This console tool is similar to Drush but has some mind-blowing features, which I cannot wait to show you in action. Although, Drupal Console is in RC stage at the moment, it performs its functions well enough.

In this tutorial, we will generate boilerplate code for Drupal 8 via command line. In some frameworks this approach can be also called scaffolding. With about five lines of custom code and a few console commands we will create a fully-functional Drupal 8 module with a field formatter that will display QR codes in fields of Link type. The module will be using a third-party service to generate QR codes of entered URLs.

To follow this tutorial and strike while the iron is hot you should have Drupal 8 installed on your local machine.

Let’s get started.

Install Drupal Console

First of all, we need to install Drupal Console following the official documentation for Linux or Windows. Alternatively, you may install it through Composer if you prefer this way.

After installing Drupal Console you should be able to list all available commands:

drupal list

Does it work? Great. Let’s move to the next step then.

Generate a module

The principle of code generation is straightforward. You open your system terminal and enter one of the Drupal Console generate commands. Then you answer questions and Drupal Console generates code according to your answers. If you’re provided with a default answer during the interactive process, you can press Enter to accept it.

The first thing we are going to generate is a module as a container for our future code.

drupal generate:module

Pay attention to the question about dependencies. Since we’re going to extend Link field we should add “link” module as a dependency.

drupal generate:module

Alright, let’s check what Drupal Console has generated for us. Open a file manager and go to modules/custom folder of your Drupal installation. You should see qrcoder folder and qrcoder.info.yml file inside of it.

The info file is a minimum requirement for any Drupal 8 module.

name: QRCoder
type: module
description: Provides a QR Code formatter for the Link field.
core: 8.x
package: Custom
dependencies:
  - link

As you probably noticed, the format of configuration and meta files has been changed to YAML in Drupal 8. This is one of the features that Symfony components brought to us.

Enable the module

Let’s enable our module through Drupal Console.

drupal module:install qrcoder

Yes, the console can do that and even more.

Generate a field formatter

To create a field formatter in Drupal 8 we need to create a class, which extends FormatterBase class. However, we should not care about the class structure. What we need to do is to run Drupal Console again.

The command that generates field formatters is:

drupal generate:plugin:fieldformatter

When you are asked about field type, please choose link type, which belongs to point 4 in our case.

drupal generate:plugin:fieldformatter

To be able to use the generated formatter we should rebuild Drupal cache.

drupal cache:rebuild all

One of the differences between Drupal 7 and Drupal 8 is that in Drupal 8 you need to rebuild your cache after any code change. Annoying, isn't it?

Create a Link field with QR Code formatter

A logical step would be to test our formatter in action. To do so we will add a Link field to the Basic page content type, which is included in the Standard Drupal profile.

Go to Home -> Administration -> Structure -> Content types -> Page -> Manage fields
(admin/structure/types/manage/page/fields)

And press Add field button to create a LInk field called QR Code URL with the following settings:

create qr code url field

Leave field values of the next couple of steps by default or change them if you wish.

After finishing with the field creation wizard, you should see QR Code URL field in the list of fields of the Basic page content type.

created qr code url field

Then go to Manage display tab of the Basic page content type settings
(admin/structure/types/manage/page/display) and set QR Code display format for our newly created QR Code URL field.

display set to qr code

It is time to create a page and test the settings. To do that, go to Home -> Administration -> Content (admin/content) and press Add content button.

Then choose Basic page, enter values for required fields and the QR Code URL field. The QR Code URL can be absolute or relative.

create page

After that, press Save and publish to create the page. At this stage, the resulting page node should look like the following:

created page

The link is not displayed because our field formatter is not ready yet.

Modify the field formatter

Let’s teach the formatter how to render URLs as QR codes. We will make some amendments to the QRCodeLinkFieldFormatter class for that. You may find the class in the module/custom/qrcoder/src/Plugin/Field/FieldFormatter folder.

A service called QR Code Generator will assist us with rendering QR codes. We just need to add QR code image hosted externally to the output of our formatter.

The source of the image ought to be:

https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=[URL]

where [URL] is the entered QR Code URL.

Now find viewElements() in the QRCodeLinkFieldFormatter class and replace:

      $elements[$delta] = ['#markup' => $this->viewValue($item)];

with

      // Get a URL from the field and make it absolute.
      $url = $item->getUrl()->setAbsolute(TRUE)->toString();
      // Just in case, sanitize entered URL.
      $url =  UrlHelper::filterBadProtocol($url);
      // Use image theme function to render a QR code image for the URL.
      $elements[$delta] = [
        '#theme' => 'image',
        '#uri' => 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' . $url,
      ];

Also, don't forget to add a use statement for UrlHelper to the top of the file after namespace:

use Drupal\Component\Utility\UrlHelper;

Additionally, you might want to remove unused methods from the plugin class, such as viewValue(), defaultSettings(), settingsForm() and settingsSummary(). (Special thanks to @NickWilde1990 who suggested these improvements on Github)

Clear cache once again and refresh the test page, which we created on previous step.

page after formatter modification

Now the page contains the anticipated QR code. Hooray! We’ve done it.

You may find QRCoder module on Github. From author's point of view their code can look ideal until it’s reviewed by their peer, so I encourage you to take a look at the code and suggest improvements.

If you’d like to exercise more with Drupal Console, you may create a block plugin to display QR codes in blocks. The command is:

drupal generate:plugin:block

The custom code you need to write for the block plugin should be quite similar to the custom code of our field formatter.

Conclusions

Drush has always been my favorite console toy and I still use it a lot. On the other hand, I’m surprised by code generation features of Drupal Console. I believe one day the authors will remember about “collaboration over competition” principle and merge these two great tools, so that we had one kind of magic wand for all Drupal wizards.

To sum up, you can see that the development workflow in Drupal 8 has changed compared to previous versions of Drupal. Thanks to Drupal Console, now you can save time on writing boilerplate code and focus on business logic of your application.