fromJune 2014

Touring Drupal

Contextual help to the rescue

Alphabet Help Drupal 8 has been all about pushing the boundaries, so why should help content be any different?

With the release of Drupal 8, we will also ship with tools to complement hook_help() entries: if you, the developer, are providing a documentation page for your module, why not also provide an interactive step by step guide on how your module works as well?

The idea of Tour isn’t a new one; it has been maturing over the past two years. It all began after the release of Drupal 7 when we decided to move the help passage from the front page to the help page. This meant that users new to Drupal would not see this text, and would have to struggle through with no guidance.

In light of that issue, the below was suggested;

How about creating a “Welcome” message that pops up in an overlay with that same information that continues to appear until either the user checks a box on the overlay saying to dismiss it or the user creates a piece of content on the site?
- Vegantriathlete, August 10, 2011

With tour.module committed to Drupal 8 core, we now have context-sensitive guided tours for Drupal’s complex interfaces, and developers have a new way to communicate with the user. It doesn’t stop at core either: contrib modules can ship with tours to describe how users can take full advantage of their modules. Distributions can also ship with tours on how to get started. Imagine a tour in the Commerce distribution that took the user through setting up products: That would be amazing! It would enable users to discover the pages they are looking for and take the guesswork out of finding pages.

How do I Take Tours?

Tours can be initiated with a toggle which appears on the top right corner of a page. The toggle integrates with the new toolbar developed by the Spark team and is visible on those pages that contain tours. As of this writing, there is no standard way to find a listing of all tours, but it’s my belief that we, as a community, have reached a consensus that all tours will be listed on the help page – the same page where all help module content can be found as well. We are working very hard to get this committed to core (and might already be committed as you read this article). For more information on this work the issue can be found here

Creating a Tour

To be able to write tour content, you will first need to learn two terms. The first is tip: what we call each of the steps in the tour. Generally, a tip is a small item of content, like a string – no more than two sentences that describe the item it is contextually referencing. The second term is tip type, which references the communication medium of the tip. That could be anything from a basic “title and body” type to a “YouTube video” type. This ability is due to the power of Drupal 8 and its plugin system, which streamlines architecting a module and keeping it very extendable for others.

So now that you know the basic terminology, let’s create a tour with a single tip as part of the tour. Tours are defined in YAML format and are stored in the config directory within the appropriate module. We’ll create a file tour.tour.submission-form.yml in the directory yourmodule/config/ which contains the following:

id: submission-form
label: Registration page
langcode: en
  - route_name: user.register
    id: field-first-name
    plugin: text
    label: "First name"
    body: "This is where you enter your first name."
    weight: "1"
      data-id: field-first-name

In the example above we created a tour with a single tip called “Registration page”. When the user clicks the toggle to enable the tour, a tip will be placed over the #field-first-name element of the page and show the text “This is where you enter your first name”. The tour tip type of “text” will ship with Drupal 8.

But what if you want different tip types?

We extend!

Let’s create a YouTube tip type that will accept a video ID and render that clip inside of a tour tip. That can be done by placing the following code in the file lib/Drupal/<name of module>/Plugin/tour/tip/<class name>.php:

* @file
* Contains \Drupal\tour_youtube\Plugin\tour\tip\TipPluginYoutube.
namespace Drupal\tour_youtube\Plugin\tour\tip;
use Drupal\tour\TipPluginBase;
* Displays a youtube video as a tip.
* @Tip(
*   id = "youtube",
*   title = @Translation("Youtube")
* )
class TipPluginYoutube extends TipPluginBase {
  * The ID which is used for the youtube tip.
  * @var string
  *   The ID of the youtube video.
  protected $youtube_id;
  * Overrides \Drupal\tour\Plugin\tour\tour\TipPluginInterface::getOutput().
  public function getOutput() {
    $output = '<h2>' . check_plain($this->get('label')) . '</h2>';
    $output .= '<p><iframe class="youtube-player" type="text/html" width="275" height="154" src="' . $this->get('youtube_id') . '" frameborder="0">
    return array('#markup' => $output);

As you can see, we create the tip under the namespace Drupal/<module name>/Plugin/tour/tip/<name of the class> and we extend from the TipPluginBase class.

Our tip type plugin has a property of youtube_id and uses that to render some markup in the getOutput() function. We can then create a tour that takes advantage of this tip type:

id: demo-youtube
module: 'tour_youtube'
label: 'Demo some youtube'
langcode: en
  - route_name: node.content_overview
    id: demo-video
    plugin: youtube
    label: 'Group Photo Time Lapse'
    weight: 3
    youtube_id: '8tHvys7xTRM'
      data-id: 'view-changed-table-column'


Some takeaways from the code sample above is that we have changed the plugin to youtube and we now have a youtube_id value that we can set courtesy of our new Youtube tip type! How easy was that? This is a simple system built on strong foundations implemented in Drupal 8.

With this information you have the tools to create amazing tours for contrib modules and distributions.
But why not core? Core will always be looking for updates to its help content, so why not contribute?
I can’t wait to see everyone in the issue queue!

Image: ©