Implements hook_help().
September 17, 2015

This post is part of our Drupal 8 series.

A few weeks back, we started with a seemingly easy task; installing Drupal 8. There were hidden complexities and challenges, but they’re definitely surmountable. In this edition, we’ll continue to build upon the technical foundation with a task that will be incredibly important for early adopters; custom module development.

The second challenge: make a custom module

Specifically, create a module that defines a block that executes dynamic, cacheable code. Again, this is something that sounds easy on the surface, but there’s a lot of hidden complexity. For example, Drupal 8 modules now include YAML configuration files, PSR-4 structures, and a different paradigm (sorry) for interacting with Drupal.

Fortunately, there’s a tool to help - the Drupal Console, which can be used to generate scaffolding for custom code.

Lessons learned

  • Drupal Console is extremely efficient and effective at generating working code, including services.
  • Drupal Console may be a potential replacement for Drush for most day-to-day operations.
  • Blocks enabled through the Drupal UI are cached forever by default.
    • In order to deliver dynamic content in a block, the block caching had to be manually disabled.

Some developers also experimented with module upgrading.

Spoiler: caching the current time

Here’s the source code of a block with custom caching in current_time/src/Plugin/Block/CurrentTimeBlock.php:

 * @file
 * Contains Drupal\current_time\Plugin\Block\CurrentTimeBlock.

namespace Drupal\current_time\Plugin\Block;

use Drupal\Core\Block\BlockBase;

 * Provides a 'CurrentTimeBlock' block.
 * @Block(
 *  id = "current_time_block",
 *  admin_label = @Translation("Current Time"),
 * )
class CurrentTimeBlock extends BlockBase {

   * {@inheritdoc}
  public function build() {
    $build = [];

    $cid = 'current_time_block:time';

    $data = NULL;
    if ($cache = \Drupal::cache('current_time')->get($cid)) {
      $data = $cache->data;
    else {
      $data = time();
      \Drupal::cache('current_time')->set($cid, $data);

    $build['current_time_block']['#markup'] = t('Time: @time', array(
      '@time' => format_date($data, 'custom', 'c'),

    return $build;


The next challenge: theming a custom node with two fields

Bits and pieces are coming together, but it’s all very rough right now. What about the look and feel? Drupal 8 changed the default templating engine from PHPTemplate to Twig.

Create an node in code with at least two fields and render it with a twig template.

How’s it been so far? Tell us about your experience in the comments!

See Jon Peck's profile
Jon Peck
September 17, 2015

Posted in

Jon Peck is a senior engineer focused on back-end architecture, optimization and performance. Originally from Upstate New York, Jon currently lives in Castro Valley, California.