Drupal 8 Custom Block Module Dev

For those ready to move beyond a simple “Hello World” module, this post documents building a Drupal 8 module with a Giphy search form in a custom block. The form uses jQuery to request data from the Giphy API and display the results.

Drupal 8 module to demonstrate custom block creation with the following features:

  • configuration data that is passed into the modules js library
  • public API search using core jQuery functions
  • twig template for a front end Giphy search form
Source Code

Module Folder

To get started, create a folder for the module in either /modules/custom/ or /sites/all/modules/. The name of the module folder is typically the same as the name given to the module. In the case of this particular module, giphys is an appropriate name. For example:

# context is drupal project root

cd modules
mkdir custom
mkdir custom/giphys

Module Info File

An info.yml file is needed to store module metadata. Since the module machine name is giphys, the file will be named giphys.info.yml

# create the giphys.info.yml file

cd custom/giphys
touch giphys.info.yml

Here are the metadata contents of this file. Included is data to inform Drupal of the core compatibility, module dependencies and a description for the administration portal interface.

name: Giphys
type: module
description: 'Giphys is a Giphy search block'
core: 8.x
package: Other
  - block

After saving giphys.info.yml, in Drupal, select the Extend menu, e.g., http://drupal.docker.localhost:8000/admin/modules. Giphys should be listed under Other:

Extend | Giphys

Module File

The giphys.module file is the entrypoint used to define help and theme hook functions that return respective data and paths. .module files should only contain functions that implement hooks.

# create the giphys.module file

touch giphys.module

 * @file
 * Module file for giphys_module.

use Drupal\Core\Routing\RouteMatchInterface;

 * Implements hook_help().
 * @see https://www.drupal.org/documentation/help-text-standards
 * @see hook_help()
function giphys_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    case 'help.page.giphys':
      // Help text for the admin section, using the module name in the path.
      return t("This is help text created in giphys implementation of hook_help().");

function giphys_theme($existing, $type, $theme, $path) {
  return [
    'giphys' => [
      'variables' => [
        'url' => 'http://example.com',
        'secret' => NULL

The next page covers twig templating for the HTML, module specific CSS and JavaScript asset management.

Docker Drupal Dev Environment

This post documents mounting a new Drupal Composer project as a volume in a Docker container. Features include Drush, Drupal Console, mailhog and phpMyAdmin. A Docker-sync configuration is available for OS X.


With the release of Drupal 8.3, using Composer to manage Drupal projects has vastly improved and is becoming a best practice. See Getting Started at getcomposer.org to install Composer.

Drupal Composer Template

Using Composer and the Composer template for Drupal projects to create a new Drupal site.

Open a CLI and execute the composer create-project command from the directory where you want to create your project. For example,

composer create-project drupal-composer/drupal-project:8.x-dev mysitefolder --stability dev --no-interaction


The docker-compose.yml file from Docker4Drupal image stack is optimized for local development. Use curl to download the file into the root of your Drupal project. For example,

curl https://raw.githubusercontent.com/wodby/docker4drupal/master/docker-compose.yml -Outfile mysitefolder\docker-compose.yml
curl -o mysitefolder/docker-compose.yml  https://raw.githubusercontent.com/wodby/docker4drupal/master/docker-compose.yml

Update the docker-compose.yml file. Create a named volume for data persistence in the mariadb node.

      - mysql:/var/lib/mysql
  • Note that an ellipsis … in the code snippets are not a part of the code and are there only to denote code that is being skipped and not applicable to the example. View all of the docker-compose.yml updates on GitHub.

In the php node, comment out the vanilla Drupal image node and uncomment the image without Drupal. Additionally, change the volume to mount the relative local directory ./ to /var/www/html in the container.


    image: wodby/drupal-php:7.1-2.1.0
      - ./:/var/www/html

In the nginx node, change the volume to mount the relative local directory ./ to /var/www/html in the container.


      - ./:/var/www/html

For data persistence, in the volumes node at the bottom of the docker-compose.yml file, replace the unused codebase volume with mysql.



Run containers

From the site folder, e.g., mysitefolder, execute docker-compose

docker-compose up -d

Drupal Console

Test drive Drupal Console by connecting to the php container.

docker-compose exec --user=82 php sh

List all of the Drupal Console commands.
Disconnect from the session with Ctrl+D

drupal list
Source Code


Acquia Certified Site Builder – Drupal 8

Earlier this week I took and passed the Acquia Certified Site Builder exam for Drupal 8. Here are some tips and a few resources that helped me prepare for this 50 question, 75 minute exam.

Acquia Academy

These free Drupal courses for the community were a big help. It has been several years since I have done any site building with Drupal and it was like going back to my home town, barely recognizable. The exam questions are mostly scenario based and the Building a Basic Site Using Drupal 8 course covers some of these. The videos also walk through the various administration menus that you will need to be familiar with.


For the Acquia Academy Site Builder course, I used the Docker image created by wadmiraal to run Drupal locally. It was also handy for experimentation since the Drupal site could easily be reset to that of a fresh install. If you are already familiar with Docker, then this won’t add much to your plate on top of preparing for the Site Builder exam. Otherwise, I recommend sticking with the Drupal environment solutions covered in the courses. Another bonus is that this image comes with Devel and Drush already setup. Drupal Console is also ready for installation when advancing to the developer track.


Here are few tips and scenarios to consider when studying.

  • Understand how to create custom content types and how to modify their display.
  • Understand Taxonomy use for content categorization.
  • Understand how to create content relationships. There are good examples using Events and Sponsors in the Acquia Academy Site Builder course to demonstrate this.
  • Understand how to use blocks in the page layout. For example, using blocks to reuse header and footer content assets in various ways.
  • Understand Users, Roles and Permissions and how to change what a certain group of users can do in terms of content workflow.
  • Understand how to handle a compromised User account.
  • Understand how to handle comment spam.
  • Understand how to administer the core cache modules, including views data caching that is tucked away under the Advanced Views settings.
  • Understand the various Display modes.
  • Understand how to create pages and blocks with Views.
  • Understand best practices when communicating with the Drupal community. For example, when an issue is encountered with a module.
  • The Site Builder course at Acquia Academy uses a couple of contributed modules. The Devel module is used to generate a bunch of content nodes to demonstrate views and filters, etc. Pathauto is used to demonstrate generation of path aliases. Token and Ctools are required by Pathauto, so they also need to be installed. It is useful to know where to find and how to install modules. However, if a given scenario can be solved using core modules, that answer is preferred.
Acquia Certified Site Builder - Drupal 8 Badge

Other Resources

Mint LAMP Development Environment

OPERATING SYSTEM: Linux Mint 13 Maya

For Drupal development, since I already have a Linux Mint system setup, I decide to focus on it rather than the Windows 8 Acquia Drupal setup I blogged about a few days ago.

Apache, MySQL & PHP

Install all of these applications with a single command. Thanks to Unix System Engineer, Nitin Sookun for posting this on the Linux Mint Community website.

Since you will need root permissions when performing write operations outisde of your home directory, the commands shown below presume that you are logged in as root or are in a root instance of the terminal. If you are not in a root terminal, you can prepend the commands with ‘sudo’, for example listing the contents of the current directory:

sudo ls
Sudo Sandwich

In a root terminal (such as ‘Konsole as root’).

apt-get install lamp-server

If you get this error message (as I did during a Mint Xfce LAMP install)

E: Unable to locate package lamp-server

Then you will need a carat at the end:

apt-get install lamp-server^

Then install phpMyAdmin

apt-get install phpmyadmin

Restart Apache and try loading http://localhost/phpmyadmin.

/etc/init.d/apache2 restart

If phpMyAdmin doesn’t load, try adding an Include to your Apache config with a text editor (such as ‘Kate’). In your terminal, open a new bash shell tab, and launch the editor (gedit, kate, etc.)

kate /etc/apache2/apache2.conf

In the apache configuration file, near the bottom, look for the location of other Include statements and insert this phpmyadmin include as needed.

Include /etc/phpmyadmin/apache.conf
/etc/init.d/apache2 restart


If you need to set or change the mySQL root password, use this command syntax when the password has not been set.

$ mysqladmin -u root password NEWPASSWORD

Use this command syntax to change the root password.

$ mysqladmin -u root -p'OLDPASSWORD' password 'NEWPASSWORD'


Download the latest stable Drupal core distro from http://drupal.org/download. Extract the downloaded file, for example, drupal-7.19.tar.gz to the host root, /var/www. Then with the mv command, rename the drupal-7.19 directory extracted into www to drupal7

tar -xf drupal-7.19.tar.gz -C /var/www
mv /var/www/drupal-7.19 /var/www/drupal7

Copy the default.settings.php to settings.php. Then apply write permissions to both the dafault directory and the settings.php file so Drupal can modify settings.php as needed during the install.

cd /var/www/drupal7/sites
cp default/default.settings.php default/settings.php
chmod a+w default
chmod a+w default/settings.php

Note, after Drupal is installed, reset settings.php file permissions to read only using a-w

Virtual Hosts

Setting up some Virtual Hosts in our Apache config. In terminal, open the apache cofig file for editing (gedit, kate, etc.)

kate /etc/apache2/apache2.conf

Below the Files node, add this code block.

NameVirtualHost *:80

  ServerName default
  DocumentRoot /var/www/

  ServerName drupal7
  DocumentRoot /var/www/drupal7

  ServerName drupal8
  DocumentRoot /var/www/drupal8

Restart Apache to load our config changes

/etc/init.d/apache2 restart

Hosts file

Add the two named virtual hosts to the hosts file

kate /etc/hosts	drupal7	drupal8

Restart apache …

/etc/init.d/apache2 restart

Now you can access the new Drupal website at http://drupal7

Next – Mint LAMP Development Environment – Part Two


Acquia Drupal for Windows

I needed to setup a localhost Drupal development environment to upgrade a Drupal 6 theme and do some testing prior to upgrading a live site to Drupal 7. I decided to give the Microsoft Web Platform Installer a try on my Windows 8 computer.

While installing Acquia Drupal with Web Platform Installer 4.0, at some point the Web Platform Installer asks for MySQL ‘root’ user password. Further along during the install, I received an error and was prompted again for the MySQL ‘root’ password. This error would not go away even after entering the correct password:

The specified password for user account ‘root’ is not valid, or failed to connect to the database server.

To resolve this issue, Launch the Windows Registry Editor and delete the mysql_pwd registry key under, HKCU\Software\Microsoft\WebPlatformInstaller

Download and install MySQL Connector/Net (32 bit).

I restarted Web Platform Installer, searched for Drupal, and this time I left the save ‘root’ password option un-checked during the install.


Random full page background

This Tutorial is written with Drupal 7 in mind. However, it can be applied to any website.

While upgrading and redesigning thebga.org golf association website, I decided to figure out how to have a random full page background part of the design. Drupal 7 makes it easy to include js and keep it, the theme and templates all separate from the Drupal core. The key is separation of your theme and it’s modules from the Drupal core and it’s modules. The Zen theme and Starter Kit make this very easy to accomplish.

Create or add this code to a javascript file in your themes “js” folder. I saved the file as random-bg.js (/sites/all/themes/thebga/js/random-bg.js).

(function ($) {
    $(document).ready(function() {
	var bgimages = [
	$('body').css({'background-image': 'url(sites/all/themes/thebga/images/bg-body/' + bgimages[Math.floor(Math.random() * bgimages.length)] + ')'});

Note the JavaScript closure around


more info on that here: drupal.org/node/171213.

Put your background images in /sites/all/themes/thebga/images/bg-body/. The bg-body directory is optional, I created it to keep the background images separate from the other images used in the theme.

Add this code to the page-backgrounds.css (/sites/all/themes/thebga/css/page-backgrounds.css).

body {
    /* background color + default image (in-case random-bg.js fails) */
    background: #003c00 url('../images/bg-body/ovl_2011_dos-equis_sunday.jpg') no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;

Open the theme .info file and after

; Optionally add some JavaScripts to your theme.

add this line to load your javascript file:

scripts[] = js/random-bg.js

That is it! Every time the page is refreshed, a random background is loaded using a jQuery css modifier.