Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Sep 28 2021
Sep 28

Mailchimp is a web based email marketing service used to send mass emails to a list of subscribers.

Drupal, out of the box, already allows you to send emails. However, there are distinct advantages to using a service like Mailchimp to send emails and maintain your mailing lists.

In this tutorial, you’ll learn how to integrate Drupal and Mailchimp.

The Mailchimp module integrates Mailchimp and Drupal by allowing Drupal to connect via Mailchimp’s API. This module also comes with a few submodules. Each submodule provides additional functionality that leverages Mailchimp’s features.

These submodules are:

  • Mailchimp Lists
  • Mailchimp Campaign
  • Mailchimp Signup

This tutorial will cover each of these submodules in more detail.

Table of Contents

Getting Started

First make sure you have a Mailchimp account. Just go to mailchimp.com and create a free account.

It is recommended to install this module using Composer so that the Mailchimp API library will be automatically downloaded to the correct location:

composer require drupal/mailchimp

To enable the module: we can use Drush:

drush en mailchimp -y

After enabling any Drupal module, it’s a good idea to clear the Drupal cache:

drush cr

Now go to Configuration >> Web Services >> Mailchimp (admin/config/services/mailchimp)

Here you need to enter your Mailchimp API key. The initial configuration screen looks like this:

You will notice the error:

“Failed to load Mailchimp PHP library. Please refer to the installation requirements.”

This is because you have not entered your Mailchimp API key yet. To get your Mailchimp API key, log into your MailChimp account and go to Account >> Extras >> API Keys.

Create your API key and insert it in the Drupal Mailchimp API key field as shown in the above screenshot and then click on “Save configuration”.

You may need to refresh the page to suppress the error.

At this point, you have successfully linked your Drupal site to the Mailchimp API.

Using the Mailchimp Lists

A Mailchimp List is also known as “Audience” within the Mailchimp interface. It seems Mailchimp uses the terms “List” and “Audience” interchangeably within their interface.

The Mailchimp Lists submodule allows you to subscribe any entity with an email address to Mailchimp Lists by creating a Mailchimp List field and allowing anyone who can edit that type of entity to subscribe/unsubscribe and update member information directly from within Drupal.

So what does this mean? In a nutshell, it allows you to connect your Mailchimp Audience to Drupal.

Then, any Drupal entity with an email field (typically the User entity) can be used to subscribe users to your Mailchimp Audience. The process of “subscribing users” is done by the Mailchimp Signup submodule, which is explained further in this tutorial.

The Mailchimp List submodule only connects your Mailchimp Audience to Drupal so that Drupal is aware of all your Mailchimp Audiences.

Step 1: In Mailchimp go to “Audience” and create your Audience/List. For this tutorial, we have created a Mailchimp audience with the name “Webwash Test Audience”.

NOTE: You can only create a single audience using a free account.

Step 2: Use Drush to enable Mailchimp Lists in Drupal:

drush en mailchimp_lists -y

Step 3: Clear the Drupal cache:

drush cr

At this point, in Drupal if you go to Configuration >> Web services >> Mailchimp >> Audiences (admin/config/services/mailchimp/lists) you should see all of your Mailchimp lists which looks like this:

To allow Drupal users to be added to this List, go to the “Signup forms” section of your Mailchimp Audience as shown in the screenshot below:

There are a few options on this page to embed the form into your Drupal site, which mostly involves creating and editing the form from within the Mailchimp interface and then embedding the generated HTML code directly into a Drupal block or page template.

You can also use the Mailchimp Signup submodule, which creates a block or page with a simple web form with fields such as Email (required), First Name and Last Name etc. When users submit this form, they will be subscribed to your Mailchimp list.

Now that you have connected your Mailchimp Audience (List) to Drupal, you can allow users to subscribe to your Mailchimp list within Drupal.

How do you do this? You have to use the Mailchimp Signup submodule.

Using the Mailchimp Signup

The Mailchimp Signup submodule allows you to create blocks and/or pages within your Drupal site to allow users to subscribe to Mailchimp Lists. This way, you do not have to embed any Mailchimp generated code into your site.

We will now demonstrate how you can use this module.

Step 1: Enable the Mailchimp Signup submodule using Drush:

drush en mailchimp_signup -y

Step 2: Clear the Drupal cache:

drush cr

Go to Configuration >> Web services >> Mailchimp you will notice a new tab “Signup Forms” as shown below. The direct Drupal URL is:


Step 3: Add a Signup Form

Click on “Add Signup Form” and fill in the details. For this tutorial we will select both Block and Page for demonstration purposes. This is a screenshot of our Signup form:

Notice that the Mailchimp Audience is automatically available (thanks to the Mailchimp List submodule).

In the Merge Field Display section, you will see the fields that are generated from your Mailchimp form. You can edit these fields by going to the Settings of your Audience in Mailchimp and then under Settings, click on “Audience fields and *|MERGE|* tags” as shown below:

If you selected Page Display mode, you can go to the URL you entered and your sign up form should look like this:

For the Block Display mode, you must clear the Drupal cache first and then you can add the block to any region in the usual Drupal way by going to Structure >> Block layout and placing the block in the desired region. We have placed our block in the right sidebar region of our homepage and it looks like this:

NOTE: If you go to Structure >> Block layout and you do not see the Sign up block when trying to place it in a region, you should clear your Drupal cache.


It is worth mentioning that the Mailchimp Signup module comes with some permissions as shown below. You can set this to your liking:

Using the Mailchimp Campaigns

The Mailchimp Campaign submodule allows Drupal users (with the appropriate permissions) to send Mailchimp campaigns from within Drupal. The content of the campaigns can contain any Drupal entity or custom HTML content.

We will demonstrate how to set up Mailchimp Campaigns from within Drupal.

Step 1: Enable the Mailchimp Campaigns submodule using Drush:

drush en mailchimp_campaign -y

Step 2: Clear the Drupal cache:

drush cr

Step 3: Set the appropriate permissions.

The Mailchimp Campaign submodule comes with 1 permission allowing a specified role to administer Mailchimp Campaigns from within Drupal (see screenshot below). You should set this permission to the appropriate role.

Step 4: Create at least 1 Audience Tag

As of March 21st 2021, there is a reported bug whereby if you do not have any Audience Tags defined for your Audience, you will not be successful in creating a campaign in Drupal. Follow the bug here. A temporary workaround is to create at least 1 Audience Tag in Mailchimp.

So let’s create an Audience Tag in Mailchimp. In Mailchimp, there are two ways to add Audience Tags. You can either click on the Tags menu in the left sidebar for your Audience, or find the Tags setting under “Manage Contacts”. Both options are shown in the screenshot below:

Go ahead and create a tag. Even though we are not using this Tag for our Campaign, we need at least 1 Tag created until the bug has been fixed.

When this bug is fixed, Step 4 will no longer be required.

Step 5: Add your Mailchimp Campaign within Drupal

There are two ways to add Mailchimp Campaigns. One way is from within the Mailchimp interface (hereby bypassing the need for this module) and another is using this module and doing it inside of Drupal. It is important to note that if you create a campaign from within Mailchimp, it will not be imported into Drupal. However, the reverse is not true. That is, if you create a campaign from within Drupal, it will be automatically imported into Mailchimp.

To create your campaign within Drupal, go to Configuration >> Web services >> Mailchimp and click on the Campaigns tab. Then click on “Add Mailchimp Campaign”. This is shown below:

Fill in all the necessary fields. Notice that the Audience Tags field is automatically prefilled once you select the Audience as shown below:

NOTE: At the time of writing this tutorial (March 21st 2021), if you try to create a Campaign from within Drupal, it will only work if you do not select a template as shown below.

Whatever you type into the “Content” field will be inserted into the email body when you send the Campaign. Follow this issue to keep updated when there is a fix.

Once you create your Campaign in Drupal, it will look similar to this:

And your Campaign will be automatically imported into Mailchimp which will look like this:


Mailchimp and Drupal can be connected to integrate Mailchimp’s features in Drupal. We have shown how to use the Mailchimp module to do this.

The Mailchimp List submodule can be used to connect your Drupal entities to a Mailchimp Audience.

Once connected you can then use the Mailchimp Signup submodule to provide a page/block for Drupal users to actually sign up and be added to your Mailchimp Audience.

And finally the Mailchimp Campaign submodule can be used to create Campaigns within Drupal.

Sep 23 2021
Sep 23

Acro Media’s own Chithra K has put together this handy, step-by-step guide to integrating your BigCommerce store with the Drupal CMS.

BigCommerce for Drupal setup guide

The BigCommerce for Drupal module, created by Acro Media in partnership with BigCommerce, was released early this year and brings together two different platforms – BigCommerce, the open SaaS ecommerce platform, and Drupal, the open source content management system. The result provides a wonderful new way for retailers to implement an innovative and content-rich headless ecommerce strategy. If you use one and would like to have the capabilities of the other, the BigCommerce for Drupal module is the bridge you need. With this module, you can use Drupal as the powerful front-end CMS with BigCommerce as the easy-to-use and scalable ecommerce backend.

This post is a step-by-step guide for people who want to know how to install the BigCommerce for Drupal module and get started with both platforms. If you just want to know more about BigCommerce and Drupal together as an ecommerce solution, check out this post instead.

How this module works

Here’s a quick overview of how this all works. The BigCommerce for Drupal module integrates BigCommerce and Drupal together, but each platform is still used for different tasks.

In BigCommerce, you configure products, categories, shipping, taxes and everything else for the ecommerce side of your site. BigCommerce is also where you go to manage orders as they come in.

Drupal is then used for the website frontend and themeing. Product and category information from BigCommerce are synced to Drupal, importing them as Drupal Commerce products so that they can be displayed and used like any other Drupal-based content. Any non-commerce content is also managed within Drupal. When a customer goes to checkout, a BigCommerce checkout pane is embedded in the Drupal site to securely process payment and save customer and order information.

Setup BigCommerce and Drupal

On to the guide! Follow these steps and you’ll have your BigCommerce and Drupal store configured in no time!


This guide already assumes that you have the following ready.

  1. A BigCommerce account and store created
    You will need to create a BigCommerce account with at least one product, shipping method and payment method configured in your BigCommerce store. Do this here, not in Drupal.

    NOTE: BigCommerce currently offers a 14-day trial period, so anyone can go and create and configure a store easily for free. For this demo, I signed up for that and created some random products to use for testing.

  2. A working Drupal 8 site
    You should have a Drupal 8 site with the Commerce module enabled and a default store added (via Commerce > Configuration > Store > Stores). You don’t need to do any other setup here yet or enable any of the other Commerce modules like checkout or payment. BigCommerce is going to handle all of this for you.
  3. An SSL certificate for your Drupal site
    Your Drupal website needs to have an SSL certificate active for the BigCommerce checkout form to render. This is required because it ensures security for your customers at checkout, so make sure you install one.

BigCommerce for Drupal setup guide

With the prerequisites done, here’s what you need to do to the BigCommerce for Drupal connection made.

Step 1: Create a BigCommerce API account

  1. Go to your BigCommerce store admin page and navigate to Advanced Settings > API Accounts.
  2. Click on the “Create API Account” button and select “Create V3/V2 API Token”.

    BigCommerce Store API Accounts page
    Fig: BigCommerce Store API Accounts page

  3. Provide a name (i.e. Product Sync) and select the scope for each feature (i.e. if you don’t want the ability for the Drupal admin to modify the product information, you can set the scope for “Products” as “read-only”).

    API configuration in BigCommerce
    Fig: API configuration in BigCommerce

  4. Click “Save” to save your changes. Once saved, you will see a summary and a prompt to download a file. Download it and keep it safe. Once you create an API account, you can’t modify the keys (but you can always make a new one).

    BigCommerce API Credentials dialog box
    Fig: BigCommerce API Credentials dialogue box

Step 2: Download and configure the BigCommerce for Drupal module

  1. Get and install the BigCommerce for Drupal module.

    TIP: This module requires a bunch of other modules to work. To get the BigCommerce for Drupal module and all of its dependencies at the same time it’s recommended to use Composer instead of manually downloading it. Running the following command within your Composer-based Drupal project will get everything you need.

    composer require drupal/bigcommerce
  2. In Drupal, navigate to the module configuration page at Commerce > Configuration > BigCommerce > BigCommerce Settings.
    1. Fill in the API Path, Client ID, Secret Key, and Access Token that you received when creating the BigCommerce API.
    2. Hit “Save”. If everything is correct, you will see a message saying “Connected Successfully”.

      BigCommerce Configuration page in Drupal
      Fig: BigCommerce Configuration page in Drupal site

  3. Next, we configure the Channel Settings. This will create a storefront URL for you in BigCommerce which will match the one that is generated on the Drupal side.
    1. Select “Add new channel” from the select channel list.
    2. Provide a channel name.
    3. Click the “Create new BigCommerce channel” button. You will then see a Site ID and Site URL on the setting page.

      BigCommerce configuration page in Drupal - Channel settings
      Fig: BigCommerce configuration page in Drupal

  4. Now in the same Channel Settings area, click on the “Update BigCommerce Site URL” button. This lets you confirm that the URL generated is actually sent to BigCommerce, otherwise, the checkout form will not be loaded on your Drupal site.

    You can also confirm the channel connection from within the BigCommerce admin dashboard by visiting the Channel Manager admin page.

    Channel Manager storefront confirmation in BigCommerce
    Fig: Channel Manager storefront confirmation in BigCommerce

Step 3: Sync products, variations and taxonomies from BigCommerce

  1. In Drupal, navigate to the product synchronization page at Commerce > Configuration > BigCommerce > BigCommerce Product Synchronization.
  2. Click the “Sync Products from BigCommerce” button and ta-da, all the products, variations, and categories will be synced to your Drupal site in an instant.
    Alternatively, you can also synchronize via the following Drush command. Advanced Drupal users can use this command on cron to do automatic syncing.
    drush migrate:import --group bigcommerce
    Product Synchronization page
    Fig: Product Synchronization page

    Fig: Syncing from BigCommerce in progress

    NOTE: If you run into errors when syncing products, it is probably because you don’t have a store added in the Drupal Commerce module yet. Add one at Commerce > Configuration > Store > Stores.

    TIP: Any time you make changes to the products in BigCommerce, visit this page or use the Drush command to synchronize the changes. Before syncing, you’ll also see a message telling you that updates are available.

  3. Confirm the products have synced by visiting the Product page for Drupal Commerce at Commerce > Products. A list of all of the products brought in from BigCommerce will appear here.

Step 4: See the BigCommerce checkout in action

  1. Now that everything is set up, go to a product page, and it to your cart and proceed to checkout.

    If everything was done correctly, you will be able to see the BigCommerce checkout form embedded into your Drupal site! Hurray! All of the shipping methods, payment methods, tax calculations, and other BigCommerce store configurations will be seen in the embedded form here.

    If you don’t see the checkout form make sure that your channels settings are correct and that you have an SSL certificate installed.

    Drupal’s checkout page with embedded BigCommerce checkout form
    Fig: Drupal’s checkout page with embedded BigCommerce checkout form

    Drupal’s checkout page after order complete
    Fig: Drupal’s checkout page after order complete

  2. Once an order has been placed, the order information will be stored in Drupal (at Commerce > Orders) and will also be sent to BigCommerce (at Orders > View).

    BigCommerce backend View Orders page
    Fig: BigCommerce backend View Orders page

Additional notes

The BigCommerce for Drupal module is ready for production and available for all to use. When writing this guide, there were some additional notes that I wanted to share.

  • At this time, product management should always be handled within BigCommerce and then synced to Drupal. Currently, there is no option to bring back a product if you delete it on the Drupal side, so be careful.
  • A development roadmap for the module can be found here. It outlines future features and plans.
  • If you use the module and find any bugs or want specific features, please add them to the module issue queue here.

Acro Media is a BigCommerce Agency Partner

Acro Media is the development team partnered with BigCommerce that made the BigCommerce for Drupal module a reality. We have many, many years of ecommerce consulting and development experience available to support your team too.

If you’re interested in exploring Drupal, BigCommerce or both for your online store, we’d love to talk.

See our BigCommerce for Drupal solutions

Editor’s note: This article was originally published on December 2, 2019, and has been updated for freshness, accuracy and comprehensiveness.

Sep 21 2021
Sep 21

View Bulk Operations, commonly referred to as VBO, is a module that allows specifically defined actions that can be simultaneously executed on rows of Views data.

This tutorial will show how to install this module and set up a simple View with a defined action and VBO field. We will then demonstrate how to use VBO to perform this action on selected View rows. We will also show how you can define permissions for roles to use our defined action.

Table of Contents

Getting Started

We can easily download VBO using Composer:

composer require drupal/views_bulk_operations

To enable VBO you can use drush:

drush en views_bulk_operations -y

After enabling any Drupal module, it’s always a good idea to clear the cache:

drush cr

Create a View

For this tutorial, we will create a simple View that will list recently created content of type “Basic Page”.

For our View to display results, we should have some content of “Basic Page” already created. If you don’t already have content, go ahead and create some content of type “Basic Page”.

Now let’s set up a very simple View. Our View just lists nodes of type “Basic Page” in a table format. Here is a screenshot of the Views configuration screen:

And here is the output of the above View:

Add VBO field to the View

The magic happens when we add the VBO field to our View. For this tutorial, we will create an “Unpublish” action that will allow users to unpublish nodes of “Basic Page” in our View.

1. In the Fields section of our View, add the “Views bulk operation” field:

2. After clicking on “Add and configure fields”, look for the “Selected Actions” section. We are going to select “Unpublish content item” and give it a label of “Unpublish” and then click on “Apply”. (You can select multiple actions as needed.) This is shown below:

Now your View should look like this:

3. If you had selected multiple actions, they would all be shown in the “Action” dropdown list. You can select some rows using the VBO field and apply the Action of “Unpublish” to see the changes. Follow the 3 steps in this screenshot:

The following screenshot shows the results after doing this to the first 2 rows. Notice the “Published” column values have been updated.

Specify which roles can apply specific Actions (Optional)

What if you only wanted to allow specific roles to use specific actions? The awesome developers of View Bulk Operations included a sub module called “Actions Permissions” to accomplish just that!

Let’s say we only wanted the “Authenticated User” role to use the “Unpublish” action in our above View.

After enabling the sub module “Actions Permissions”, go to Admin >> People >> Permissions and in the list of Actions Permissions you should select “Execute the Unpublish content item action on Content” as shown below:

Now only the “Authenticated User” role can apply the “Unpublish” action in our View. This “Actions Permissions” sub module becomes a very powerful feature when you have multiple roles in your site.


Views Bulk Operations (VBO) allows users to perform actions on View rows data. In this tutorial, we have shown how you can add the VBO field to a View and optionally give a specific role permissions to use this action.

Sep 14 2021
Sep 14

Decoupling separates the system that stores the content from how that content is displayed on other independent systems. This can come with many benefits but also some downsides and tradeoffs. With progressive decoupling, you can get some of the benefits of decoupling while avoiding some of the downsides.

This is a re-post of the article on the Lullabot blog.

Slides available here.

Decoupling separates the system that stores the content from how that content is displayed on other independent systems. This can come with many benefits but also some downsides and tradeoffs.

With progressive decoupling, you can get some of the benefits of decoupling while avoiding some of the downsides.

There are several ways to decouple a website progressively, but this article makes the case that widgets provide the most flexibility.

What are widgets?

Widgets are stand-alone JavaScript (JS) applications that are framework-agnostic and are designed to be embedded and configured by CMS editors.

Widgets can be vanilla JS or use frameworks like Vue or React.

Why JS over server-generated HTML?

Better reactivity and interactivity

The pages can be static or served from cache (very fast), and JS can be sprinkled on top. The server can provide the unchanging parts, while the JS application adds interactivity.

This reduces the load on your servers while increasing website performance. You keep the benefits of built-in CMS performance tooling.

Distributed delivery

Different development teams can write software independently. They can publish software on the same platform without coordinating complex deployment efforts.

  • Teams write the JS code in isolation
  • The browser executes the JS
  • Different deployment pipelines and servers can be used.

Distributed example

One team works on the navigation, one team works on the main feature set, and one team works on a price calculator.

Biggest talent pool

According to extensive surveys, JS and TypeScript (a superset of JS) are the most commonly used languages, based on Stackoverflow’s yearly survey.

By building pages and experiences in JS, you can pull talent from a bigger pool. You have more options.

Better developer experience

Since JS is so popular, your developers can leverage many tools, services, and frameworks. Jest, Storybook, Husky, Gulp, for things like unit testing, component management, setting githooks, etc. Many services integrate with the technology.

Many platforms will give you better support, which leads to better workflows, which hopefully leads to better code—things like visual diffs, code quality analysis, and code deployment. Popularity leads to a flourishing ecosystem.

In addition, frameworks like Vue can take care of some of the rough edges.

Should we just build JS applications then?

Yes and no. We still care about the content. Content is the heart of the web. You can have a great user experience, but without content, your project is doomed to fail.

To manage content, you need a CMS. Especially if content is your product or is central to your business. A CMS provides many features that are hard to build from scratch.

  • Managing pages and setting up URLs
  • Users and access restrictions
  • SEO metadata
  • Media library
  • Security patches
  • Editorially controlled layouts
  • Moderation and previews

Why widgets?

We have a CMS. We know we want to use some JS. Why not put JS in our CMS templates?

This works. You can certainly go that route. But widgets have some advantages over JS in the template.

They require no CMS deployments

A developer creates a new widget in the registry, and it appears in the CMS editorial interface for embedding. No additional effort. Bug fixes and enhancements are also instantaneous.

Here is what a traditional deployment might look like:

JS Deploy 1

  1. Develop JS app
  2. Integrate it with a CMS template (and with the content model if you want the app to receive editorial input)
  3. Deploy both in conjunction since they are coupled together
  4. Editors can expose the JS app to end-users

Widgets allow you to skip the two middle steps. When you use the existing CMS integrations, development is only done in JS, and it can be deployed on its own. No need to call in a CMS developer to add new widgets or update existing widgets.

A widget deployment looks like this:

JS Deploy 2

Embedded and controlled by editors

JS developers can create flexible applications that allow for tweaked experiences and configuration. A single widget can act as multiple similar widgets.

JS developers define the input data they expect from editors, and the CMS creates a form for the editors to input that data. This allows many instances of the same type of widget to be embedded with different configurations: different content, color palettes, external integrations, etc.

The following example defines a customizable button that the editor can configure.

settingsSchema: {
  type: 'object',
  additionalProperties: false,
  properties: {
    fields: {
      type: 'object',
      properties: {
        'button-text': {
          type: 'string',
          title: 'Button text',
            'Some random string to be displayed.',
          examples: ['I am a button', 'Please, click me'],
title: 'Example Widget',
status: 'stable',

The CMS integration, which can be defined up-front, reads the definition and presents the proper form elements to the editor.

Customized button example

Embedded anywhere

Since widgets are not embedded at build time, but editorially, they can be placed anywhere. If the JS is in the template, you can’t choose, for example, to insert the JS app between two paragraphs of the body field. And changing the position would require a CMS deployment.

Body field insert

With widgets, editors can insert them anywhere.

  • Using layout building tools
  • Using WYSIWYG integrations
  • Using content modeling tools (entity reference field that points to a widget instance)
  • Using 3rd party JavaScript

WYSIWYG layout builder

And the same widget can work for any CMS. As long as the CMS subscribes to the registry and can read the schema, it can embed the JS application. When you change or fix something in the JS app, it is distributed to all CMSs. Widgets can also work in static HTML pages and Optimizely pages. Anywhere.

When are widgets a good fit?

Structured content is still the way to go. You don’t have to use widgets everywhere, but they are useful in several contexts.

  • Interacting with 3rd party APIs - reviews sites (g2crowd), commenting
  • Interactive tools - pricing calculators, checklists saving progress
  • Data visualizations - maps, charts of COVID data
  • Adding some pop to a page - you can do some things with JS that may be difficult to achieve when limited to HTML and CSS

How to get started

Create a widget

From a technical perspective, a widget is a function that takes a DOM id and renders JS in it. A widget can also receive arguments as HTML data.

Here is an example of rendering a React component:

  window.renderExampleWidget = function(instanceId) {
  const element = document.getElementById(instanceId);
  const title = element.getAttribute('data-button-text');
    <Widget title={title} />,

It is very easy to port existing components and re-use them.

Upload the app code

The code needs to live somewhere accessible to the internet (Github pages, Amazon s3 bucket, etc.). The CMS can use this to either download the files or serve them from there. We don’t want to bundle the files within the CMS because that introduces coupling again.

Publish the metadata

This is the tricky part. Without the metadata, this is just another JS application in some repo.

We need a registry, which is just a JSON document containing the metadata about all the available apps that can be downloaded from the internet. An array of objects. This includes the “directoryUrl,” which defines exactly where the files live. You can also see the “settingsSchema” property, which defines the shape of the input data this widget will accept.

    "repositoryUrl": "https://github.com/js-widgets/example-widget",
    "shortcode": "example-widget",
    "version": "v1.0.4",
    "title": "Example Widget"
    "description": "This is a widget example that showcases some of the features of the JS Widgets project."
    "directoryUrl": "https://static.mateuaguilo.com/widgets/sandbox/example-widget/v1",
    "files": [
    "availableTranslations": [
    "settingsSchema": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "fields": {"type": "object"...}

This file will need to be uploaded somewhere that is accessible via HTTP.

The CMS pulls that JSON object and knows about all the widgets and where to grab their assets. You’ll start seeing widgets appear in your editorial tools.

Widget list

Ok…but where do I actually start?

There are lots of existing tooling and examples at https://github.com/js-widgets. It includes a registry boilerplate and catalog, widget examples, and CI/CD integration.

If you fork it, you’ll get a lot of nice things out of the box.

Stakeholder-ready catalog

The same registry that provides information to the CMS can provide information to a single-page application that is browsable and searchable. This requires zero effort. Everyone involved can see what is available: editors, developers, stakeholders, etc.

The catalog can also render a widget as a live sample, even if the widget requires editorial inputs. Examples utilize the “examples” key as shown in the widget definition above.

Widget catalog

Governance like you need it

All of this might seem like a governance nightmare. Do you really want JavaScript updated in a remote location and immediately deployed to your live site?

Of course not.

You decide what registries to accept into your CMS. You decide what widgets and updates go into your registry. You decide who has access to change those widgets and registries.

Production-ready dependencies

We want these widgets as light as possible. What if there was a way not to bundle big dependencies in every single JS app? We don’t want to download React for every widget, for example.

Shared dependencies are possible with this paradigm. Widgets can be configured to pull certain dependencies from the parent container. This requires some Webpack configuration and telling the CMS where to find the excluded libraries. Read the documentation for external dependencies here.


We hope this makes you excited to start taking advantage of widgets and progressive decoupling. For more videos on the specifics of setting this up, take a look at these additional videos:

Photo by Anne Nygård on Unsplash

Sep 07 2021
Sep 07

One of Acro Media’s very own, Mike Hubbard, breaks down two of the world’s best-known content management systems. Full of detailed analysis and side-by-side comparisons of the WordPress and Drupal CMS admin user interfaces. Read on to learn everything you didn’t know you didn’t know.

Side-by-side: WordPress and Drupal admin UI comparison quick links.

Click on the links below to jump to each section and see which CMS comes out on top.

Content management systems (CMSs) are the engine that drives content creation on the web today. They form the foundation that we build on for publishing and sharing information, creating digital experiences and conducting online retail. WordPress and Drupal are staples in the CMS world and they have both been around a long time. WordPress is known for its intuitive and easy-to-use interface. Drupal is known for its flexibility and complexity. While both have their strengths and weaknesses, the usability gap between WordPress and Drupal is changing. This article will show you the current state of Drupal’s admin user experience in a side-by-side comparison with WordPress, the most widely used CMS. If you’re familiar with one CMS but not the other, this comparison is also a good introduction to the other.

TL;DR: The primary goal of this article is to dispel the perception that Drupal is widely different and harder for administrators to use than WordPress. If you don’t care about the background behind this perception, just skip down to the direct comparison.

WordPress is easy, Drupal is hard… why does this perception exist

But first, a little background. The dominant CMS in terms of the number of sites running on it is WordPress. W3Techs estimates that WordPress powers about 62% of all websites that use a CMS, meaning multiple millions of websites are using it.

Why is WordPress so popular? WordPress started as a blogging engine with a focus on being easy to use. This proved to be incredibly important because it meant that nearly anyone could get a WordPress site up and running fast and be able to use it with little-to-no training. The idea caught fire with both individuals and local businesses who just wanted a simple, low-cost website that others could find online. Web developers and agencies also finally had a framework that allowed their clients to make simple content edits within an admin environment that was friendly.

Of course, today, businesses can use WordPress for much more than a simple website, but ideally, that is still the best use case. The perception that WordPress is easy to use stands true. It may not be the solution if you have more complex needs.

But, dear reader, this article isn’t meant to praise and promote WordPress. Instead, much of this article will focus on another popular CMS, Drupal. 

Drupal is a fantastic CMS and is incredibly powerful when used correctly. Drupal is the go-to solution for providing a robust solution for today’s CMS-driven website development in many web development circles. It is thriving as the #3 ranked CMS with about 3% of the internet population, equalling hundreds of thousands of websites using it. 

Why isn’t Drupal more popular? Well, anyone who knows Drupal (and even many who don’t) will tell you that Drupal is best suited for large websites with high traffic and complex requirements. Universities, government, nonprofits and online retailers are a sample of those who use Drupal. Out-of-the-box Drupal isn’t as ready to use as WordPress, so it’s unlikely a suitable fit for simple websites. For non-developer individuals, configuring Drupal is a steep learning curve. Local web agencies take more time to set up, which means they must charge more. These reasons alone essentially take Drupal out of the running for many websites, so for Drupal, it’s more about the use case than mass adoption.

With that said, Drupal’s ability to be configured and developed means it can handle nearly any situation required of it, whether selling products for enterprise businesses or being the integration layer between multiple platforms. While this inherent flexibility is excellent for software developers, Drupal’s perception of complexity, combined with a historically underwhelming admin experience, has cemented a reputation that Drupal is unintuitive and difficult to use for the end-user. Much like WordPress, Drupal’s reputation preceded itself. In Drupal’s case, however, this reputation isn’t as flattering, and it’s something that our sales and outreach teams often battle.

For Drupal, it’s time for change

Like WordPress, Drupal is open source software. It’s free to use, and anyone has full access to the underlying code to modify and build on. Both platforms have a core team for advancing key initiatives and a massive community of individuals and organizations that support the initiatives while also adding additional functionality through plugins (WordPress lingo) or modules (Drupal lingo).

While usability has always been important to WordPress (since it started as a blogging platform), Drupal was historically more focused on being open and flexible. Its user experience has continuously improved with each version release, but late 2018 marked the beginning of a big push towards modernizing the Drupal admin user interface (UI). Drupal is an amazing software, and it’s time that the admin experience catches up.

Introducing Claro, Drupal’s new admin UI

Drupal 8 Claro admin theme
Claro interface design mockup courtesy of Drupal.org

Claro is the new admin theme being built as part of the Admin UI Modernization initiative. It’s included with every Drupal 8 site, new and old, and can be enabled right now if you so choose. Just be aware that it is currently considered “experimental” while progress continues to be made. It’s not yet in its finished state, but you can view the development roadmap here to see what is still left to do.

Side-by-side: WordPress & Drupal Admin UI Comparison

On to the comparison!

For WordPress, I’m using version 5.3.2 (released Dec. 18, 2019) which comes with its own Twenty Twenty default theme and content.

For Drupal, I’m using version 8.8.1 (also released Dec. 19, 2019. How about that!) and the new, but experimental, Claro admin theme. If you’re looking at this at a later date, some aspects may be different (for the better!) as the development of the theme continues. I’ve also installed Drupal using the official Umami demo install profile so that I have a theme and some content to work with.

In each of the 10 comparison categories below, I’ll give my opinion on which CMS has the edge out-of-the-box and why I think this. I’ve used both platforms and do have some bias towards Drupal, but I’ll do my best to keep that in check.

Category quick links
  1. Admin toolbar
  2. Login dashboard
  3. Managing media
  4. Creating pages
  5. Editing pages
  6. Managing widgets and blocks
  7. Managing menus
  8. Managing users, roles and permissions
  9. Site status report
  10. Plugins and modules
  11. WordPress & Drupal comparison summary

1. Admin toolbar

The admin toolbar is always present on the page of both WordPress and Drupal.


WordPress admin toolbar

In WordPress, a single toolbar is used as a jump-off point for common admin pages, but you can also start the content creation process and access your account profile and information.


Drupal 8 admin toolbar

Drupal has a similar admin toolbar except you have access to everything, including creating new content. Every admin page that your user role has permission to view is available through this menu. While it’s more to look at initially, experienced users enjoy fewer clicks to get where they want to go.

Edge: Drupal

While the learning curve to know where everything is might be a bit steeper, experienced Drupal users enjoy being able to access everything in one familiar way. With that said, new users may find this larger menu intimidating.

2. Login dashboard

After logging in, the login dashboard is the first page you see. WordPress and Drupal both take a different approach to their login dashboard.


WordPress login dashboard

WordPress has a robust dashboard right out of the gate. This dashboard takes admins away from the site frontend and into an interface that only they can see. The left side has a larger menu for accessing the rest of the admin interface. The main content area mix of useful information about your site and information specific to WordPress as a whole, such as training resources and upcoming WordPress events. The panes on this page can be toggled on and off and plugins can add new panes.


Drupal 8 login dashboard

This is the first area where Drupal takes a different approach. Instead of a robust dashboard, you don’t actually get much of anything. The admin toolbar already gives you access to the entire site, so Drupal keeps you on the website frontend and instead shows you your “user page”. This page is entirely customizable although you will most likely need third-party or IT support to do so. It’s an open canvas to do with as you like. For ecommerce, you might show a customer their information, recently viewed products and their last order placed. For content creators, you might show a custom dashboard with quick links to their common tasks. What you do here is entirely up to you.

Edge: WordPress

Although it’s not entirely useful, WordPress actually has a dashboard which is a nice touch for new users. Drupal's clean slate offers a lot of exciting potential for admins and visitors alike, but any potential must first be realized before this page is useful.

3. Managing media

Images, videos, documents and more are uploaded and organized within a media manager. Both WordPress and Drupal offer a convenient content editor plugin that makes selecting and adding media into content easy.


WordPress media manager

WordPress really defined the way media can be managed within a CMS. Their interface for managing media contains a handy drag-to-upload feature and each piece of media is shown in a grid format by default. Media can be filtered by date, type and name.


Drupal 8 media manager

Drupal admittedly isn’t as clean as WordPress in this interface yet but its functionality is essentially the same and solid for most users. The visual interface will improve as the development of Claro progresses. By default, Drupal displays media in a list, but you can toggle between list and grid. There are also similar filtering options. Like all other aspects of Drupal, advanced users can customize media types beyond what you see here and entirely new media types can be created. This advanced functionality is unique to Drupal and isn’t as easily done in WordPress.

Edge: WordPress

WordPress does a great job of making media easy to manage. Drupal will continue to see improvements in the near future, but right now it still feels clunky.

4. Creating pages

Creating new pages, such as general content pages and blog posts, is a common interaction that most admin users will need to do.


WordPress new page Gutenberg editor

As of version 5.0, WordPress includes their much anticipated Gutenberg editor experience. This editing format is sleek, modern, and very intuitive. You start with a title and then continue piecing together chunks of content by selecting various types of “blocks” to build the page with. Blocks are a single, reusable type of content such as a heading or paragraph of text, an image or gallery, a list, a quote, etc. Custom blocks can be created and plugins may also add additional blocks that content creators can use. Along the right side of the page is a settings pane. This pane provides various page specific settings and customizations such as page visibility, featured image, an option to allow comments, etc. Additional settings for the currently selected content block also appears here.


Drupal 8 new page creation

Out-of-the-box, creating a new piece of content looks like the screenshot above. Content in Drupal could potentially be something wildly different than just a basic page, so Drupal defaults to a standard “field-based” editing interface where the different fields that are configured to make up the content are laid out on the page. All editors need to do is fill in the blanks. Field types can be text (with an optional WYSIWYG editor), an image, a file upload, a date, and anything else you can imagine. This again is where Drupal’s flexibility is both an advantage and a curse. The advantage is that a type of content can be anything you can imagine, but the downside is that someone has to configure that content type first. The field-based editing experience is provided by default to ensure the editing experience is consistent across different content types.

Here’s the important thing to know about Drupal. Drupal doesn’t like to make assumptions as to what your editing experience should be. As an example, a used car dealership, a national newspaper, and an online retailer will all have entirely different content editing requirements. Drupal doesn’t want to get in your way and it doesn’t try to. What it does do is give you a solid foundation to create YOUR ideal editing experience. This might not be ideal for organizations and businesses with simple website requirements, but for those with complex workflows and unique requirements, Drupal is ideal.

One last important note to make on this topic is that Drupal does also have a Gutenberg editing experience, it just doesn’t come packaged with Drupal out-of-the-box. This module and other editing interface modules and initiatives can be installed in Drupal to make the default editing experience more capable and modular.

Edge: WordPress

When based solely on out-of-the-box functionality, WordPress's pre-packaged Gutenberg editing experience is modern and intuitive for new and experienced users. However, it’s important to note that Drupal modules exist that greatly improve Drupal’s default experience. You can even add the same Gutenberg experience.

5. Editing pages

Once a page has been created, sometimes you still need to go back and edit it once in a while. This is a different experience from creating new content, so let’s now look at how it works with each CMS.


WordPress editing existing pages

Pretty standard, as a logged-in administrator you have access to editing content by viewing the page on the website frontend and using one of the various “edit” buttons. You’re then brought to the same Gutenberg interface that you see when creating content.


Drupal 8 edit existing pages

I would say Drupal has the upper hand for editing existing content. Similar to WordPress, as a logged-in administrator you have access to page edit links when viewing the content which brings you back to the same interface as when the content was created. However, in Drupal, you also have additional links to view content revisions as well as the view and edit page translations for multi-language sites.

Drupal 8 inline page editor

The current version of Drupal, Drupal 8, also includes an additional edit icon that contains a new “quick edit” option. Depending on the content, the quick edit allows on-page inline editing (shown above) instead of taking you to a separate page! This makes simple edits quick and easy. Furthermore, the edit icon also appears when administrators hover over menus and other configurable page elements too, giving you a quick way to access their configuration.

Edge: Drupal

While WordPress has the edge when creating new content, Drupal’s on-page inline editing feature makes editing existing content quick and easy by keeping content editors on the website frontend.

6. Managing widgets and blocks

Widgets (WordPress lingo) and blocks (Drupal lingo) are two words for essentially the same thing. While not limited to these locations, the header, footer and often left and right columns beside the main content area contain defined regions where certain elements can be placed. I’m talking about slogans, menus, a search bar, your copyright, recent posts, social feeds, etc. WordPress and Drupal have similar but different ways to manage these elements.


WordPress widgets page

WordPress includes backend and frontend methods for editing page widgets, both of which are quite basic and lack a lot of real capability.

The backend method (shown above) is accessed through the backend Appearance menu. This page gives you a nice list of available widgets on the left side and another list of active widgets within the available regions on the right. A simple drag and drop interface lets you move elements around and opening each widget allows for basic configuration.

WordPress widgets live editor

The frontend method is through a "Live Preview" mode (shown above) where a version of the site theme is presented and widgets are managed through the left column. Settings for existing widgets can also be quickly opened by clicking its blue edit icon, as you can see in the image above.

Out-of-the-box, it’s difficult to understand exactly where a widget will appear throughout the site because you don’t have the ability to see or control which pages accept the widget. Some third-party plugins are available to give you this functionality, but they must be added. New widgets are also a bit more difficult to add as they must be created by a developer or added through a plugin.


Drupal 8 block layout page

Like WordPress, Drupal has the ability to manage blocks from both the backend and frontend of the website, although Drupal handles both situations better.

The backend method (shown above) is accessed through the admin toolbar’s Structure menu. Here you can view all available regions and the blocks contained within each. Regions are a big part of Drupal theme creation, so you will often see 10+ available regions to choose from. If you’re not sure of your themes regions, the “Demonstrate block regions” link above the list of regions will give you a preview. Each region has a “Place block” button for adding new pre-configured blocks. Existing blocks can be moved dragged between regions and each block can be configured independently. Block configuration in Drupal is very robust, including but not limited to control over what pages the block is visible on and what account roles can view it. Like content, blocks can be translated and even have revisions.

Custom blocks can also be created by more advanced Drupal users in a similar way that new media and content types are created. In the screenshot above there is a link to the “Custom block library,” which is where new blocks can be created. Like WordPress, modules can also be installed which will add new blocks.

Drupal 8 frontend block quickmenu

Drupal’s frontend method for managing blocks takes on the same familiar editing experience that we discussed for editing content. When logged in and viewing the website frontend, navigating to a page and hovering your cursor over an element will reveal an edit icon if that element is a configurable block. Options for the block are then given. The block in the screenshot above contains a menu, so we see options to configure the block and edit the menu. In this case, clicking one of these options will take you to the backend page for performing these actions. If the block contained text, we would also be given an option to edit the text directly on the page, just like we can with content.

Edge: Drupal

Simply put, Drupal’s block management is robust yet not too difficult. Being able to manage existing blocks directly from the website frontend is both user-friendly and familiar given that existing pages can also be managed in the same way.

7. Managing menus

Menus connect the pages within a website. Commonly you’ll find primary navigation and some sort of footer menu, but menus are used in many other places as well.


WordPress menu management

The menu system in WordPress is a bit strange at first, but overall it’s pretty simple. You create a menu (or select an existing one using the menu selection dropdown), then add links by selecting pages, categories, or by creating custom links (add menu items in the image above), then use a drag and drop interface for moving and nesting the menu items (menu structure in image above). Each menu item within the menu structure can be opened for a bit of customization.

The menu settings area controls where the menu is displayed within predefined template locations. Just check the box and the menu will appear once saved. Any menu created here can also be assigned to the region as a widget or through the template live preview screen.

One odd thing I’ve found with WordPress is that, when editing a page, you’re not able to add it into a menu. I’m sure there are plugins that allow this, but out-of-the-box you have to add the page through the menu system or check a setting within the menu that all new pages get added… but then you might have to remove some.


Drupal 8 menu management

Drupal’s approach to menus is what I would consider more standard. You navigate the “menus” page which lists all of the menus that have been created, then you create a new menu or edit an existing menu. The screenshot above is what you see when editing a menu. Here you manage this menu’s links by either adding a new one or manipulating the existing ones. When adding a new link you can easily search for content that the link will link to or specify a custom link.

Pages can also be added to a menu when the page is being created or edited. Within the page settings, all you do is select the menu and specify a link title.

Like WordPress, once you create a menu you can then add it into a region of the site as a block. However, within the menu itself, you don’t have the ability to put the menu anywhere.

Edge: Drupal

A more standard approach makes managing menus clearer and more user-friendly. Also being able to choose if a page should be included in a menu while creating the page is a nice feature. That said, I appreciate being able to manage a menu in its entirety on a single page as you do in WordPress.

8. Managing users, roles and permissions

Managing users is common for both controlling who can edit the website and who can log in for other reasons, such as non-admin accounts for an online store or community.


WordPress user management

WordPress has six predefined user roles: Super Admin, Administrator, Editor, Author, Contributor, and Subscriber. Each has varying degrees of what they can do, but it’s pretty clear for the most part and goes back to when WordPress was mainly a blogging platform. Users can be created and managed through a “users” page (shown above), which is laid out in a straightforward manner displaying

But WordPress has some major drawbacks here. First, WordPress doesn’t have any frontend user self-management, meaning users can’t view or edit their own profiles. Second, the predefined roles and their associated permissions don’t work for everyone and actually complicate user management when you don’t need it. Third, there is nowhere to really manage role permissions in a granular way. These drawbacks can be fixed through custom development and/or various plugins, but many consider this to be a general weak point of WordPress.


Drupal 8 user management

User management is another area where Drupal shines. In contrast to WordPress, Drupal only starts with three default roles: Anonymous, Authenticated and Administrator. Anonymous is a user who is not logged in, authenticated is a user who has an account but isn’t someone who typically isn’t managing content and site configuration, and administrator is a user with the full site and admin access. These three roles are minimal, clear and cover all of the basic needs of most sites. If and when another role with different permissions is created, this is easy to do right out of the box.

The image above shows Drupal’s version of the current list of users. It follows a similar look and style to the rest of the admin pages, giving administrators a place to add and manage user accounts, including assigning users to specific roles. Anonymous and authenticated users can also create or manage their own accounts through the website frontend (although this functionality can be turned off if desired).

Drupal 8 user permissions page

Drupal’s strength in user management comes in the form of roles and permissions. When a role is created, a column of permission checkboxes for the role is added to the Permissions page (shown above). Almost every piece of functionality within Drupal has associated permission. Simply checking the boxes determines what each role can and can’t do. It’s powerful and easy.

Edge: Drupal

A simple yet powerful user management system combined with frontend self-service functionality gives Drupal a clear edge over WordPress.

9. Site status report

Both WordPress and Drupal include a site status page that gives you information about the website and server configuration as well as an overall health report that outlines any issues. These automated health checks help keep your CMS up-to-date and secure.


WordPress site health page

The “Site health” page (shown above) gives you an overall health status and a list of any issues. This status page is clean and each item can be expanded for more information, but there is no visual urgency that makes the “2 critical issues” stand out. In my opinion, critical issues should be resolved and so highlighting these issues in some way is a necessary UX improvement.

An info tab at the top of the page can be opened which gives more information about your installation of WordPress, the server, the PHP version, and the database.


Drupal 8 status report page

Drupal contains both site information and site health in one “Status report” page (shown above). Like WordPress, this page gives you everything you need to know at a glance about your Drupal installation and the other components that make it run. Here we can also clearly see what errors and warnings have been found and some information on how they can be resolved.

Edge: Drupal

While both WordPress and Drupal have similar pages that show similar information, Drupal’s status report does a better job at laying out the information and visually capturing the severity of any issues.

10. Plugins and modules

Plugins (WordPress lingo) and modules (Drupal lingo) extend core CMS functionality and add new features. Extensions are usually created by third-party developers and released to the platform communities for anyone else to use. Whether it’s to increase performance, enhance SEO capabilities or create an online store, extensions are a powerful way to improve and adapt the CMS platform.


WordPress plugins page

Visiting the “Plugins” page (shown above) is a quick way to see what additional plugins are currently packaged with your WordPress installation and can be activated if desired. The plugins shown here all provide some sort of new functionality or feature that is not part of the core WordPress software.

WordPress plugin search page

When you need new functionality, WordPress provides an excellent and convenient plugin library browser (shown above) accessible within the website backend. Here you can search for, view, and install plugins easily with the click of a button.


Drupal 8 extend page

Drupal’s module list is where you can see all current extensions, activated or not, for your Drupal installation. The big difference here between WordPress and Drupal is that for Drupal you are able to see all modules installed, even those that are part of the core software. Modules are also nicely grouped which nicely organizes the large list.

Installing new modules isn’t nearly as easy in Drupal. Unlike WordPress, Drupal doesn’t include a module library browser within the backend interface. Instead, users must search for modules within a web browser and manually install them. Finding modules can be difficult if you’re not familiar with the process.

Edge: WordPress

While both platforms have a massive library of extensions, WordPress offers users a much friendlier and intuitive way of finding and installing extensions that users of any skill level can appreciate. This may or may not be an issue for you if you have a capable IT team or development partner, but for small teams, WordPress has the clear edge.

WordPress & Drupal comparison summary

I hope after going through this comparison you now have a good understanding of the differences and similarities between WordPress and Drupal. As you can see, both platforms out-of-the-box have different strengths and weaknesses, but it’s important to know that all of the weaknesses can be overcome through platform extensions and experience. In extreme cases, both platforms support custom development to overcome unique problems.

For convenience, here is a quick summary showing which CMS has the edge in the 10 categories compared. However, I would recommend that you go back and read the edge summary for each category if you haven’t done so already.

Comparison category WordPress Drupal Admin toolbar   ✓ Login dashboard ✓   Managing media ✓   Creating pages ✓   Editing pages   ✓ Managing widgets and blocks   ✓ Managing menus   ✓ Managing users, roles and permissions   ✓ Site status report   ✓ Plugins and modules ✓  

A final word of advice

In my opinion, you shouldn’t be turned off from one platform or the other simply because you’ve heard that one is better or easier to use. Both platforms are mature and constantly improving, user experience is top of mind, and usability gaps have become less of an issue in recent years.

My advice, select the platform you use based on your requirements. WordPress is a great authoring tool and is good for small and medium-sized organizations. Drupal is fantastic for medium and enterprise organizations or anyone who has complex workflows, products, and/or a need to integrate with other platforms. That’s a pretty general summary, but if you’re considering either of these platforms, first know what your requirements of the platform are and then start talking to the experts for each.

Acro Media is an ecommerce consultation and development agency that can help you in this regard. We specialize in open source ecommerce and a large part of our work is based around Drupal. Drupal typically works better for our clients but we know WordPress, too. If you’re researching your requirements or evaluating your options, hit us up for a quick chat, we would love to help. Otherwise, check out some of these related resources.

Contact Acro Media Today!

Related resources

Sep 07 2021
Sep 07

The Coffee module adds quick search functionality for backend pages in Drupal. The module was inspired by the Spotlight app on MacOs and Alfred.

Coffee makes it possible to navigate quickly through backend configuration pages by just searching for them instead of using the toolbar.

Table of Contents

Getting Started

Before we begin, download Coffee by running the following Composer command:

composer require drupal/coffee

Then go to Extend and install the module.

How to use Coffee

To display the pop-up window, use alt+D (or alt+K) for Windows or opt+D for MacOs.

Start typing the page title, and you should see results returned, then click on one of the returned results and you’ll be redirected to the page.

You can also display the pop-up by clicking on the “Go to” link in the toolbar.

Jump to Create Page using :add

Furthermore, Coffee facilitates opening a new page or article for you, just type “:add” and choose an article or a basic page. You can also go to the front page by typing colon only.

Module Settings

You can configure the module by going to Configuration -> Coffee (/admin/config/user-interface/coffee).

Here you can configure which menus will appear in the results and the max number of items returned. By default, it’ll only show a max of 7 results.

Module Permissions

The module comes with two permissions:

  • Access Coffee: This allows you to use the Coffee functionality.
  • Administer Coffee: This allows you to configure the module.

If you have an editor role and you want them to use Coffee then assign them the “Access Coffee” permission.

Change Keyboard Shortcut

Currently, you can’t change the default shortcut key from Command/Ctrl/Alt-D. There is, however, a patch for the module if you really want to do it.

If you want to define your own commands in the Coffee module using (hook_coffee_command); see coffee.api.php for more documentation.

Alternative to Coffee

The Admin Toolbar module comes with a quick search functionality which is similar to Coffee. You can learn more about this by reading the “Add Quick Search and Drop-downs to the Toolbar using Admin Toolbar in Drupal” tutorial.


The Coffee module offers handy functionality especially if you spend a lot of time administering Drupal sites.

The ability to quickly jump between pages can speed things up and make you more productive.

Aug 30 2021
Aug 30

open waters podcast logo

In this episode, we're joined by Damien McKenna to talk about open source security and how that has changed over the years in Drupal core as well as in newer versions of Drupal. Damien directs internal initiatives that strengthen Mediacurrent’s commitment to open-source principles, collaboration, and sharing knowledge to strengthen the Drupal community and is regularly ranked as one of the ten most active contributors on drupal.org.

Episode Transcript

Mark Shropshire: Hi, I'm Mark Shropshire and with me is my cohost Mario Hernandez. We are very excited about this episode of the Open Waters podcast as we welcome Damien McKenna, a prolific Drupal contributor and community leader. We will be talking about open source security, specifically the ins and outs of Drupal security.

Mario Hernandez: Thanks, Shrop. Thank you very much, everyone, for joining us and a special thanks to Damien for joining us today to talk about security and contribution to the Drupal project. So Damien, before we get started into the technical aspects of your role, why don't you tell us a little bit about your role on Mediacurrent and your involvement in open source?

Damien McKenna: Thank you for having me. So I've been involved in Drupal since 2007, but open source as a whole, since around about 2000. I got into it because I had been building my own websites that expanded into building custom content management systems, and I realized I couldn't be the only person who wanted to have a simple CMS to manage their site's content or their clients' content. Discovered hey, there's a whole bunch of people who were uploading complete open source, complete PHP projects, as they were at the time to the net on SourceForge. I can just download it and customize it how I need.

Over the years, I saw a number of patterns emerge with open source communities. A big one was that for any given software project, if it didn't have a security team put together fairly early on, they would need one fairly soon. I saw so many projects that didn't have decent security practices and they eventually ran into a major security problem and had to scramble together the processes to deal with it properly. So I've been very glad that Drupal started their security team fairly early on, and it has been continuing ever since. So at Mediacurrent, I juggle both being a backend developer and project lead along with I lead, cat herd, on some internal initiatives around open source offer and contributing. We try to have a contrib first process so that we are contributing back improvements and things to open source communities and software when it's suitable rather than leading projects to have to maintain more and more custom code and documentation and things.

Mario: I'm gonna go with a follow-up question on that because that's very important what you just said there, Damien, the contribute first. So does that mean when you are tasked with analyzing the project that you about to work on, do you figure out ways in which maybe through this project you can contribute to the Drupal project or the open source in general? Or how does that work?

Damien: Exactly. So there are lots of different situations where it comes up. One example was a few years ago, one of our clients needed to have, requested documentation on how to set up their site to be able to pull in tweets from their Twitter account. And it was just when Twitter had changed the API process. So you used to be able to just pull an RSS feed of the tweets and they changed it to needing to set up a developer account and this custom application in their system.

And it was a bit elaborate and you had to do it from the account that was pulling the tweets because of security best practices. You didn't want to be sharing around these passwords for everybody to log into your Twitter account and accidentally post some screenshot of a picture of a meal out or being with some friends accidentally to a business account. So we put together documentation on how to go through the steps with screenshots and everything, but instead of putting it into a document and sending that to them, we uploaded it to the documentation section for the project that was being used to pull down the tweets so that everybody could then have the same documentation. It was the same amount of work, it was just putting it in one place versus another. So the client appreciated it, they had all of the details they needed, and then everybody else in the world who ran into the same situation then could benefit from the same work.

Shrop: Yeah. That, that's, that's a fantastic example. I mean, I know you have a lot of examples of contrib first, Damien and, personally you're a mentor to me and I appreciate all the guidance you've given me over the years and continue to on how to work in open source overall, but also in the Drupal community. And so I just want to say that I appreciate you and everybody else that does that for the community. It's, it's really great. So I want to jump a little bit into your involvement with the Drupal security team and I think that's an interesting aspect here, since we're talking about open source security today, what's it like being on the Drupal security team and then from a day-to-day standpoint? I know there's lots of things that you have to embargo til advisories come out, but you know what you know, what's it like day day-to-day, what's it look like?

Damien: Sure. So we have different processes that we've, for the most part, documented on drupal.org/security-team. There's lots of details in there, but we have a team of, I forget if it's 20 or 30 so odd people, and one step, I guess, an initial starting point is that we take turns being the initial point of contact. And as it happens, I'm on duty for the next two weeks, so timely. What that means is when somebody opens a security issue for a project, module, theme, or even Drupal core, that we're the first person to respond to that, to review what is submitted, and try and do a little bit of analysis on maybe the person just had one of the settings misconfigured. Maybe they have the PHP module enabled and they're inadvertently letting anybody write PHP code on their website.

Not that that has ever happened, but we do an initial bit of triage on the issues that are opened and then get the maintainers involved, presuming that it requires it, presuming it's a legitimate issue. And then try to guide the conversation between the maintainers and the person who reported the issue and potentially anybody else who's pulled into the conversation. So we might have an issue that is focused on the control module, but it might say affect core or affect somebody in the backdrop community as well, because there's a lot of overlap between the two. Occasionally there might be an identical issue for a similar module, and we try to get conversation focused on moving towards a solid, reliable fix, and then work with the maintainers to prep for release. We also have a mailing list where people can post questions to.

And that is often used as a step towards then having a proper issue in our security issue queue. So then it's, whoever's on duty then is the first person to respond to questions when they come in.

Shrop: How many of those do you think you get in a given week?

Damien: On average, not too many new ones each week. One thing that I found is that sometimes you'll have, especially in the contrib world, somebody will spot...Hey, there's this one situation where this module leaves a security vulnerability open or vector open, and they'll go and check some other modules that have, say, similar functionality or some similar approaches and then they'll, they might discover, say five modules have basically the same bug. But that doesn't happen very often.
Mario: What would you say is the most common security and the Drupal open-source work?

Damien: So the most common one is cross-site scripting, and this is going back to, at least a few years ago, there was an article published on Wiley by Greg Knaddison who wrote the book Cracking Drupal, and he went through and cataloged at all and cross-site scripting was the most common by a good margin where basically the output from a field or some data input was not being properly filtered during display, o that would leave it open for somebody to, say, throw in some JavaScript that would then get executed when the page was viewed. And so that one comes up quite often, and there are some relatively simple means of fixing those bugs. Biggest issue I found is forgetting where in your code something might be filtered already by the time you get it at this one piece.

So sometimes you've got a settings form and it might be available to people who aren't administrators, and you might forget to filter the output because somebody who's an administrator to the site is kind of assumed that they're not going to cause problems for that site. Generally, as a company, employees, don't go bananas and start throwing filing cabinets around. Likewise, they tend not to start throwing in a really bad JavaScript into a site for the purposes of stealing data, et cetera. It's technically possible, I'm sure it has happened, but tends not to happen. So when you're writing code or writing code for a site or for a project, or for a module, you might forget in this one situation, I'm outputting a variable or a configuration object or something and you might forget to filter that one time because when you're testing it, you never try throwing in JavaScript because what silly person would do that? But from the point of view of trying to keep it secure, you need to cover for the situations where somebody might want to do that.

Shrop: If you can execute JavaScript on a site, it's pretty powerful.

Damien: Yes. It's not as bad these days, because Drupal Core and eight and nine don't have the PHP module in core anymore. It was a lot more dangerous when the PHP module was in core because there were so many situations where people inadvertently had that available to all text fields including, say, a comment box for submitting a comment to the webmaster or owners. Yeah.

Shrop: Oh, wow. Yeah, you can think of all kinds of terrible situations that could come with that. Like just reading the settings file in PHP or something. Well switching gears just a bit, because I'm always interested in this and, as you know, in our teams at Mediacurrent, we, we have discussions, we have a security channel in Slack where we discuss when a security advisory comes out, we're always wanting to read it and dissect it as a team and figure out like, all right, what are our next steps for those? Are there mitigations and things like that? I'd love to hear from your standpoint, Damien, in your expertise around this, tell us a bit about those Drupal security advisories and the details they contain. And I mean, just curious about, you know, that coverage for that. I know it's well-documented but there is a lot of information in these advisories, right?

Damien: So there's always a balance between giving enough information and giving too much because you don't want to give people who want to write scripts to attack sites step-by-step instructions on how to do that. You just want to kind of give enough clues that people who are maintaining sites can tell whether or not this is going to affect them right now, and that they need to update right now ahead of anything else they're doing versus, say, it can be just included in the next scheduled deployment.

That could be a week or three from when it comes out. The security advisories will try to give some at least hints on what causes the vulnerability and then, if there are any available, some details on how it can be mitigated. So sometimes it'll be the security problem only happens if you turn off these options or if the person does not have a particular permission. So we'll indicate in the advisory any workarounds that might exist. Oftentimes there won't be obvious workarounds that are feasible, so the only step is to just update the module or theme or whatever it is, or core. We used to do one security advisory per project per week. So per week that there was a security update. So if there were multiple vulnerabilities, they would all be lumped into one security advisory. That policy was changed so that every individual security issue gets its own advisory. And that was to fit with industry standards because Drupal was, I think, just about the only major project still doing it that way.

Shrop: But from my standpoint, it's made it easier for me to comprehend what's going on. I can, you know, read one focus on it. All right. How does that apply mitigations? Are there any, and then you just move on to the next one. And so that's been great from my standpoint.

Mario: Switching gears a little bit here, Damien. So we know that with the release schedule that Drupal has in place, you know, there's a lot of benefits and people have seen things improve, you know, once the new release schedule was implemented. But can you tell us how these release schedule has helped with security, with the Drupal project?
Damien: The schedule has really helped from the point of view of having a plan or a schedule ahead of time that, you know on certain days of the month or certain months of the year, you're going to have security updates available.

Damien: So every Wednesday, starting by the simple thing of all of the security releases are done on Wednesdays. Almost always. There can be some occasional out of schedule updates when there's, say, a third-party library or something that has an update, and we have to scramble to do a core update on a different day, but almost always they're on Wednesdays. And then the core updates are done on one day and contrib updates. So one day a month, there's a window for core to have security updates, and if there isn't one on that day, then there won't be that month. Again, unless there's some or some other issue with a third-party library. And so site maintainers or site owners have a bit of relief knowing that there isn't, almost isn't, going to be a major security release dropping any time of the week, any time of the day, so they can rest easy and just go about their normal business the rest of the week, the rest of the month, and just be able to plan Wednesday afternoon, timezone depending, they will have to do some security updates.

Mario: Good. So what's the story with the Drupal eight reaching end of life? What's, what's going on there?

Damien: Well, it's a standard thing that, or it always has been a standard thing that when a new major release of Drupal core comes out, that the previous release goes into kind of a security updates only mode and then the version before that is marked as end of life so that there won't be any more security updates on that, and pretty much at that point, the community stops maintaining core and contributed modules and themes for that version. In practice, (it) historically meant when triple seven came out, that Drupal five was no longer given security updates and support. When Drupal eight came out, I think it was like eight years after Drupal seven, sorry, after Drupal six had been released, they gave and, if I remember correctly, they gave an extra six months of support just to help bridge the gap of time for sites to upgrade because the development cycle from seven to eight had been so long.

But then, when Drupal nine came out, Drupal seven was still around and still had support. When Drupal 9 came out, the majority of Drupal sites were still on Drupal 7. I forget if it was like two thirds or so of the sites in the world that were on Drupal were still using Drupal seven. So we couldn't just say no Drupal seven is not going to have anymore support, io it was given extra support. Then the plan is that Drupal Ten is going to be released next year, and so there's the knock on effect of you need time to upgrade from core version to core version. And so Drupal eight will be, we'll reach end of life this year. The nice thing is that upgrading from eight to nine is a very, very simple process, especially in comparison to previous sites or previous versions.

We've done some upgrades where a site was fully up to date on contrib modules and was able to be upgraded to from eight to nine with just a few hours of work, and most of that was just poking at Composer to get the right combination of dependencies.

Mario: You're saying that Drupal seven's end of life is actually going to happen after Drupal eight's end of life, yes?

Damien: Yes. So Drupal eight's end of life is tied to the dependencies it has, and its dependencies will run out this year. So I think, it's the big dependency that is causing it is Composer.

Shrop: I think Symphony symphony is part of it, too.

Damien: Composer, symphony. Yes.

Mario: So these end of life decisions are made mainly based on those dependencies, in the case of Drupal seven, it was probably because of the, the adoption that Drupal seven has had gotten, yeah?

Damien: The reason for continuing to support Drupal seven was because of the volume of sites out there that had not upgraded yet and because there wasn't the technical requirement. The dependencies for Drupal seven were still continuing for longer. Drupal seven had fewer third-party dependencies than Drupal eight. So it's easier to say, yes, we're just going to continue it.

Mario: And the future that as the dependencies get shorter and shorter, right, that the actual analyze for future versions may even become shorter than what they are now, perhaps, especially if the upgrade path is such, that is seamless there becomes time where it's just a matter of upgrade and the next installing the next update. And now you're in the next version.

Damien: Yeah. So, keeping a site up to date with the latest version of core, for the major release that you're using, and then keeping all of the contrib module updates, will ultimately mean that it doesn't matter if it's six months or three years between major versions, if it's up to date and you keep it current, it should be a relatively straightforward process. So Drupal eight will hit its end of life this November. Drupal seven has an extra year of support to November '22. So there will be more time for sites to finish upgrading to Drupal nine at that point.

Shrop: I'm glad you mentioned that. They'll just, that'll be the recommended path, just to go straight to nine. You, you won't even have to go through eight at that point, or actually even today, you'd want to go, I think (Drupal) ten is in June, June next year. Yeah. So, so it's moving fast, but it, and I'm glad you mentioned that, Damien, that the upgrade paths are smoother, and that doesn't mean a complex site could have some complications and if you haven't kept things up to date, but from any of us who've been in the community a long time, it, you really don't have to approach it like we're going to build a new site and then migrate all the content. Now it's like actually true upgrades and there's migration paths and it's really great.

Damien: Yeah. So it's more of a traditional once you get onto Drupal eight, plus it's more of an upgrade rather than a rebuild. That's the last major upgrade. Yeah.

Shrop: So get up, get on the new Drupal train then, and I think train is a good visual representation that the community's used to illustrate the end of life for some of these, the train tracks end at a certain point, you want to be on the train track that keeps moving forward. Damien, what kinds of Drupal security resources do you think folks listening should know about?

Damien: So the most important one, I would say, is the security advisory newsletter that everybody can subscribe to off of their profile on Drupal.org. There's just a nice, if I remember correctly, a nice checkbox for that. The security advisories are also available through an RSS feed, and they're also published on Twitter through the website. There are separate feeds for core, contrib, and public service announcements.

So depending on how you like to get your security updates, do all three. Then there's also, as mentioned before, documentation on the security team's processes, and under the Drupal eight documentation, there are pages that describe best practices for writing secure code. So you can avoid security problems while you're building the site rather than dealing with them later. There are a number of books out there, most notably the Cracking Drupal book by Greg Knaddison mentioned earlier. It was written before Drupal eight came out, so it's a bit out of date, but the general practices are still reasonable. And for every function it mentions, you can find the equivalent Drupal eight or nine replacement through documentation online.

Shrop: Well, Damien, we really appreciate your your time on the podcast today and for coming on and talking about, you know, specifically Drupal security, but also, you know, a lot of these concepts, like you were mentioning about Greg's Cracking Drupal book, you know, security is evergreen, it does change over time, there's maybe new things, of course, we learn about securing our systems, but some of those old things are still out there like cross-site scripting. They just are probably going to be for a long time.

Mario: They don't go away.

Shrop: Yeah, exactly.

Mario: Well, Damien, thanks again for joining us today and sharing with us your expertise when it comes to security and the Drupal project. I also personally want to thank you for always being available and helping us with any security or contrib questions that we have. You recently helped me contribute to a project, and that was pretty rewarding to be able to do that.

Damien: You're very welcome.

Shrop: Thanks for listening. You can find us at mediacurrent.com/podcast and subscribe with your favorite podcast app. If you enjoyed this episode, share it with your friends and tag @Mediacurrent on Twitter. For more resources on open source technology, web design, and web strategy. Visit us at mediacurrent.com.



Aug 24 2021
Aug 24

Linkit gives you an easy interface with an ‘autocomplete’ field to search for content on your site, and then link to it. In other words, it provides search functionality to find the content on your site and insert the corresponding internal link.

Using the same interface, you can also insert external links. So you can insert links, both internal and external, with the same interface.

It supports internal links to nodes, users, taxonomy terms, files and comments, etc. With this module, you do not need to copy or remember the target URL, or go back and forth to find out and verify the exact link. It provides a more user-friendly interface well integrated with the insert link function of the editor.

Table of Contents

While working on links, you will find that you need something more, such as the option to open the link ‘in a new window’. You might as well also install another module called the Editor Advanced Link, which is another popular module which provides enhanced features for inserting links. For this reason, it is recommended also to install this module at the same time, to make it more complete.

In fact, it was also mentioned in the project page of the Linkit module that, starting from version 8.x-5.x, support for link attributes has been removed, and this Editor Advanced Link module is recommended there.

Getting Started

Installation of the Linkit module is easy. There are no extra requirements. Just follow normal module installation procedure. However, note that there are different versions in this module. At the time of this writing, there are:

  • 6.0.0 which requires Drupal 8.8 | 9
  • 8.x-5.0 which also supports Drupal 8.8 | 9
  • 8.x-4.3 which supports Drupal 8 prior versions
  • 7.x-3.6 for Drupal 7

If you are running Drupal 8.8 or above, we suggest installing 6.0.0 or later. For older versions of Drupal 8, you should install version 8.x-4.3. In this article, we shall focus on the latest 6.0.0 version.

Installation using Composer

If you follow the normal Composer installation, like

composer require drupal/linkit

ft will install version 8.x-4.3 by default. To install the latest version of the module, which is recommended, you need to specify the version in the Composer command:

composer require drupal/linkit:^6.0.0-beta2

Enable the Linkit module after installation.

Installation of the Editor Advanced Link module is straight forward. There are no extra requirements. Just follow normal module installation procedure.

Installation using Composer

Install using Composer:

composer require drupal/editor_advanced_link

Enable the Editor Advanced Link module after installation.

Configuring the Linkit Module

Configuration of the Linkit module is a little bit different for different versions of the module. In this article, we shall focus on the latest version 6.0.0.

1. Go to Configuration > ‘Content authoring’ and click on ‘Text formats and editors’

2. Click on Configure on the text format you’re going to use. In this example we’ll click on Configure on the “Basic HTML” row.

3. Enable Linkit under the ‘Enabled filters’ section by checking ‘Linkit URL converter’

4. Scroll up back to the ‘CKEditor plugin settings’, and select the ‘Drupal link’ tab. Make sure the ‘Linkit enabled’ option is checked, and then select the appropriate ‘Linkit profile’. Let’s choose the ‘Default’ profile for now. For more details about Linkit profiles, it will be covered below later.

After this configuration has been completed, linkit will be available for users.

How to Use Linkit

Users normally create content in the long text format fields using the default Drupal editor. To insert a link, you first highlight the text and click on the ‘Link’ button, and an ‘Add Link’ window will popup and there you can enter either an internal or external link.

You can see the small text under the space in this popup window, it says ‘Start typing to find content’, because it is now an ‘autocomplete’ field, which is enabled by the Linkit module.

If you are looking for the link to another internal content on the same site, just start typing with the title or keywords, and the system will automatically search for the matching content:

Here you just select the right content, and the system will insert the appropriate internal link for you into the editing text.

Note that these figures show the scenario without the Advanced Editor Link module enabled.

After installing and enabling the Editor Advanced Link module, an extra attribute ‘Title’ becomes available by default.

The ‘Title’ attribute, when entered, will appear when you hover over the link.

There are other attributes available apart from ‘title’, but they are limited by the ‘Allowed HTML tags’ setting in the Basic HTML editor configuration. These other attributes need to be enabled before you can use it.

To enable the other attributes from this Editor Advanced Link module, go to

1. Go to Configuration > ‘Content authoring’ and click on the ‘Text formats and editors’

2. Click on Configure on your text format.

3. Scroll down to the bottom and find the Filter settings. Select ‘Limit allowed HTML tags and correct faulty HTML. There you can find the attributes allowed associated with the tag for links. After the Editor Advanced Link module is enabled, the following allowed HTML tag reads:

Here you can find the attribute ‘title’, and that’s why it is available by default.

4. To enable the ‘target’ attribute, you can modify this allowed HTML tag by inserting the tag as follow:


And then save the configuration. After that, you will find the extra attribute in the popup window:

With this ‘target’ attribute, you can configure the link to be opened in a new window or a new browser tab.

If you are an advanced user, you may add more available attributes to the allowed HTML tags for additional attributes. They include the following attributes highlighted as bold. Each represents a separate attribute corresponding to different CSS elements.

target class id rel</strong>>

We shall not go into details for these other attributes here.

Create Additional Linkit Profiles

Additional Linkit profiles can be created:

1. Go to Configuration > Content authoring and click on ‘Linkit’

2. From this page you can create and manage all your Linkit profiles. To create a new profile, click the ‘+ Add profile’ button, then enter in a “Profile Name”.

3. Click on the ‘+ Add matcher’ button to continue

4. Select a matcher from the list. When you search the content by autocomplete in the URL field, this is the entity you select here which the system will search from.

5. After selecting the matcher, you will arrive at this following page for additional configuration for this particular matcher.

6. Enter the ‘Metadata’ in the form of ‘tokens’. Metadata is additional information to be displayed in the autocomplete list of search which helps content creators to better identify the right content to select. Click on the ‘Available Tokens’ to display the list of tokens you can choose to configure. This list is based on what matcher you have chosen above.

As an example, following is the metadata field in the default profile for ‘content’:

by [node:author] | [node:created:medium]

which adds the name of the author and the date created to the list of autocomplete search. When searching in the URL field, it will look like this. The small text comes from the ‘metadata’ configured.

7. Complete other settings or you can leave them as default, then Click ‘Save changes’ to save this matcher.

For each profile, you can add additional matchers for different types of content that are allowed. Following is an example of multiple matchers created in a single profile, which allows content creators to search for different types of content entities. Each matcher will be configured with different matching metadata to display. This will make the content searching much easier.

In this example, matchers include content, users, taxonomy and media items (if the media module is enabled).

8. Do not forget to select the right profile in the target text format editor:


The Linkit module, together with the Editor Advanced Link module, provides a user-friendly interface for inserting both internal and external links.

The Linkit profile allows you to configure the appropriate metadata which appears when searching for content. This is helpful to content creators to accurately locate the appropriate content in the autocomplete search.

These 2 modules together allow us to provide a very nice user-experience for the content creators, and make life easier for them.

Aug 19 2021
Aug 19

End-of-life (EOL) software is a very real problem. Whether your business is using ecommerce and customer relationship management systems across multiple platforms or relying on basic scheduling and accounting software, you will at some point reach a technological expiry date.

Listen to this post by using the player, or subscribe using Spotify, Apple Podcasts, or Google Podcasts.

Acro Media has developed a 6 step action plan for handling software end of life. View it here >>

When a system reaches end-of-life, the creator/owner of the software/technology no longer delivers support services for the product. That can include technical support, hardware or software upgrades, bug fixes, security patches, or feature development. In short, the system gets abandoned by its owner. 

Software becoming obsolete can cause all sorts of problems. Here are a few of the  risks to your business in running EOL software:

1. Compromised security

If you hold people's information and data, you are responsible and liable for it.

End-of-life technology receives no security updates. No bug fixes. No patches. No monitoring. Your technology is dead in the eyes of the creator. That means your security is completely compromised, not only for the platform that is EOL, but also potentially for any others that connect to it.

At a minimum, your system can be accessed and your content or records edited, stolen, or deleted. If you have any user data, financial data, or sensitive information, you could have a major problem. The monetary and reputational costs could kill your business.

A survey of 2,600 CIOs across the U.S. found that the number one concern was keeping systems and information secure. By being proactive and not letting your systems reach their end of life, your company is better positioned to ensure that your data and your customer’s information remains secure.

2. Lack of reliability

If you were a taxi driver, would you willingly drive an old car that is no longer maintained and has sporadic issues? Of course not. That’s because your livelihood relies on the economics of your vehicle. 

But that is what you are doing if you continue with EOL software. Old software is less reliable and more prone to failure. 

Maintaining EOL software is complex and expensive, and integrations into other systems require even more time-consuming and expensive workarounds. 

Regular updates, bug fixes and support, in general, goes away at EOL, which makes system maintenance much more difficult. Instead of spending your resources on new tools or building better customer experiences, you are stuck paying top dollar for fixes and updates no longer covered by the software creator.

This brings us to our final point...

3. Higher operational costs

EOL software costs more, whether it’s through lost/stolen data, updating and maintaining with third parties, legal liabilities, or lost revenue from downtime or issues. 

The sticker price on a new system can sometimes seem large and prohibitive from a business point of view. But, consider the consequences of a security breach or a major bug. The peace of mind that comes with having a fully secure and supported system that won’t arbitrarily go offline is worth its weight in gold.

Another benefit from moving away from EOL software is the opportunity to review your company's entire technology stack/architecture. If you have software moving towards EOL, it's essential to look at not only replacing the single system but also assessing your whole technology landscape for opportunities to make larger improvements.


Ultimately, EOL technology is costly to your business in multiple ways. Most technology providers give lots of notice when one of their products is going to be unsupported. That gives you time to assess your options and determine the path you should take. 

To help you assess your options download our 6 step action plan for handling software end of life.

Download the End of Life Playbook (PDF)

Editor’s Note: This article was originally published on June 2, 2020, and has been updated for freshness, accuracy and comprehensiveness.
Jul 27 2021
Jul 27

open waters podcast logo

Open Waters Podcast: Season 2, Episode 4 

In this episode, we're joined by Randy Fay from DDEV to discuss features and benefits of DDEV, the future of the project, and how you can get involved with contributing to the Drupal community. Randy provides his perspective on DDEV and the ways in which both developers and non developers can use it for projects.

Episode Transcript

Mario Hernandez: Hello, everybody welcome. We are very excited here. Shrop and I are very excited to have with us, Randy Fay, who will be talking to us about DDEV and what's coming down the pipe with that. We are very excited about that because we here, at Mediacurrent, use DDEV for most of our projects, and we are loving the product and looking forward to what's coming ahead. So thanks for joining us, Randy. We appreciate it. We just had you actually do a knowledge share for our team, our development team, not too long ago. It was just last week. I believe it was. And now you're back with us. So we appreciate you taking the time from your really busy schedule and talk about DDEV. There is some great news happening with DDEV, but before we get into that, tell us a little bit about your role today and how you became interested in open source. What brought you to this point as a prolific maintainer of a key piece of open-source software like DDEV?

Randy Fay: You bet, I'm glad to be here. Again, my name's Randy Fay, I'm R. Fay most places, Randy Fay some places, and I live in far western Colorado, right near the Utah border in a little town called Palisade. And I ended up here because my wife and I took a long bicycle journey through the Americas from 2006 to 2009, and at the end of that time, my parents were getting old and we decided to come, you know, take a turn. Our turn history ended up being quite long now, but take a turn with helping them out. And so that's, that's where they were and that's where we are. But the open source thing is, of course, when we took two and a half years out of our life to do bicycle touring, there was going to be a change when we got back, and I've worked in various kinds of software development since the early eighties, but of course, like everybody else, I got more and more excited about web stuff and I'd never, I benefited from open source over the years.

Randy Fay: I've done lots of, you know, Linux work over the years and all that kind of thing, but I benefited from open source, but never contributed at all. And so one big thought was, well, how could I, how could I figure out what this open source thing is? And so when we were restarting our life after our bike tour, Drupal was there. I felt like I had some idea what was going on with Drupal. And I said, well, maybe I could figure out how to contribute to Drupal. And you know, how Drupal is, if you stick your finger in there and you figure out who the players are, you will be sucked in. And you know, you can spend the rest of your life...just working on that. And I did that for a couple of years and had had a great time, met wonderful people and got very involved in the Drupal community, but it was Drupal that brought me into the open-source world.

Randy Fay: So anyway, so I did that for a long time and then I burned out pretty good. I even did a whole series of sessions at a Drupalcon and stuff like that on burnout. And I got flamed out pretty good. Couldn't do it anymore. Worked on various things for a few years, but about maybe five and a half years ago, something like that, I went to work for a company named DRUD that was developing a Golang Kubernetes hosting product. And they also had DDEV going, although it was very much in its infancy, and I really liked DDEV. I liked it a lot more than the hosting part. Maybe because, I don't know, I just, I just liked it a lot. And I started to feel like it was useful and they were amazingly generous. They just let me go ahead and maintain DDEV for, it must have been at least four years and paid me to do it and rarely asked anything in return. Every so often they'd want some kind of integration with the process and that kind of thing. But that's how I ended up maintaining DDEV and got to continue doing that through their amazing generosity. That was a long answer to a short question.

Mark Shropshire: That's great. I love hearing these stories, you know, about how people get to where they are today, because, you know, it's also humbling to hear these stories, but you know, Randy, when I've interacted with you, it just amazes me how quickly you respond and support the community. And you're just always had such a great positive attitude. But you seem like this, this huge persona, you know, coming in like that, like the maintainer of DDEV and they got real personal with Mario and Shrop and helped, helped us with our problems and all that. But it's great to hear just this real human stories. There's, there's the human behind the keyboard, right?

Mario Hernandez: I can definitely attest to Randy's generosity with helping. I mean, no matter what I ask him, he's always there. He never judges, is always willing to help and has got me out of some pretty big holes with things that I work on with DDEV. So that's excellent to hear.

Randy Fay: It's lovely being a member of a community where you feel like you have something useful to do. I mean, I, I love it when people ask questions and everybody is at a different place. I mean, there's so many things going on in our heads, trying to understand all the different technologies we're working on, and there's so many different layers of all those technologies. It is astonishing and crazy. And so we're all at a different place and how much we understand on those. And so it's, it's always great to work with people at whatever level they're at to try to go to the next level, even though it's...I can't, it's hard to believe anybody can do any of this stuff with all the layers of stuff you have to know. It's crazy.

Mark Shropshire: I agree. I agree. And that, that's some of what you just said is part of why I love open source so much. And I know we've said the word, or if you want to call it a word, DDEV a lot so far, cause that's really what one of the things we're here to talk about, and in addition to Randy you, as a community member, but so while I know a lot of our listeners are really familiar with DDEV and what that means, and we love it here at Mediacurrent, it's our go-to environment. We made that choice a while back and and have been really pleased with it. But for those who don't know what DDEV is, what that means, can you give us a high level overview of this really fascinating open-source project?

Randy Fay: You bet, you bet. So everybody needs, in web development or really in any other context, a developer has to be able to work in an environment that's their own, where they're not going to break something else or break somebody else's world or that kind of thing. And I mean, probably most of us, sometime in our shaded past, actually edited files on a server and hoped that it worked out, but don't do that, right? If you're going to be a real developer, you're going to have your own environment to develop in, and you're going to be able to see the results of what you do locally before you inflict it on somebody else and you're going to have processes to make that work. So DDEV is a local development environment. It's, it's a way for people to do web development. It works with PHP, works with HTML and JavaScript, and probably you could do lots of other things with it, but the most of the communities that are involved with it are PHP, Drupal, and TYPO3 are the biggest ones, but the big idea is it's a, it's a wrapper written in Go on Docker Compose and Docker.

Randy Fay: And so it basically runs a web server and a database server inside containers. So they're actually running inside Linux containers. So it's more like a real-world situation but it looks the same on every platform. So, and so, in other words, the containers are the same on every platform. They're exactly the same. So if you're working on windows or WSL Two, or MacOS or Mac M1, or...people even work on Chromebooks, or if you're working on Linux, I mean, Chromebook just offers Linux. So if you're working on any links, distribution, everything works the same. It's using the same containers underneath.

Mark Shropshire: Sorry, I didn't mean to interrupt, but I was just thinking I'm pretty sure I got it working on my Raspberry PI a while back, thanks to all the work from the community, too, which is I had to do it just to do it.

Randy Fay: It actually works pretty well on Raspberry Pi. The trick about Raspberry Pi, it's ARM 64. So you'd have to set up, I think, I think you have to get the current version of Ubuntu, it's the easiest way. I wrote a blog post about it, so you could search for DDEV and Raspberry Pi, and it, it actually is decent. It it could be a little faster, but it's decent.

Mario Hernandez: So you mentioned earlier, Randy, that you worked for DRUD, a company who was building this product and DDEV, and we know that, some of you may know, that the company split up and for a while, the community was wondering what was going to happen with DDEV, but just this week we heard some great news. Sounds like great news. DDEV has been acquired by Fruition. And is there something you can tell us about this? What does this mean to DDEV? What does it mean to the community? What should the community expect about this new acquisition?

Randy Fay: Yeah, you bet. So the company named DDEV, you know. Companies, come and go, it was called DDEV, it used to be called DRUD, it went by several names, but, you know, not everything always works out and the money doesn't always hold out. And it's just the way it is sometimes. And somebody pulled the plug. I don't know who, but somebody pulled the plug. And so the company named DDEV shut down. The DDEV project was never in any question. The DDEV local project was never in any question because I'm committed to it and it's an open-source project and it was going forward anyway, but there was a little bit of uncertainty about whether the project might have to be forked, or the name might have to change because there is a trademark, a DDEV trademark.

Randy Fay: So there was some uncertainty about that. And the company named Fruition in Denver has bought the what, what, what would it be? The software that (the) DDEV company wanted to make money off of, and didn't end up doing that. They bought that software and they got the DDEV trademark name with it. And they've been very generous to say that they're gonna make sure that the DDEV local project remains open source, and then it doesn't have to change its name. And...the thinking isn't fully thought out, but they're, they're thinking that they would like to be the the central place to try to organize financing for the project as it goes forward. So there's a number of companies that have stepped up and said that they'd like to support the project and you know, maybe even Mediacurrent will want to, and it may be that we're, you know, these are things that we're still talking about, but Fruition may want to organize that financially, or maybe we'll figure out another way to do it, but anyway, they're just putting their foot in there and trying to make sure that it's clear to everybody that there's nothing wrong.

Randy Fay: Everything's good. And and that the name will continue and there's, there's no problems.

Mario Hernandez: Will you be still involved in maintaining the product, and how do you feel about this news about Fruition acquiring DDEV?

Randy Fay: I'm glad that they got it worked out. It doesn't change anything for me right now because I'm just supporting the project. I'm the maintainer of the project, and I continue to be the maintainer of the project. So it doesn't change anything for me. I'm not becoming a Fruition employee. They're, you know, they've been through a lot getting this done, so they haven't even been able to think about the finances yet. I'm sure. But for me, it just resolves the primary thing it does is resolve some ambiguity about whether we would have to fork or, you know, or change the name or something like that. So it's all, it's all very good and they're very nice people and have been very generous trying to sort this out. And they...I think they're taking on a big task with their ambitions, with the hosting software as well. So they've got a lot going on right now and we'll see how this all, how this all plays out. It's all good.

Mario Hernandez: It sounds like it's a great win for the community.

Mark Shropshire: Yeah, this is such great news. And it's it's kind of a testament how open source can continue even around business changes and things that happen in that world. That's not to say it always works out. We've all read stories and heard things, you know, but it's great to hear this and, and we're really happy that you're there and there's still keep supporting that, Randy, and I'd love to talk more about like what kind of support you need, too, later in the podcast. But because I'm sure, you know, you'd love to continue to have more PRs and people helping the project. But yeah, go ahead. Did you have, did you have anything immediate in mind on that, Randy?

Randy Fay: No. That's, good. I, like I say, the thinking isn't done and stuff, but it's all good. It's all good. It's gonna work out great. And, there've been a couple of excellent things that have happened in the funding realm already. TagOne has been supporting specific features. And so that's an easy way to support the project. So they just made me a contractor and have been paying me to do features that are important to some of their projects. And so I, you know, I just work a few, a few hours a week on their project, you know, on their features. And those are big wins for the whole community. And I expect Fruition is going to do the same kind of thing.

Randy Fay: And I think there's other companies that may want to do that. And there may be other companies that just say, Hey, we'll take five hours, we'll take five hours a week. And just, you know, just support the community or just, or, or, you know, maybe dedicated to what they actually need as far as features, but it's all, it's all good. So TagOne stepped up, now Fruition stepped up. There are other companies that have certainly made noise, but of course, as you know, it hasn't been clear how we would do that until this part sorted out. So that's another reason. This is really good is that now that this is sorted out, we can sort out the, all the people that have wanted to financially support the project.

Mark Shropshire: Yeah. That's so great to hear. Thanks for the additional detail on that. So, jumping back to the tech a little bit on DDEV, what are some of the key advantages that you see of around DDEV over other local development tech that's maybe been around or is around currently?

Randy Fay: You bet. You bet. So the original way that you did local development with the website is you'd put Apache on your computer and you'd put MySQL on your computer and you would hook them up and it actually would work great if you were if you were a whiz at Sysadmin, I was always a whiz at Sysadmin. It was my thing, you know, I liked it. It was, you know, I do Linux and I do Windows and I do Mac and it was all, I thought it was great. In fact, I was pretty skeptical of DDEV when I first started using it, because if you're a whiz, then you can just run that stuff. You can, you know, it all runs on every computer and it's great. But not everybody wants to spend their life configuring Apache or Engine X or MySQL, and the thing that amazed me when I started working on DDEV that really really shown for me was that every project could have different configuration.

Randy Fay: So back when I used to maintain everything on my own computer, that wasn't true, right? You have it set up for PHP 5.6 and that's it. You couldn't have one project on PHP 5.6 and another one on PHP 7, PHP 7 wasn't around then, but you just, it wasn't something you could do. And so I started realizing that with DDEV, you could have every project be different and customized, and you could do it right. And so that's because it's a Docker based, DDEv uses Docker underneath and all the stuff underneath is per project, and it is configurable for that project. So that's the huge difference between the Docker generation and the on the machine generation. The difference between DDEV and other Docker based local development environments like Lando or Doxil, which by the way, are great, great products and have lots of supporters and lots of great things to say about them.

Randy Fay: DDEV has got full cross, full support across all these platforms. So many different platforms, which you won't really find that level of support. DDEV is actually tested on all the different platforms. So it runs the full test suite on all the different platforms. DDEV is interoperable with many different versions of Docker. And we think the performance is great. On MacOS it's always a challenge. I'm still working on new ways to improve that in MacOS. So you can look for mutagen, mutagen integration coming up. I think the biggest thing, though, and this actually was playing out in Twitter today, is that DDEV doesn't assume that it owns your machine. So when you install DDEv, DDEV is going to be as respectful as it can. The only thing that I know of that requires you to use Sudu is if you're not using the regular DDEV.site URLs or host names and then it has to...edit the Etsy host's file, but in general, DDEV tries not to do anything to your machine. It won't install Docker, it won't overwrite Docker, it won't kill off your Docker, all of those kinds of things. And I think that's a big deal. But maybe, maybe you can put in the notes. I wrote a thing called "What's so different about DDEV Local?" Maybe you can put a link to that in the show notes.

Mario Hernandez: So I can certainly personally attest I was trying to, I originally got an M1 Mac and was trying to get other development environments set up and I was unfortunately not able to, but DDEV just worked for me, you know, the first try. And so, so that's great to have that kind of support. But, as far as you know, the efficiencies that DDEV provides besides the support, what are other efficiencies that DDEV provides to help teams? Is it something that non-developers can use to run their sites locally and test, or is this mainly just for developers?

Randy Fay: No, actually lots of, anybody who needs to evaluate a site will often do it or, you know, to evaluate or to test a site. It, all those kinds of things, there's actually an obscure feature where you can actually run websites using it. I call it casual web hosting, but I run my little websites using DDEV. That's that's not what DDEV was intended for, but people asked for it for years. And so they finally did it and it actually works pretty well. But it is definitely, it is definitely not managed web hosting or anything like that. So you wouldn't, you wouldn't put a big customer site on that under any circumstances. So the biggest thing about teams is that you check in your configuration for the project. So each project, you just check in the DDEV directory, the dot DDEV directorty, you check it in, and then everybody can check that out and DDEV has already configured for them.

Randy Fay: And so usually a team lead would configure and check in DDEV, and then all the other members of the team can just DDEV start and DDEV launch and get to work and it's already configured, even if they're even if the team lead was on windows and somebody else is on Mac or Linux, it'll just go. And obviously there's going to be caveats there, but really it pretty much works that way. So we're going to do at at Drupal Camp Colorado, I don't know whether, you know, Truls (Steenstrup Yggeseth) who's a Norwegian developer who is kind of an expert at setting up DDEV for teams. He's done it for two different companies. He's the guy that makes that work for two different companies. So he and I are doing a session, an hour-long session at Drupal Camp Colorado, which is free. And we're gonna, it's about, it's about teams and DDev. So we'd love to have you at that.

Mark Shropshire: Oh, that's great. Yeah. And you know, just to reinforce, this we'll definitely add a lot of these links and items to the show notes, so that it's all available. So don't worry. And if you're listening, go Google for it, just check out the show notes. And we've already got that link in our notes here from you, Randy, so thank you for that. So I know you mentioned earlier you know, some of the platforms or frameworks that run on DDEV include, you know, Drupal, TYPO3, what are some of the others of interest? And are there any others that, you know, are maybe coming up? But I know you've got quite a few.

Randy Fay: Yeah, yeah. I mean, we got a really all versions of Drupal six to nine, WordPress, Oracle, TYPO3, Shopware six, Magento one, Magento two, I might've forgotten about one or two, but really, lots of people....you know, because we have explicit support for these and we create settings files and stuff, it doesn't actually mean that much to anybody that understands how to do a settings file. So, all it means basically is that DDEV will generate some settings files for you, so you can get up running really, really fast. There's...no PHP project that you can't run on DDEV, really no HTML, JavaScript, Node, whatever you can run them all on DDEV. It just, it requires the same setup that you would do in any other, in any other environment. Just...DDEV, it just makes like Drupal so easy.

Randy Fay: Cause you do a DDEV config and a DDEV start, and it's already configured. You don't even, you don't know where the database is, you don't care where the database is. You don't, you didn't do the settings file. It's just there, but that's just a settings file. It's not like, we all know how to do a settings file so we could all do that by hand. Then I'm pretty sure on like on Lando and Doxil, you have to do the settings file yourself. Well, that's fine. There's nothing wrong with that. It just makes it, I don't know. It's a little addictive. So that that's mostly what the framework stuff is. It's icing on the cake, but it's not the fundamentals, but it feels like the fundamentals because everybody gets used to it.

Mark Shropshire: It does, because I know when I'm in development mode and not a DevOps mode, I want to just worry about the code and get into the code. And so if it saves, you know, that automation save that time and you know, in an agency situation like Mario and I are in, we're popping in different projects all the time and spinning things up, spinning things. I mean, it becomes even more so a benefit, even though you do that settings file once, you know, usually, and then it's done, but yeah, totally agree. That's great insight. And I think, Mario, we've even had, we've even had some projects where we've run Gatsby in DDEV and some other node things like Randy mentioned.

Mario Hernandez: You know, shameless plug here. I actually, with the help of Randy, I wrote a blog post. I think it was late last year where I configure an environment and since I do a lot of training myself, training workshops, I configure an environment where the students would just run DDEV start and they will have everything from, you know, obviously Drupal, PHP, everything else, but also NVM, NPM, node and everything pre-configured and running from the containers, including Pattern Lab, which will run from the containers. And by sharing some ports, you can literally have an NPM watch task watch your changes and everything in the containers. Pattern Lab will even reload the browser for you, all running from the container. So it is incredible what you can do with it. So highly recommend if you are a developer to look into it. So, now that we talked a little bit about the DDEV, what it does, what it can do and how cool it is, what can you tell us, Randy, about what's coming up for DDEV?

Randy Fay: Well, I'm really excited about what I've been spent working on the last the last few weeks I already mentioned it. It's mutagen passing speed up. The big problem on MacOS and to some extent on Windows is that Docker is slow updating files between the host and the container. And so there's a workaround for that. You can call it caching, or you can call it asynchronous updates. But there's a project called mutagen that's another open source project that has been working on trying to solve that problem for some time. And it actually has pretty good potential. Basically what happens with it is when you make a change in the container, that change is immediately available to like the web server or a PHP FPM. And so it doesn't have to wait for that to sync before it is used.

Randy Fay: So that's not the way it is in current Docker setups. In, current Docker setups, every file change requires everything to happen immediately. Anyway, mutagen can be two to 10 times faster at like a, at like a Drupal nine installer or something like that. I've been doing some timing on it. Very, very impressive. And that's fast, I'm talking about faster than NFS, which is the other technique that we've been recommending for a long time. The complexity of mutagen is that...you can introduce conflicts by touching something on the Windows side or the Mac side, and also inside the container. The consistency stuff is hard and mutagen is good at it. But there's a lot of workarounds that DDEV is having to do to make that go. But I think you'll see an alpha of that in the next couple of weeks.

Randy Fay: And I hope, I'd love to have everybody try it and get their feedback. It is lovely to work with. The worry always is about consistency. Would some files suddenly go away on you that you didn't mean that to happen, that kind of thing. So consistency is the big deal. Also (developer) Ofer Shaal has been working like crazy making gitpod work with D dev. So there's a whole project called DDEV gitpod, (https://github.com/shaal/ddev-gitpod) that will just bring you up a whole Drupal, a whole Drupal nine set up, boom, there you are. By the way, Ofer likes to say boom. So I'm going to say boom a few times, you can put the boom into the release notes. And so, you can try that out and it's just lovely, but the next step, he's transforming that for Drupal contributions so that you can just say here, and this, this project is called Drupal pod capital D capital P.

Randy Fay: So Shaal drupalpod, and he's got it to where you can visit an issue on drupal.org and you can do an issue fork or contribute to an issue fork right there in your browser. Now I should have started by saying what gitpod is. Gitpod is a way to run a Linux computer in the browser. It's basically giving you a free Linux computer that's fully configurable in the browser with VS code. So it's got a very nice IDE. So if you bring up DDEV gitpod, for example, you have all of DDEV right there in your browser, all of it. You can, immediately do debugging. Ofer has done a number of demonstrations of this. You just spin up, you go to any PR or you go to any project on GitHub, click the gitpod link, and boom, you have got that boom in there, again for you, Ofer, you have it up and running and you can debug with XD bug in VS code without doing anything, nothing at all.

Randy Fay: So it's right there. It's got great potential for DrupalCons for contribution days. Both of these have enormous potential for that because you don't, if you've ever worked in that, one of the contribution days at DrupalCon about half the day can be spent helping people get a local environment set up and they've all got their own computer and it all has to be set up differently. And with with these various ideas that Ofer is spinning off so fast, all that goes away and it can all be done consistently in gitpod. It's an amazing demonstration. I don't think it probably works as well on a podcast.

Mark Shropshire: Yeah, yeah, that's right. This is audio only, but Ofer, he is on tour. It seems like giving demos, he gave a demo or a Drupal Camp Asheville unconference, and it blew my mind. I was immediately posting links and I've already got those listed now for the show notes, but I was posting links in our developers channel cause I was so excited. I saw the potential in Drupal pod, but I don't think I realized there was DDEV gitpod. So thanks for mentioning that, Randy.

Randy Fay: Yeah, well that's what Drupal pod is, too. Drupal pod just uses DDEV inside gitpod, but it's focused on Drupal issues. So it's focused on Drupal. And so that, I mean, that's gitpod is DDEV in gitpod.

Mark Shropshire: I see. Yeah, that makes sense. Drupal pod is for the issue queue side of things.

Randy Fay: Ofer and I are going to do a demo of a Drupal pod probably at Drupal Camp Colorado. I think, don't they always have like an IT day? I think we have a slot on that.

Mark Shropshire: That is fantastic. I guess we're at a point here where we can we can start to wrap up a bit. I mean, you've mentioned a few fantastic trainings already. So I would tell everyone to kind of check out the Drupal Camp Colorado website. We'll get links in the show notes. And also I think there's some training coming up with, with Mike Anello, too, Randy.

Randy Fay: Yeah, we're doing we're doing at, at Drupal Camp Colorado. We're doing a half day training with Mike Anello. If you haven't done one of Mike's classes, every one he does is wonderful, but he's been doing DDEV for years. He does this whole, like year-long Drupal thing to take you from zero to expert in a year. He does, he does all kinds of wonderful things. But he also does Composer, which I highly recommend his Composer class, but he and I are doing DDEV local, beginner to expert half day at Drupal Camp Colorado. Yeah.

Mario Hernandez: Mike...I have worked with them before and attended this class, actually. Mark Shropshire: He's fantastic. And a great community member. I highly encourage folks to check that out for sure. So I think that should do it for today. We really appreciate it there, Randy, taking the time to join us again and give us all this great information, especially it looks like the future looks very bright for DDEV and makes us all very happy here at Mediacurrent and I'm sure a lot of the community members out there, so boom, there you go.

Mark Shropshire: I like it. I'll drop a boom in now. It's like, it's so much better.

Mario Hernandez: So thanks again, Randy. We appreciate it. And anything else, Shrop, you'd like to close with?

Mark Shropshire: No, no, just encourage everybody to, if you haven't used DDEV, go check it out. We've got links for all of Randy's. Well, not all of Randy's places on the internet, but at least some places I know I looked for Randy and that's his website, GitHub links and Twitter. So definitely check that out and I encourage, also, this is open source, you know, Randy can't do everything, and I encourage folks to help with the project in whatever way they can, organizations or individuals.

Randy Fay: Yeah. Yeah. That's what I was going to follow up with that, too. DDEV Is a community of people and it's, you know, when there's a whole bunch of different Slack groups, there's DDEV in the Drupal slack and in the TYPO3 Slack, but DDEV depends on everybody learning new things and pioneering new approaches and helping each other more than anything else. And those communities where people are listening and helping people at all levels when they land are wonderful things. So remember that DDEV is a community project and you're part of it. And you're welcome there.

Mark Shropshire: Well, that can't say it any better than that. Thank you so much for your time today, Randy. We really appreciate it. And now we know it's precious, so thank you.


Jul 16 2021
Jul 16

For the July 2021 SC DUG, I gave my new talk titled “Queries on Queries” which poses questions to ask yourself when migrating data between systems. Data migrations are often critical to project success, but all too often that are treating as a throw-away process. This talk is intentionally platform agnostic building from my experience with both Drupal and Salesforce.

[embedded content]

If you would like to join us please check out our up coming events on MeetUp. You’ll find our meeting times and, once you RSVP, remote connection information.

We frequently use these presentations to practice new presentations, heavily revised versions, and test out new ideas with a friendly audience. So if some of the content of these videos seems a bit rough please understand that is some of the point. If you want to see a polished version checkout our group members’ talks at camps and cons.

If you are interested in giving a practice talk, leave me a comment here, contact me through Drupal.org, or find me on Drupal Slack. We’re excited to hear new voices and ideas. We want to support the community, and that means you.

Jul 13 2021
Jul 13

Headless commerce is quickly becoming the gold standard in content management system architecture. In this article, Josh Miller delves into the capabilities of Drupal Commerce 2 for a headless setup.

Using Drupal Commerce 2 checkout for headless ecommerce

Drupal Commerce 2, like Drupal 9, was a big change from previous versions. The codebase is much different and it’s quite a learning curve when moving from older versions of Drupal, like 7 or 8. However, this is good. The new versions are modern and all-around better. I’ve had a number of revelations while working with Drupal Commerce 2 and Drupal 8 that made me smile. (If you haven’t upgraded to Drupal 9, check out my blog Drupal 8 to Drupal 9: The Easiest Major Upgrade in a Decade).

In this post, I’ll explore one revelation I had while working with Drupal Commerce 2’s checkout handling and how its forward-thinking development has paved the way (and encourages all new checkout panes to follow suit) for headless ecommerce using Drupal.

Drupal Commerce 2 checkout is not a form. Say what!?

Generally, when you think of checkout, you think of it as a sequence of events and one big final submission. This is further driven home by the idea that you can, and should, be able to go back and edit your checkout choices before the final submission. In Drupal Commerce 2, going back and forth between checkout steps is supported, but there is no final submission handler that saves everything.

Wait, what? That’s right, there’s no need to save all the data on the checkout form once checkout is completed. You see, all checkout panes (a step in the checkout process) have a submission event that gets called when it's time to save the data. So if you’re going to save data in a checkout pane, you have to do it after your customer has moved forward in the checkout process but before your customer is ready to commit to the checkout pane’s final value state (complete checkout). Submission is perceived to be at the end of checkout, not before.

On the surface that might make sense, in fact, this workflow being so obvious might even blind you to the implications. Since each pane is basically handling its own submission workflow, you can’t allow your form state to persist choices and not make a decision until the end. You’re probably, like me, thinking that saving data and reacting to data is the same thing. But this assumption is old, out-of-date, incompatible with best practices, and in checkout for Commerce 2, causes design problems.

Click to discover your ideal architecture with our analysis.

Explanation through an example: A checkout newsletter subscription

A common want is to include a little checkbox underneath a contact information email field where new or returning customers can opt-in to a newsletter. Sure, that’s no big deal, right?

Our customer expects that things in checkout aren’t real until they complete checkout (i.e. nothing is saved until they actually place the order). On the other hand, Drupal Commerce 2 expects all panes to save their data after a “continue to next-step” button gets clicked, submitting that pane.

Here’s how the checkbox would be made using our current form submission logic:

  1. Create a CheckoutPaneBase object that collects data through a checkbox.
  2. On the pane form submission, subscribe the customer to your newsletter.

Do you see the problem? If we react on pane submission (our only choice in our current way of thinking), we’ll subscribe the customer to our newsletter well before they are done with checkout. In fact, each time they see the first page of checkout and proceed to the second, they will be subscribed to our newsletter. Not only is this not what the customer would expect, but subscribing them multiple times is totally unnecessary and would likely cause problems. Subscribing the customer on pane form submission is the wrong approach.

This is where things get really trippy — and awesome and beautiful and wonderfully clever and great. You see, Drupal 8, which Commerce 2 is built around, has been designed to not require forms, form states and value persistence in order to trigger important actions. This is a whole new way of thinking and maybe the most important to our discussion. Previous to this, most Drupal 7 developers would have assumed that all forms require user-facing interfaces that would be submitted, but that is a pretty brutal assumption and has plagued a lot of Drupal installations over the years. If that was still the case, then form submissions are something that headless implementations of Drupal would never really trigger. There must be a better way.

Headless decoupling breeds better code using events.

If checkout was a single form with a final submission handler that submitted payment, subscribed users to newsletters, saved addresses to profiles, and did all the things you would expect all at once, then all the code that manages these things would have to react to a single form submission.

However, if we use Drupal's built-in event system instead, we suddenly have a much greater degree of control. But before we get into that, let’s first take a quick look at what events are and where they come from.

Drupal 8 made a big shift towards being object-oriented by adopting Symfony within its framework. Symfony provides a number of components useful in modern object-oriented programming, one of which is events. Events in Drupal 8 give developers a new way to extend and modify how interactions with core and other modules work. If you’re already familiar with Drupal 7, events are basically meant to replace hooks. Drupal 8’s event system documentation helps us to understand the basic concepts and components making up the event system.

  • Event Subscribers — Sometimes called "Listeners", are callable methods or functions that react to an event being propagated throughout the Event Registry.
  • Event Registry — Where event subscribers are collected and sorted.
  • Event Dispatcher — The mechanism in which an event is triggered, or "dispatched" throughout the system.
  • Event Context — Many events require a specific set of data that is important to the subscribers to an event. This can be as simple as a value passed to the Event Subscriber, or as complex as a specially created class that contains the relevant data.

Source: Drupal.org documentation, Subscribe to and dispatch events (link)

Getting back to our checkout scenario, if you use the events system and your checkout completion is simply a state transition from Draft to Completed, then other modules could subscribe to that transition event, take the saved data from the different pane submissions, and do whatever they want with it.

Do you see the beauty here? By forcing checkout panes to submit before the final submission, we (module builders, implementers, etc.) have a baked-in reason to store checkout decisions on the order so that order events can access them separately, giving us the ability to create orders with checkout decisions saved that can skip checkout completely and still have the events trigger the needed actions. This is quite powerful and opens up a whole new world of possibilities. Of course, since this is an implicit design choice, it’s up to the author of the module or code to see the reasons and embrace them.

Entity and event-based, instead of form-based

So to complete our newsletter subscription pane example using our new knowledge of events instead of form submissions, here’s what we would do:

  1. Create a CheckoutPaneBase object that collects data through a checkbox and saves it to the order (either through a field value or the ->setData typed data interface.
  2. Save this value on pane submission but don’t act on the value (i.e. don’t subscribe the user).
  3. Create an event subscriber and use the transition event you want to use as a trigger. Completing checkout makes the most sense.
  4. Treat the order value as a "request subscription to newsletter." Then, when the event fires and the event subscriber runs, it can look for the saved value and set the user to subscribed or not after it returns. This allows us to handle someone going through an event twice for some reason, like for multiple orders, etc.

Your customer gets subscribed to your newsletter when they, and you, expect them to. No forms are needed. ISN’T THAT AMAZING!

Thanks to the many authors of Drupal Commerce 2, including Bojan Živanović and Matt Glaman, who implemented this design choice years ago, many modules and implementations are simply technically better and likely ready for headless implementations now that headless is all-the-rage.

And best of all, from a developer standpoint, this also means the bulk of your most critical automated tests that interact with your code doesn’t have to access the checkout form. They simply have to have orders that get transitioned. This makes writing tests, which equates to better code, simpler.

Your Drupal Commerce experts

As a full-service Drupal agency, Acro Media has significant expertise in digital commerce architecture, ecommerce consulting and design, customer experience, Drupal development and hosting architecture. We would love the opportunity to work with you.

View Our Drupal Commerce Services

Editor’s note: This article was originally published on October 28, 2019, and has been updated for freshness, accuracy and comprehensiveness.

Jul 09 2021
Jul 09

In June for the SC DUG meeting Will Jackson from Kanopi Studios gave a talk about using MQTT with Drupal to connect to local IoT devices. A fan of home automation, Will has created a Drupal 8/9 version of the MQTT module. He is hoping to encourage more people in the Drupal community to join the fun.

[embedded content]

If you would like to join us please check out our up coming events on MeetUp. You’ll find our meeting times and, once you RSVP, remote connection information.

We frequently use these presentations to practice new presentations, heavily revised versions, and test out new ideas with a friendly audience. So if some of the content of these videos seems a bit rough please understand that is some of the point. If you want to see a polished version checkout our group members’ talks at camps and cons.

If you are interested in giving a practice talk, leave me a comment here, contact me through Drupal.org, or find me on Drupal Slack. We’re excited to hear new voices and ideas. We want to support the community, and that means you.

Jun 30 2021
Jun 30
[embedded content]

Don’t forget to subscribe to our YouTube channel to stay up-to-date.

Infinite scrolling is a technique used to show more content as the user scrolls down a page eliminating the need for the user to click to go to the next page. This is commonly implemented in popular social media apps.

This tutorial will demonstrate how to use the Views Infinite Scroll module to achieve this and also show options that can be used to customize the user interaction with the infinite scrolling behavior.

We will show you how to:

  • Install the module
  • Set up a simple view
  • Add the infinite scroll behavior
  • Customize the infinite scrolling behavior.

Drupal Views Series

Table of Contents

Getting Started

We can easily install Views Infinite Scroll using Composer:

composer require drupal/views_infinite_scroll

To enable you can use Drush:

drush en views_infinite_scroll -y

Step 1: Set up your View

For the purposes of this tutorial, we are assuming you already have a content type set up and have already generated enough content for it.

We are going to create a simple View that lists Articles (Title and Body fields).

Go to Structure -> Views -> Add view

Here is a screenshot of our simple View. There is nothing fancy. We are only listing published Articles and have created a Page display for it.

If you’re new to Views then check out our “Getting Started with Views” tutorial.

Step 2: Adding the Pager

In the Pager settings of your View, change the type to “Infinite Scroll” (leaving all the settings as default for now).

Also, in the Advanced section of your View, set “Use AJAX” to “yes”.

Here is how our View settings looks now:

Save your View and go to the URL of the View page to test out your Infinite Scroll. You should now see a “Load More” button in the pager section of your View page that looks like this:

And that’s it! You now have infinite scrolling for your View. However, there are more options that can be configured for your Infinite Scroll. These are all optional as we shall demonstrate them now.

Step 3 (Optional): Replace the button text

You can add tokens to your Infinite Scroll button to enhance the user’s experience.

In the pager section of your Views configuration page, open the settings of your Infinite Scroll pager as shown in the screenshot below:

Set the button text to “Load @next_page_count more (Total @total)” as shown in the screenshot below:

Now your Views Infinite Scroll Pager button text will look like this:

@next_page_count” and “@total” are called “tokens” in Drupal. The tokens are replaced with actual data automatically.

View Infinite Scroll supports the following tokens:

  • @next_page_count
  • @remaining_items_count
  • @total

Step 4 (Optional): Automatically Load Content

Currently, users would have to click on the “Load More” button to get the next set of content. The Views Infinite Scroll page has an option to automatically load content (without the need to click on the button).

Go to the settings of your Views Infinite Scroll pager and check the box “Automatically Load Content” and click on Apply.

Save your View and then test it. As you scroll to the bottom of your View, another set of content should automatically be loaded.

Warning: Enabling this setting means that the user never actually gets to the footer of your page until they have exhausted loading all of your content. For example, if you had 1000 articles, it would take a very long time to see the footer. This means that if you had important links in your Footer (like Privacy policy links etc), it’s almost unreachable.

Step 5 (Optional): Exposing Options to the User

Views Infinite Scroll allows you to expose settings to allow the user to control selected displays options. We will demonstrate by doing an example. In the Settings of your Views Infinite Scroll Pager, scroll to the “Expose Options” and check “Allow user to control the number of items displayed in this view”, then click on Apply and save your View.

This results in the following being added to the top of your View page:

This specific option will allow the user to select how many results are returned everytime they click on the “Load More” button.


Views Infinite Scroll is a neat module that allows you to add infinite scrolling behavior to your View. We have shown how you can use this module to achieve this infinite scrolling behavior and also demonstrated a few of its customizations along with one of it’s biggest pitfalls.

Jun 23 2021
Jun 23
[embedded content]

Don’t forget to subscribe to our YouTube channel to stay up-to-date.

In Drupal, content is stored in the database. Views is a query builder that allows the user to extract content from the database and output it in various displays such as tables and lists. With Views, the user does not have to know or write any SQL queries. If you want to create a page or block in Drupal that lists any kind of content based on different filter criteria, you should use Views!

In this tutorial, we will explain what Drupal Views are and how to create it. We will also demonstrate some simple customizations such as page settings, filters, sorting, display options, exposed filters, permissions, creating a View Block and creating an admin page using Views. By the end of this tutorial, you will know how to create and customize a Drupal View.

Drupal Views Series

Table of Contents

Getting Started

As of Drupal 8, Views already comes packaged with Drupal core so there is no need to download anything. If you installed Drupal using the standard installation profile then it’ll be already installed.

Go to Extend and make sure Views and Views UI are installed.

How to Create a View

In this section, we will walk you through the process of creating a very simple View that lists  published Articles using the teaser view mode.

First, ensure you have enough article content on your website and ensure you are logged in as the administrator. Now let’s create the View.

1. Go to Structure -> Views (admin/structure/views) and click on “Add view”.

2. On the “Add view” page, fill out the fields as suggested in the screenshot below. All we are doing here is giving the view a name, selecting “Article” in View Settings and ticking the box “Create a page”. Every other field can be left as the default for now. Click on “Save and edit” when you are finished.

Views Creation Screen – Figure 1

And that’s it! You have successfully created your View. If you were to go to “/latest-articles” you can see the output of your View.

We will now explain the major parts of the Views configuration screen. We have highlighted different sections of the Views configuration screen in the screenshot below and labelled each section with a number for easier reference and explanation.

Views Config Screen – Figure 2

Label 1 – As the name suggests, this is the title of the View. This is the text that will appear as the title of the /latest-articles page.

Label 2 – This determines the output style of the view. Frontend themers can use this to style the output by overriding the default templates provided by Views. There are also contributed modules that can extend and provide more options such as Views Slideshow.

Label 3 – This determines how each row result of the View should be displayed. Currently it’s set to “Content” which allows us to choose different view modes like Teaser or Full Content. If you want to show just specific fields of your Articles, you can change it from “Content” to “Fields”. Then, you can select the fields you want to display in Views Config Screen Label 4.

Label 4 – Based on which Format style you choose above, this section will allow you to choose the specific fields to display.

Label 5 – This section allows you to define criteria for filtering your View results. Currently we are only showing published articles.

Label 6 – As the name suggests, we can define how to sort the View results. You can also sort on your content type fields by adding them here.

Label 7 – This is the path for your View page.

Label 8 – If you want to add your View page to any of your Drupal menus, this is where you can do it.

Label 9 – In this section you can define specific permissions for who is allowed to access your View.

Customizing your View

Let’s say we want to customize our current View to display a table layout with just Title and Body fields of the Article content type. But we also wanted to allow the user to input a text string that will filter the results against the Title. We will refer to the labelling in Figure 2 to help with our explanation.

1. Update the Format (Views Config Screen Label 2). Set it to Table. You can leave the default Table settings.

2. In doing Step 1, you may notice that Views automatically added the Title field in the Fields section (Label 4). Let’s add the Body field as well.

Click on “Add” in the Field section:

In the “Add fields” popup, search for “body” and click on “Add and configure fields”.

On the “Configure field: Content Body”, you can leave all the defaults and just click on Apply.

3. Now let’s demonstrate how to allow the user to enter text into a field that will automatically search against the Title field. In Drupal Views, this is called an “exposed filter”.

To create this exposed filter, click on “Add” in the Filter Criteria section (Label 5).

Then search for Title in the next screen and click on “Add and configure filter criteria”.

On the next screen, check the box “Expose this filter to visitors, to allow them to change it”. More options will automatically become available. Make sure to set the Operator to “Contains” and then click on “Apply”.

Tip: “Contains” means Views will use the string entered by the user and execute a SQL search in the database for any string that contains the characters entered in that order, i.e., “...LIKE %usertext%...” in SQL.

4. Now that we have set the Table Format, Title/Body fields and exposed filters, it’s time to save the View. This step can be easy to miss so don’t forget it!

Now if you view the actual View page, the View output should look like this:

Create Block using Views

A View Block is just a regular Drupal block except it originates from Views.

For demonstration purposes, let’s say we wanted to create a block version of the View page we created above.

There are two ways to do this. You can either click on “+Add” or click on “Duplicate as Block”. Both options are shown below:

Once you have done that you will notice you will now have “Block Settings” instead of “Page Settings”. This makes sense since now we are dealing with a Drupal Block.

Go ahead and save your View. Once the View is saved, a Drupal block is automatically generated and will be listed alongside all the other Drupal blocks.

Place the block anywhere in your Drupal site as you normally would place any Drupal block into a region. Here is a quick video of how to place a Drupal block into a region. We placed ours in the left sidebar and it looks like this:

You will notice our exposed filter is not being displayed in our Block. There is one extra step involved if you want to get exposed filters to work in View blocks. On the View configuration screen, inside of Advanced, set “Use AJAX” to yes and save your View. Here is how that looks:

Now our Views Block has the exposed filter which looks like this:

Create Admin Page using Views

Let’s say we wanted to use the View page we created above but place it within the admin UI and only accessible to a person with elevated permissions (in other words, not anonymous users). This is a screenshot of the end result we are trying to achieve:

There are a few things we need to edit in our existing View to achieve this. All of the changes we have to make will be in the Page Settings of our View config screen (See Figure 2). We need to update three things:

  1. Label 7 – Update the Path
  2. Label 8 – Update the Menu
  3. Label 9 – Update the Access Permission

1. Updating the Path: In the Views config screen, update the Path to “admin/content/latest-articles”.

2. Update the Menu: In the Views config screen, update the Menu. Clicking on “No menu” will take you to the Menu item entry config screen. On this screen, choose Menu Tab for Type, enter a Menu link title and set the Parent to “” and then click on Apply.

3. Update the Access: We can do this either by defining the Permission or by defining the role. For this tutorial, we will define the permission. In the Views config screen, click on “View published content” and change it to “Access the content overview page”.

4. Save your View!

Now if you go to “admin/content/latest-articles” as a logged in user, you should see your View page. If you tried going to this same page as an anonymous user you should get Access Denied.


In this tutorial, we introduced you to Views and some of its potential capabilities by providing some simple customizations. We specifically concentrated on demonstrating how to create a View Page and a View Block which list published Articles and also included a View exposed filter which allows the user to enter a text string to search against the Title. We also touched on how you can create an admin page using Views by updating its path, menu and permissions.

Views, which is in Drupal core as of version 8, is a very powerful tool and can be highly configured and customized. We hope we helped in getting you introduced to Views and the potential it has.

Jun 22 2021
Jun 22

open waters podcast logo

Open Waters Podcast: Season 2, Episode 3 

In this episode, we're joined by Shane Thomas of Gatsby to talk about decoupled Drupal and how features in Gatsby make it easier to make decoupled websites using Gatsby and other CMS like WordPress or Drupal. Shane gives us insight into what makes Gatsby unique as well as some sneak peeks into upcoming features. 

Episode Transcript 

Mark Shropshire: All right. Welcome everybody to the Open Waters podcast. And today we have a very special episode. We are going to be talking about decoupled websites. We'll get into decoupled Drupal. We'll get into some Gatsby because today we have Shane Thomas of Gatsby, who's our guest today, and I'm here as usual with Mario Hernandez as a cohost. Gatsby provides development teams and open source front-end framework for creating dynamic, optimized websites and cloud platform for delivering them on a blazing fast edge network. That's a lot of words, but it all makes sense. And it sounds fantastic. So Mario, I'm gonna kick it over to you and we'll kind of start chatting it up with Shane.

Mario Hernandez: Excellent. Thanks a lot, Shrop. I appreciate it. Very excited to be on this episode two of the Open Waters podcast, season two. And thank you so much, Shane, again for joining us. We appreciate you taking the time from your busy schedule to join us one more time. I think we had you on the first season of the podcast. Tell us about your role at Gatsby today and how you became interested in the decoupled Drupal architecture.

Shane Thomas: Yeah. So I've been working with Drupal since I think 2009. And I started a little web agency doing, starting with Drupal 6 websites. So I've been working with Drupal for a long time. I used to run a website and I guess I still do, but it's not really active called codekarate.com. So I've done a lot of videos and all kinds of different content for Drupal. When I was really using it heavily. I worked at a Drupal agency in the past as well. I've been part of some startups. Then I started to really get interested in hearing about, you know, headless Drupal and decoupled Drupal. And what does it mean? And there are a lot of new JavaScript front-end frameworks that were coming out about this time. And you may have heard of static site generators that are popular and maybe pulling data from some of CMS systems like Drupal and other CMS providers.

And so that got me really interested in digging into it a little bit more. And I kept hearing at actually at Drupal camps, I kept hearing talk about this Gatsby thing. What does this Gatsby thing? And originally it was just, oh, it's a static site generator, just make all your content static. And then when I really dug into it, I realized it's not just a static site generator, it's really a React framework. So if you're familiar with React, it's it's a way to it's a JavaScript front end in front end library to build websites and web apps and gets these built on top of that. And so then I started playing around and realized like Gatsby is really kind of an ecosystem for building websites and web apps. And now with Gatsby Cloud, there's kind of this entire platform that really makes it easy to do that. And so I started met with some of the people at Gatsby, saw them at some conferences, and I guess the stars aligned and I was hired as an engineer to work on the Drupal integration. So it kind of all kind of coincided pretty well with my back background in Drupal. And from there spent quite a bit of time working on the Drupal integrations, which I'm sure we'll talk a little bit about. And then eventually took over as an engineering manager for our integrations and collaboration squad at Gatsby.

Mario: That's pretty neat. Code Karate I know Shrop, he gave a thumbs up. I benefited a lot from that myself.

Shrop: Yeah. That is a great kind of background review Shane where, where you, you know, where you've been and how you got to where you're at today. And you mentioned some of the work you've done, like with Drupal and Gatsby, and Gatsby and Drupal working together. Can you give us a high level kind of perspective of where Gatsby fits in to the decoupled discussion?

Shane: Yeah. So, what Gatsby allows you to do, and I guess that's kind of the, one of the best benefits of Gatsby is you can bring your content from anywhere. So there's a lot of different CMS systems that marketers and content editors like to use. Drupal's a great choice, right? You can model your content and set it up however you want. There are other ones like WordPress or Contentful, and Gatsby is not opinionated about which framework you use to build your content. So essentially you bring the content and then we provide the front-end framework for it. And the reason you might choose to do that is because a lot of CMS providers like Drupal, like WordPress there, they tried to do all things. And so sometimes when you try to do all things, you don't do everything as well as something that's very specific or focused.

And so by Gatsby being very focused on just the front end of your website, it can be, uh, more performance and you can get a better Lighthouse scores, which can help conversions because your users or your customers are experiencing a faster, more app-like website. And so their load times are better. It seems they don't get frustrated if the page takes too long to load those types of things. And so that, that's kind of how it fits in. As you know, it's not necessarily a replacement for Drupal or WordPress or any CMS provider. It's kind of just taking the theming layer, if you've heard of WordPress themes or Drupal themes, and saying rather than use what's provided with within the framework, use Gatsby instead for that part, and then still use or WordPress or Contentful or whatever for all your content.

Mario: You know, we've been working with Gatsby for a little while now, and certainly we can see the benefits, but but one question that, you know, we, we get quite a bit is, you know, why would a site owner look into going the decoupled architecture route? So let's say, for example, why would a marketer, you know, we'll find this appealing, right? What are some of the benefits and from let's say, security, performance hiring, and that kind of thing. What are some of those things that you think are beneficial for a marketer to look into the couple of architecture?

Shane: Yeah. So deciding to go to decoupled is certainly, it's not an easy decision to make, and there's a lot of considerations. It's. Especially if you built sites, not decoupled before, it's, it is a change and you need people with a little bit different engineering backgrounds. However, it is getting easier to hire JavaScript engineers. There's, you know, that's definitely something that people are interested in and learning about. And so they're coming out fresh from school or from, you know, other industries and they're digging right into JavaScript. So they're literally, I'm not saying that engineers are easier to find, but there's more interested engineers. It seems like than hiring someone very specific or specialized, like it's Drupal engineer. And so by separating that out, you can have someone focused on the back end and then someone focused kind of on the front end or the framework side.

So by decoupling, you kind of split those concerns off a little bit. Also, you really, one of the big drivers of decoupling is performance, which I had mentioned a little bit before your, your speed of your website matters because if your customers are having a better experience, they're more likely to either buy it from you or call you, if you're trying to get them to call and use your services or sign up for your product, whatever it is. They're more likely to convert if the website is so well-designed fast and it feels like they don't have, you know, it's a seamless experience for them. And that's where front-end frameworks and going decoupled can help with that because you can use a framework that's specifically focused on performance. And the other thing is just security. So using a front

You're not necessarily exposing everything available through your, your website. So you have kind of an API, you can kind of hide certain things you don't want to see. And it does help that, you know, everything's static. So you it's secure and it's it's faster, it's highly available. So you don't necessarily have to have a running server for a lot of your stuff. So if you ever had a website go down and you're wondering why, why is my website always going down? Well, that's not saying it never could happen, but it's a lot less likely to happen when you're just serving more static content and less where every, every request has to go back to a web server to generate that information. So, and then those are some of the reasons, um so there's definitely trade-offs though, you know, good at good and bad for both, but there's a lot of good things about deciding to to look into a decoupled architecture.

Shrop: I know we were talking a little bit before we started well, before Mario hit the record button, then you know, we do have a lot of Drupal folks listening to this today. But I do want to mention that when you dig into Gatsby, what's what I really like is that you can even have markdown be your backend. You know, that could be the source of content. You can have so many, like you said previously, Shane, It's it's not really opinionated about the content. You know, you bring the content in different forms and, and I'm pretty sure that you can but you tell me, Shane, here on this, if I'm right or wrong, but I mean, you could have Drupal and WordPress and markdown, you could actually have multiple sources even for different pieces of content into a Gatsby site. It might get complicated, but it's interesting.

Shane: Yeah. So, you see that quite a bit, especially as the sites get more complex, that you might have a Drupal for dynamic lead building landing pages, right? Because Drupal, you can model content. You can set up, you know, if you're familiar with Drupal using, you know, paragraphs or something like that, to set up a really dynamic landing page builder, and that builds onto your Gatsby site, but maybe you have products, too. So you use Shopify for your for your e-commerce part of your site. So your products are served from Shopify, and maybe you have a marketing team, you're a big organization and they just are, they love WordPress. They just have a blog, that's all they need. And so they could be using just the blog parts of WordPress. You can have all three of those systems and everyone, you know, the developers who are building these landing pages and, you know, making that available and using Drupal,

And then, you know, you have your marketers that are blogging and WordPress, and then, you know, people managing all your products in Shopify and it all kind of ties together and gets pulled into all into one Gatsby site. So it's kind of referred to as the content mesh, it's something that the Gatsby likes to call it internally. And I think we have, you know, posts on what the content mesh really is, but it's really a, you bring the content from anywhere and Gatsby's kind of your source of truth that pulls in that content and build your website. You're certainly not locked in as much to just using the tools that you're given. You can kind of look for the best tool for the job.

Mario: It'll meets at the end, right. At the front end. Yeah, exactly. So, so once you've done your homework and you know, you've done a little research and you say, okay, this is the way I like to go. And, you know, you arrive at that decision to go to decoupled, what are some of the marketing benefits that a content manager or a marketer should expect to see, besides some of the things that you already mentioned?

Shane: I mean, definitely, you know, we talked about performanceReally the benefits are I w I would say, and of course the a, if you're a marketer, you want to test this, right? But I would say conversions are the, are the biggest thing, right? If you have a better website, you provide a better experience. You're going to get more conversions. Your, your analytics are going to go up into the right, which is what you want, if you're a marketer. So, so that, that's the biggest selling point. There are certainly some trade-offs though, that you have to consider because it's, it's not the same, right? If you're familiar with working in WordPress, or you're familiar with working in Drupal, and now you have this kind of decoupled architecture, you know, this, you, whether it's a Gatsby site or another framework like Next.js or some, some other, you know, front-end framework, that's decoupled your back end from your front end.

Now, there are some considerations, things that you kind of took for granted, like live preview are a little bit more complicated and, not saying they don't work, but there there's some differences in how your content editing workflow might change from what it was before to what it is with the decoupled architecture. So those are things that you certainly need to keep in mind when you're, when you're choosing to make that decision. And also making sure that your developers understand that the first time you do it, there's a learning curve to moving to a decoupled architecture. And so you have to go through that, you know, just like you did when you first built it, you went from a, a static HTML website to a WordPress or Drupal website. You know, there's, there's learning curves at each step. And so this is no different.

Now, I do believe that once you, once the development team learns how to, how to use it and how it all ties together, that most of the time that I've seen, they don't want to go back. They love the love working in that, with that model, like separating out the concerns between the back end and the front end, and being able to I think in a lot of ways people think it's going to take a lot longer to build the decoupled sites. And I think at the beginning it does, but in the long term, I think it actually is as fast or maybe even faster, because you can work on the back end and front end in parallel rather than a lot of times it seems like with in the past, you'd have to kind of build, you couldn't really do that. You had to build the backend stuff first, and then you'd have a front and themer or designer come in and build the front end pieces. So this kind of allows you to do both at the same time, at least to more of an extent.

Mario: Yeah, I can, I can see, you know, when you mentioned talking about being able to bring the content from any source, right. I mean, when we build a site, let's say Drupal-WordPress site you know, things can get pretty complicated just within that platform. So I can only imagine how things get a little more complicated and complex if you're bringing any more tools, right? Like Gatsby or combining WordPress and Drupal together, markdown or something else. So certainly something to keep in mind. And I say this because a lot of people say, oh, Gatsby is great. And I love to use it. I want to use it, but yeah, you need to take a step back and kind of consider, okay, what is this going to mean to my workflow now? What is this going to do to my build of my site? How has this complexity going to affect performance from the editing point of view deployments and that kind of thing. So a lot of those things a lot of people don't consider, you know, they just see this shiny thing, which is great, but there's a lot of things that need to be considered when moving into something like this, where the complexity is drastically increased.

Shrop: One of the things I'm excited about speaking of taking complexities of decoupled and just website building in general is a lot of the work that Shane you and the Gatsby team have done with Gatsby Cloud. Could, could you just briefly mention a few of the things that Gatsby Cloud gives you know, gives the development teams and marketing teams, that sort of thing.

Shane: Yeah. Yeah, definitely. So one of the things you have to keep in mind with, if you choose to build a website with Gatsby specifically, is that we talked to her a little earlier about how it creates everything kind of as a static website. And there's the when you have that process of taking all your content from a CMS, like Drupal, and then building a static website, there's that build process that has to happen. And you can think about it as if you were using a Drupal website and you didn't use any kind of caching or anything like that, every time you go to that page, the server is doing work to generate that content. That means every user that goes to that page, the server's doing work for every single user that views it. And now of course you can add caching layers and things to try to prevent that and make it faster.

But Gatsby kind of flips that model on its head. So rather than adding layers of caching, it's just fast by default. And you have to, I think I've heard someone say you have to work pretty hard to make Drupal websites fast. It's certainly possible, but you have to really work at it. And it's kind of the opposite. You have to work pretty hard to make Gatsby websites slow. I've certainly seen it, but it's really out of the box, it's pretty fast. So but there's that build process that has to happen. So it happens once and then all your users get the benefit of that build process. But you have to keep that in mind that there's, that when you change content, when you you know, update your site and, you know, update your version of Gatsby, there has to go through this build cycle.

And especially if you're with a website that has tens of thousands of pages, that process can take a long time. So it Gatsby Cloud has incremental builds and cloud builds that speed that up. So rather than rebuilding the entire site, it'll only rebuild pages that have changed, and that speeds up your build times from, you know, maybe 5, 10, 15, 20 minutes, if your site's really big to tend to 30 seconds or less, depending on how the size of your site and what kind of change you made. So that's the first thing that Gatsby Cloud provides is really an optimized build service. So it, your site gets built faster. Again, Gatsby's an open source framework. You can certainly do all of this yourself, but Gatsby Cloud, we'd like to think is the best way to build a Gatsby website. On top of that, it also offers a live preview service for content editors.

So, one of the things you lose with going decoupled is it's harder to preview your content. If you're editing in a CMS, you're used to be able to click on view something that's not published yet, or click the preview button and see what it's going to look like. You kind of lose that. And Gatsby Cloud provides a service. So you get that back. So as a content editor, you can feel confident that when you click the publish button, it might take five or 10 or 15 seconds for it to go live. But when it's there, you know what it's going to look like. And then the last thing that Gatsby Clouid offers, so kind of the third tier, is a hosting service for your Gatsby site. So you can kind of have it all under one roof. You can build it, you can preview it. And then once you're ready, you hit deploy and then published. And then it goes, and it's hosted all kind of within Gatsby Cloud.

Shrop: It's got to be, you know, Gatsby's open source, but you've provided these tools on top of that. That's like the best practice way that you've like the Gatsby team believes to do all these things like hosting and, and builds and previews. I think that's fantastic.

Mario: You mentioned Gatsby preview, which is definitely something that we have seen in the early stages of Gatsby being an issue. And we definitely have also seen how much work your team is putting into making sure that that is something that works as people would expect it to see. Can you give us a little bit more on the Gatsby preview, specifically, and how that can benefit the content authoring experience, and maybe perhaps where you, where you and your team are with Gatsby preview, anything else coming down the pipe with that?

Shane: Yeah, I'll see. I'll have to be careful. I don't share too much information about what's what's coming up. Marketing team might not be happy if I divulge too much too quick, but preview is really important to what we're doing and it's not an easy problem to solve when you have, you know, potentially multiple systems funneling into one Gatsby site, right? You might need to preview content from WordPress or Drupal or Shopify. There's all these different sources. And when you change, let's just make a simple example of changing content in a blog post. You want to be able to preview that before you click the publish button. It seems like an easy problem, but when you have all those systems working together, it's actually a little more complicated. And so we've been one coming up with, how do we make preview more reliable?

You know, there there've been issues that just in the past with, you know, all those different systems working together, that sometimes things come up and your, your preview server stops running, or something happens where the developers that built the Gatsby site didn't correctly think about all the different possibilities. And so that causes your preview to break in this certain scenario where they add certain fields and don't add others or something like that. So there are all these different things. And what we've really been focused on is, one, reliability, making sure that it works, and if it doesn't work, we, you know, why. Is it a problem with the previous server and Gatsby Cloud? Is it a problem with the sites? And so that's been a big focus of making sure we're one preventing those problems. And two, if there are problems servicing it in an actionable way.

And on top of that, we've been releasing recently, we released something called preview UI. I guess that's, I don't know if that's an official public name yet, or if that's just an internal name, but essentially it provides kind of an indicator where, if your previews rebuilding or someone saved content, it tells you the status of that. And it gives you links to the air logs. It provides you the ability, you know, simple little things like, oh, click here to copy the link and send it to somebody so they can view it, give you the okay, and then you can publish it. And that's really where we're interested in figuring out is how do we make the content editing experience more collaborative, better? Because content editing, there's this weird fear (for) marketers, there's this weird kind of in-between stage of, you know, you need to build some content, you maybe write the first draft, and then there's all these edits that happen are these requests from different parties.

And a lot of times that might be happening outside the CMS in general, like in a Google doc. And then someone goes in and pastes it in the CMS, and then they do another round after it actually decides how it looks like. So we're trying to make that easier. So we're providing one solution for that, so they can build it in their CMS of choice, preview it, collaborate on it, make sure it's right, and then eventually publish it. So that's where I would say the next steps are that we're not there yet is kind of those, those features to help content editors and marketers collaborate on their content before they're ready to publish. And so that's not to tip our hat too much, but that's where we're, we're really looking to improve for all Gatsby users in the future.

Shrop: One thing that you mentioned earlier, you alluded to the preview button and I think about Drupal's preview button and Mario, you and I talked about this the other day you know, preparing a bit for, for this episode and I've kinda, I've become accustomed now both on mediacurrent.com and on some other projects we're working on, with having preview in, and there's also the Gatsby Drupal module that you started working on, Shane, and really pushed that along. That's what you mentioned that earlier, but all these pieces I'm, I'm, I'm really digging the Gatsby preview over that hitting the preview button Drupal experience because there's, depending on also Drupal set up, sometimes that preview button in Drupal, doesn't do what you exactly think it should, for various reasons. And, you know, once everything's set up correctly, like I feel like the Gatsby preview is really giving you a more correct show of what the website would look like. And that's the exciting part for the authoring experience. Mario, you're, I see you nodding a little bit. What are your thoughts on that?

Mario: Absolutely. Yeah. You know, I think as a content editor, right? Or content creator, you want to be able to see a more accurate representation of what your page will ultimately look like on the front end. Right? So having that preview give you that is definitely something that will be appealing to people who work on content. Yeah, go ahead, Shane.

Shane: I was going to say, and the one interesting thing is, especially on Gatsby cloud, the preview service uses the same build process as our build service. So I'm not going to say it's not possible, but there should be almost no reason. It's not identical every time, because, you know, unless you coded something, you can, of course, Gatsby's a framework, you can, you can break preview in your Gatsby site if you wantdc to and make it work for nobody. But assuming nothing is too wild in your setup, it's going to be the exact same every time. So, you know, when you're previewing something, you're actually, the cool thing about it, when you click the preview button in Drupal, for instance, you're only seeing that page, right? That one Drupal page, if it's a blog post, you're seeing that one page. You're not seeing the state of the site, like, how is this going to show up in the blog listing page? How is this going to show up in the footer of related posts with your Gatsby site? It's a full site. You can click the links, you can navigate and see where this content might show up in other places. And so it's really it provides you that really accurate representation of what it's going to look like when it does go live. So that is one benefit. Again, that, that process of updating it and all those places does take a little bit more time. So that's the trade-off is it might be a little bit slower to get that preview, but you know what you're looking at is going to be right. And when you click the publish button, you can click publish with confidence.

Shrop: Well, just shifting gears, a little bit back to decoupled overall. Are, are there any gotchas for a site owner, marketers, developers that they should be aware of before jumping into decoupled?

Shane: Just that it's going to be different than websites you built in the past. So, be prepared for, you know, no matter what kind of front end framework you're using or what kind of decoupled backend you're using, just prepare that it's a learning curve. There's going to be a few headaches along the way. You know, all the frameworks try to make it as seamless as possible, but every, every website's different, right? Every website's unique. And so there's all of these, you know, ideas, and while they're being used by huge companies, there's always, you know, new kind of edge cases that you might run into and you might have to work through, especially as your developers or engineers are really getting up to speed with how it's all built. And then as a marketer or site owner, just know that how you interact with your content is going to have to change a little bit.

Shane: And so you're going to, it's a learning process there, too. The one gotcha, I would say, a lot of times especially I've seen, when people start to build a decoupled website, they don't think about the content editor or the marketer until the website's about done, because they're like, the website is ready to go, let's publish it, and they put all the initial content in, and now the marketer or content editor wants to change something, and it doesn't quite work. The preview doesn't work right. The, the experience, they weren't prepared for it, there was no training there. So I would say if you're looking into that, just make sure you don't forget about that and kind of punt that until the end, because otherwise you're going to maybe be scrambling a little bit and the marketers might throw their hands up and say, this isn't what I signed up for. I thought this was going to be, the site's fast, but I can't do anything with it. I can't change the content. I don't know how it works. So making sure that you have documentation or trainings or whatever, to bring everyone up to speed rather than waiting till the very end to figure that stuff out. That, that'd be one. Gotcha.

Shrop: That's so good. And Mario, Shane said the training word that I know that had to excite you a bit.

Mario: Well, absolutely. You know, it's, you don't want to forget about the people who ultimately will probably be using the website more than anybody else. Right? And so you want to keep it in the mind from the beginning, there is about their experience, not just the visitor experience, but I think that's all the questions we have. I mean, this was really informative and feels like we, we talked to the Gatsby team quite a bit. And, you would think that a lot of this stuff is not going to get us excited or anything, but this stuff is pretty cool, especially the preview. That's something that I'm really excited about.

Shrop: Yeah. This was great. Well, Shane, thanks so much for coming on today to talk to us about decoupled and and to learn a little bit more about Gatsby. I'll always, Mario, I think you agree, it sounds like that's where you're headed. Like I always learn something every time, every time we talk to somebody from Gatsby or talk to someone else just about decoupled in general. So there's all these different experiences. It's not you know, it's not a one experience fits all kind of thing, but, but really appreciate you coming on today and talk and talking to us about all this.

Shane: Yeah, definitely. Thanks for having me. It was fun.

Jun 19 2021
Jun 19

How do you enable that module for just the live site again?

Kaleem Clarkson

Let’s first start off with understanding what the Configuration Split module does. In simple terms, it allows you to have different site configurations for your different environments. For example, you want to turn off the Views UI module on your live site. Or you want to turn off your Google Analytics module on your local, dev, and test environments but still have it active on your live site.

There are so many great articles on setting up configuration split. Here are a few good ones that I suggest reading to get you caught up to speed.

In other words, say that you have already set up your config-splits a few months ago but now your client wants to add email support using the SMTP module but you only want this enabled on the live site so you don’t accidentally send out an email from your local site to 1000’s of users. ps — I have done it before Ouch :)

Well in order to add to the live configuration you need to enable the live config split. The natural first step is to go to the config-split UI and disable the develop configuration and enable the live config. Click Click Click. But nothing. Such a simple thing but why in the heck are you not able to enable the live configuration?

Ohhh snap, that settings.php file got me again.

One thing all of these tutorials have in common is that they show you how to set the active and inactive config-splits in your settings.php. For some servers, the code is slightly different but the idea here is that Drupal needs to somehow know what environment you are on in order to import the right configuration.

Yep! That darn settings.phpfile. The reason you cannot activate the live configuration settings in the UI is that the settings.phpfile overrides the UI click clicks. So you need to go to your file and either temporarily comment out that code or just reverse the logic. So here is what I do.

  1. Reverse the logic in the settings.php file. For me, I just have to switch out a ! in my code so that my dev and live environments are reversed.
  2. drush cr — Cache rules everything around me — Clear it
  3. drush cim Load all of your config from the live environment into your local
  4. Enable my new SMTP module.
  5. Edit the live config split and check the box next to the SMTP module
  6. drush cex — configuration export
  7. git checkout settings.php so that my file reverts back to my old settings
  8. drush cr— you know the drill clear that cache
  9. drush cimThis disables the SMTP module and loads just the development modules on your core
  10. git commit my changes

I then check my setting by doing a drush csim live. This command imports the settings from the live config. You can also check your config directories manually or with a git statusto ensure there are new files in both of your dev and live directories.

If any of you have a better way to enable and add some new configuration to the live environment without all of the steps, help a brother out and let me know in the comments.

Jun 18 2021
Jun 18

Drupal 7's end of life is scheduled for November 28, 2022. Up until then, the Drupal Security Team will continue to provide patches to Drupal 7 core and contributed projects should any security threats arise. After that point, however, the Drupal Security team will no longer support Drupal 7.

Is it Safe to Stay on Drupal 7?

If your organization is currently running Drupal 7, you’re faced with a decision on whether to upgrade to Drupal 9 or not.

Crafting a business case can help with your decision because it contains projections for initial costs and ongoing costs for making the upgrade investment vs. maintaining the status quo, as well as projections for revenue and savings. The business case exercise can further forecast the break-even point for your upgrade investment. However, in the case of future security threats, we can’t be confident of what the future ongoing costs will be, because we can’t predict when such security threats will arise, nor will we know the severity of them. 

What we can do, however, is make organizations that use Drupal aware of the risks of not upgrading. There are three general areas of risk: security, integrations, and functionality.

Security Risks

After Drupal 7 reaches the end of life, whenever security issues are identified in core or contributed modules, there won't be very much support to fix them. Site maintainers could find themselves in the position of having to spend a lot of time searching for security holes and fixing them. This risk gets compounded if there are a lot of contributed modules in your Drupal configuration. 

There will be a few agencies that will offer the service of maintaining your Drupal 7 platform post end-of-life. This will help greatly to secure your site if you’re willing to invest in hiring such an agency. One of their main tasks is to backport fixes for core and contrib issues. These fixes will of course not be included in the D7 upgrade path because there won’t be an upgrade path at all. As a point of reference, after Drupal 6 had reached its end of life, there weren't a disproportionate amount of security fixes needed for its core nor contributed modules. Still, the risk is not zero. Every aspect of a Drupal application must be considered to ensure there are no security gaps.

Another aspect of taking this path is that much of the time maintaining a site like this is spent managing and mitigating security risks rather than making improvements or implementing new features. For a good many developers, this is not rewarding work. 

In the history of previous Drupal security fixes, some have been pretty small -- one-line changes that take an hour to review and fix -- while others have taken days or even weeks of development time to analyze and produce a solution for. 

An advantage of choosing to upgrade a Drupal 7 site to Drupal 9 is that you gain all of the advantages of security improvements that were included in Drupal 8 and each subsequent feature upgrade. In this blog post, Peter Wolanin of Acquia details some significant security improvements included in the initial Drupal 8 release. Drupal 9 has additional advantages such as support for PHP 8.0.

Integration Risks

Certainly, security risks will come along, but another risk area in maintaining the status quo is that key integrations will eventually start to fail. For example, your Drupal environment may be integrated with another platform, and a key API on that platform is getting deprecated. Because the Drupal module that connects to it is no longer being actively maintained, you (or an agency you hire) will have to update the module or write a new custom module to keep integration working.

Functionality Risks

As the Drupal community continues to diminish the amount of activity on Drupal 7 core and contributed modules, especially after end-of-life, you basically lose those “free” updates. This is especially so with bug fixes. This forces you to either live with them or to fix them, or again, hire an agency to do it. If you do hire someone, that person won’t be as familiar with the project as one of the maintainers would be, so you’d have to factor in that additional investment. Indeed, some of these risks can be so critical that you end up rewriting large chunks of code to deal with them.

Not only do you miss out on the security improvements of Drupal 8/9 discussed above, not upgrading means you're missing out on many other improvements. Drupal 8 and 9 are built around a modern PHP stack including features such as Composer compatibility, Symfony components, modern OOP coding techniques, and more. While Drupal 7 has served our community well, it is not built upon the latest PHP libraries and development workflows that developers expect. This allows Drupal 8/9+ site owners the advantage of further enhancing their security posture by adding the Guardr security distro or module. While Drupal 8 and 9 have good security features, Guardr adds additional community vetted modules and settings which meet industry security requirements.

Talk To Us

As already mentioned, there are too many future unknowns to create a blanket business case for an upgrade investment. However, we can craft a business case specific to you based on the complexity of your existing Drupal 7 solution. We will factor in the number of modules you’re using, their complexity, the nature of your integrations with external systems, and more. We at Mediacurrent have performed this type of analysis for some of our clients to help them with their technology investment decisions and can do the same for you. Please contact us to learn more!

Jun 15 2021
Jun 15
[embedded content]

Don’t forget to subscribe to our YouTube channel to stay up-to-date.

When someone tweets a link from your website, Twitter can use Twitter Cards to attach rich photos, videos and media to Tweets.

By doing some minimal configuration changes on your Drupal site using the Metatag Module and the Twitter Cards submodule, users can see a “Card” added below the tweet that contains neatly formatted information coming from your website, as shown in Image 1 below.

Image 1 shows an example of a “Card”.

The cards are generated using HTML markup in the HEAD region of your Drupal site; that’s why the Metatag module is used.

Twitter will scrape your site and generate the card using the HTML meta tags.

Table of Contents

Twitter Cards

There are four variations of Twitter cards. They are:

  1. Summary Card – Displays Title, description, and thumbnail
  2. Summary Card with Large Image – As the name suggests, similar to Summary Card but with a larger image
  3. App Card – A Card with a direct download to a mobile app. Use this Card to drive app downloads
  4. Player Card – Displays video/audio/media.

Image 1 above shows a “Card” of type Summary with Large Image.

In this tutorial, we will look at the steps involved in setting up the “Summary Card with Large Image” Twitter Card.

Getting Started

The Metatag module has a dependency on the Token module. However, if you download and enable the Drupal module using Composer and Drush, the dependency is automatically taken care of as we will show you now.

Use composer to download the module:

composer require drupal/metatag

Once the Metatag module is downloaded using composer, the Token module, which is a dependency, will be downloaded automatically.

Then enable the “Metatag: Twitter Card” submodule:

drush en metatag_twitter_cards -y

The above Drush command will automatically enable the Metatag: Twitter Card submodule, Metatag module and Token module.

Finally, it is always a good idea to clear the cache after enabling Drupal modules:

drush cr

Configure Twitter Cards

By default, Twitter Cards can be added to any content type. We will now configure the Twitter Cards for the Article Content type.

1. Go to Configuration > Metatag (admin/config/search/metatag) and click on “Add default meta tags”.

2. On the next page, select “Article” (or whatever content type you want to configure) from the Type dropdown.

3. Then click on Save. This is required for the correct tokens to appear in the “Browse available tokens” window.

4. Edit the “Content: Article” configuration from the Metatag page.

5. Click on “Twitter cards” to expand the field set and then select “Summary Card with large image” from the Twitter card type dropdown.

6. Now, we have to add tokens into the correct fields. Click “Browse available tokens.” then click on Nodes.

NOTE: If you can’t see “Nodes”, this means you need to save the “default meta tag” option first then edit it again.

Fill in the following fields:

  • Description: [node:summary]
  • Site’s Twitter account: Add your twitter account, i.e., @webwashnet
  • Title: [node:title]
  • Page URL: [node:url]
  • Image URL: [node:field_image] (adjust the field name accordingly)
  • Image alternative text: [node:field_image:alt] (adjust the field name accordingly)

Find Image Field Token

For this type of Twitter card, an image field must exist in your content type. We will show you how to use Token to grab that image data. Click on “Browse available tokens”.

Then drill down by going to Nodes -> Image. This assumes you’re using the Image (field_image) field on the Article content type.

The token should be [node:field_image].

Once you have found the image entity URL, make sure your mouse focus is in the empty Image URL Twitter Card meta tag field, and then click on the image entity URL token value. This will copy/paste the token value into the Image URL field.

Find Image Field Token on Media Asset

If you’re using a media field instead of an image field for handling assets, then use the following token, [node:field_media:entity:thumbnail] (change the field_media name accordingly).

7. Configure any extra fields as needed, then scroll down and click on Save.

8. Once you have filled out the other Twitter Card fields with their respective token values, you should validate the end result markup using the Twitter Card Validator tool. We will now show you how to validate your Twitter card.

As you can see, Twitter successfully recognised our “Summary with large image” card and displayed the information correctly.

NOTE: You’ll need to make sure your website is publicly accessible for the validator tool to work.

View HTML Source

If you want to see the generated markup, view the HTML source on your Drupal site and look for the “twitter:*” meta tags.


Twitter can display a neatly formatted version of your website’s content whenever someone’s tweets a link to your content. There are various types of Twitter cards depending on your needs.

We have shown how you can use the Metatag module and Twitter Cards submodule to configure Drupal 8 to correctly send your website’s content to Twitter and how to validate your markup to ensure Twitter correctly parses your website content.


Q: I changed the default meta tag configuration, but the tags are not changing?

Try clearing the site cache. Go to Configuration > Performance and click on “Clear all caches”.

Jun 01 2021
Jun 01

Are you still on Drupal 7 or 8?

All software, even that of Drupal’s top world ranking open source community, comes with a shelf life.

Drupal 7 is now a decade old, with the advent of Drupal 8 falling just four years behind. These previous major Drupal versions weren’t left in the dust with the release of Drupal 9 in the summer of 2020. But that support has an expiration date coming soon. Both versions 7 and 8 have set “End of Life” dates which means they will no longer be supported by the official Drupal community.

Version 9: Drupal in its Prime

Organizations are moving to Drupal 9 to reap the benefits of fresh features and community-supported innovation. The pace of adoption is faster than ever. It took one month to go from 0 to 60,000 sites on Drupal 9 compared to taking 7 months to get 60,000 sites on Drupal 7. Although good progress is being made with organizations moving to Drupal 9, there are still thousands of Drupal 7 and 8 sites live. If you have a Drupal 7 or 8 site, you need to start planning immediately to ensure you are prepared for support ending.

So, what is Drupal 7 and 8 End of Life?

End of Life marks the date when the Drupal community officially stops supporting older versions of Drupal. The Drupal community has always supported the current and previous versions of Drupal but with the launch of Drupal 9 last year and Drupal 10 scheduled for June 2022, “End of Life” is quickly approaching for Drupal 8 and Drupal 7’s days are numbered as well.

key dates for drupal 7 and 8

State of Drupal presentation (April 2021)

It might come as a surprise (and seem a little odd) that Drupal 8’s End of Life occurs before Drupal 7’s. There are a couple reasons behind this. First, the transition from Drupal 8 to Drupal 9 is not a significant effort in most cases. Drupal 9 is not a reinvention of Drupal, with only two key differences; updated dependencies and deprecating APIs. The Drupal Association illustrates the transition from Drupal 8 to 9 as just a station on the same track (versus moving the train to a different track entirely for previous upgrades). The other reason is Drupal 8 is dependent on Symfony 3 and Symfony 3’s end of life is November 2021.

drupal upgrade train track illustration

Source: Understanding How Drupal 9 Was Made, Drupal.org

For Drupal 7, the original end of life was set for November 2021 but due to the impact COVID-19 had on many organizations who are still on Drupal 7, no dependencies on Symfony 3, and the effort needed to upgrade from Drupal 7 to Drupal 9 (requiring a migration and site rebuild), the date was pushed out a year.

How does this impact you?

Drupal is an Open Source project with a uniquely robust security model:

  • Drupal has a dedicated team of Security professionals who proactively review core and contributed modules for vulnerabilities.
  • When a security vulnerability is identified, the Drupal Security Team is notified and code is quickly fixed to remove the vulnerability.
  • When a fix is available an announcement immediately goes out and a patch is released to the community. Drupal sites are also automatically notified that they need to upgrade.

When Drupal 7 and 8 support ends, there will be no more Drupal core updates to Drupal 7 and 8 - even for critical security issues. The contributed modules that power your site will also no longer be actively tested and reviewed, patches and security evaluation will depend on your internal resources.

A recent study indicates that nearly 12 million websites are currently hacked or infected. Ensuring you correctly handle the security implications of Drupal 7 and 8’s End of Life is essential.

What do YOU need to do?

Without taking active steps to protect your website, you are going to be vulnerable to a security breach. Drupal 7 and 8 are widely-used content management systems that have served as a platform for some of the world’s largest websites. It is public knowledge that support for it will be ending. It’s likely that hacking groups are waiting for official support to end to use security exploits that they have already discovered to increase the number of systems they can access before they're patched.

Mitigating this risk is much easier with an experienced partner. We advise our clients to take the following steps:

  1. Ensure your website will be secure after Community Support ends. You can do this by developing an internal plan to monitor future Drupal 7 or 8 security releases, or engaging with your Drupal hosting provider and agency to cover you while you plan and execute the move off of Drupal 7 or 8.
  2. If you’re on Drupal 7 or 8, it’s likely that the time is now for a reassessment of how you use the web. Partnering with an expert Drupal agency like Mediacurrent will help you to reassess your website plans, determine if your Digital Strategy is effective, and ensure your next platform serves your needs now and can adapt in the future.
  3. Once you have identified the correct platform, plan and execute your migration. By taking care of security first, and securing the right partner, you can take the time to correctly plan and build your next Digital Platform in Drupal.

Learn to love the upgrade

While Drupal 7 and 8 End of Life might mean more work for you, we view it as an opportunity. The way we consume information on the web has changed drastically since Drupal 7 and 8 launched, and if you are still on these versions and not planning on innovating, you are likely putting yourself at a serious competitive disadvantage.

In the longer term, sticking with Drupal 7 or 8 not only means you will be fighting a constant battle against security vulnerabilities, but also that you will be doing so with a dwindling number of allies. As time goes on, Drupal 7 and 8 sites will disappear. Fewer agencies will offer any sort of Drupal support for these versions. The talent pool of developers will dry up - anyone who learns Drupal today will be learning on newer releases.

Upgrading from Drupal 7 or 8 to Drupal 9 is the opportunity to revolutionize the way you think about the web as a business tool. If you have a Drupal 7 or 8 site, you have almost certainly had it for at least five years. How many little usability improvements have you considered in that time? Is your design dated? Does your site build reflect modern practices in SEO (Search Engine Optimization), accessibility, and user experience?

With Drupal 9, Upgrading is about more than just security

Out of the box, Drupal 9 offers a significantly more powerful feature set that allows you to build the modern digital experiences you need to compete on today’s web.

At this time, no new features are being added to Drupal 7 or 8. All the innovation is happening in Drupal 9!

Look at Drupal 9’s core features:

All the best of Drupal 8 - Drupal 8 came with many new features such as an improved authoring experience with Layout Builder, an API-first architecture that opens the door to a decoupled CMS, TWIG templating engine for improved design capabilities, and built-in web integrations to name a few. All of these features are carried over to Drupal 9.

Intuitive tools - Improving Drupal’s ease-of-use remains a top priority. Easy out of the box, a new front-end theme, and automatic updates are among the strategic initiatives for Drupal core.

Future upgrades - Upgrades will be seamless for future releases. You will no longer be forced to replatform as new versions are released.

Stay on the edge of innovation - Adopting Drupal 9 will give you access to the latest new feature releases, happening twice a year.

Powerful Distributions - If you’re planning a Drupal 9 project, you don’t have to start with a blank slate. Drupal distributions like Rain CMS can be used as the “starter” for your next Drupal project.

Prepare for an upgrade with a Drupal 9 Audit

Upgrading can certainly come with challenges. As you start planning for an upgrade, a good starting point is performing a readiness audit. An audit assesses the level of effort and provides recommendations for a smooth migration path to Drupal 9.

For more information on our Drupal 9 Readiness Audit, or to start the discussion about transitioning to Drupal 9, please visit our contact page or chat with us right now (see bottom right corner of the page). We would be happy to talk more about your project.

May 31 2021
May 31
[embedded content]

Don’t forget to subscribe to our YouTube channel to stay up-to-date.

Drupal comes with a toolbar which is useful when administering a Drupal site. If you log in and have the correct permissions, you’ll see a toolbar across the top of the page that allows you to access back-end configuration pages.

The Admin Toolbar module extends the functionality of the toolbar and gives you lots of extra features such as drop-down menus, access to cache and cron settings and an autocomplete search.

In this tutorial, you will learn how to install and configure Admin Toolbar and its sub-modules.

Table of Contents

Getting Started

Let’s begin by downloading the Admin Toolbar module.

Run the following Composer command:

composer require drupal/admin_toolbar

Then go to Extend and install Admin Toolbar and its three sub-modules.

Functionality around the toolbar is spread across four modules in total. Here’s a breakdown of what each module does.

Admin Toolbar

Provides an improved drop-down menu interface to the site toolbar.

Admin Toolbar Extra Tools

Adds menu links like Flush cache, Run Cron, Run updates, and Logout under the Drupal icon

Admin Toolbar Links Access Filter

Provides a workaround for the common problem that users with ‘Use the administration pages and help’ permission see menu links they don’t have access permission for. Once the issue https://www.drupal.org/node/296693 be solved, this module will be deprecated.

Admin Toolbar Search

Provides quick search functionality for configuration pages.

Let’s take a look at each module in more detail.

This module is the base module of Admin Toolbar. After installation, it provides drop-down functionality on top of the standard toolbar.

There is a new version 3.0.0 released recently, which requires Drupal 8.8 or above. With this version, a new configuration form was introduced to limit the number of bundles to display in the drop-down menu, resulting in performance issues.

To configure this new mechanism, go to:

Admin > Configuration > User interface > Admin Toolbar Tools

The default value is 20, but can be modified here. Just pay attention to the warning on this page which says ‘Loading a large number of items can cause performance issues.’. We can leave it 20 by default to start with.

This sub-module adds extra drop-down functionality to the base module by providing the following additional functions:

  • Additional menu items are available in the drop-down functionality
  • An extra Drupal logo icon will be attached to the left corner of the Admin Toolbar, which provides additional functions in a convenient manner:
  • Index – provides a list of functions indexed in alphabetical order
  • Flush all caches – flush all caches, or individual caches of the system.
  • Run cron – run a cron job immediately, instead of waiting for the default time period of 3 hours.
  • Run update – run a system update process, generally after system or module updates.
  • Logout – provide fast access to the logout function.

This sub-module offers a workaround for users which have the ‘Use the administration pages and help’ permission but not access to the specific pages. Menu items are still visible even if the user doesn’t have access.

Once https://www.drupal.org/node/296693 is fixed this module will be deprecated.

This sub-module doesn’t require any configuration, just install and you’re done.

An ‘Admin toolbar quick search’ box is provided on the Admin Toolbar. This is useful for beginners, site builders or administrators who are not familiar with Drupal. They can find the functions they are looking for, administrative or configuration pages by searching here.


Admin Toolbar is a must-have module on any Drupal site. It gives site administrators and builders a better user experience when managing content and configuration.

I especially like the quick search functionality offered by “Admin Toolbar Search”. This makes it easy to search for configuration pages.

May 25 2021
May 25

open waters podcast logo

Open Waters Podcast: Season 2, Episode 2 

In this episode of the Open Waters Podcast, Donna Wicks, a Web Strategist at Kettering University joins us to discuss web accessibility in higher ed. We explore engaging accessibility-related topics including marketing to prospective students, user experience, accessibility tools and training, and much more.

Episode Transcript 

Shrop: I'd like to thank everybody for joining us again on the Open Waters podcast again. With us today is Donna Wicks from Kettering University. Donna, welcome to the podcast. We're excited for you to be here today. We also have Susan Cooper co-hosting today.

Donna: Thank you. I'm excited to be here.

Susan: I'm excited to talk about accessibility today!

Shrop: Yes, especially accessibility within higher ed. It certainly applies to all of the web but higher ed has its own demands and concerns. It's great to talk to Donna and learn a little bit more about it. For Kettering's site, for example, how important is accessibility when it comes to generating leads?

Donna: It's very important. The pool of applicants is shrinking everywhere. We all know that the number of high school students going on to college has decreased. So now you're talking about needing to really compete for every available body up there. It becomes even more important in today's age when you need to be hyper-focused on every single lead. So we pay attention to the accessibility issues that anyone might have.

Susan: Could schools be turning potential students away by not providing accessible websites? 

Donna: I would think so. For those of us who do the marketing side of websites for schools, we have to be very mindful that we are often that first impression of what a campus might be like. So we really want to pay attention that people can get to the information in a way that makes it as easy as possible for them to get to and in a way that they can consume it. Accessibility is definitely something that could affect their decision of whether to continue to pursue an interest in the university or even come to campus to see what it's like.

Shrop: Has accessibility always been at the forefront of Kettering's goals for a good user experience? If not, what has made accessibility more noticeable in recent years?

Donna: I would say that it's becoming bigger as time goes on. I started in my position in 2012, but prior to that, I had been a system administrator for our learning management system. And of course, accessibility has always been at the forefront with that. So I was mindful of it, but I don't think I was quite aware of all the standards that we should be meeting and all the difficulties somebody might have.

As time goes on, the admission staff, the marketing staff, everyone's becoming more aware of the accessibility issues. It's starting to get some more attention. All visitors to a website benefit when we concentrate on meeting accessibility standards.

Susan: Now that there is more awareness and accessibility is more at the forefront, do you perform routine accessibility audits? How do you know that you're upholding the standards that you're trying to keep?

Donna: Best practices are that we should be doing audits and it is something I strive to do. We're a small university, with a small web team. Some of the things that I do are anytime that I see content being created, whether it's for our marketing sites, that I directly am responsible for a digital ad, or even some of our print pieces. I am constantly pointing out information, as I understand it, that might not meet the accessibility standards that we should be striving for. It's easier to do that sort of education for anyone involved in the process of marketing so that they become aware of where they should be shooting. As they become more educated, I have less to worry about going back and looking, I can begin to set up some of those audits. Maybe check with me next year and I can proudly say, yes, we're doing audits on a regular basis. And we don't have problems that exist longer than 24 hours on the website. We'll continue to strive for it.

Shrop: I'm involved a lot in the security side of web development and we have the same attitude. We want security to be something that everybody thinks about and asks questions about and is always concerned with.

Susan: I think most schools have good intentions to comply with accessibility guidelines. But what are some of the reasons that they may fall behind? What are some of the struggles?

Donna: Well, from my personal experience, the amount of information out there is simply overwhelming. I of course started with just looking up accessibility guidelines. They're out there and they're spelled out in great detail, but it's a matter of trying to figure out what are the important things I should focus on initially. What can I reasonably do? From my perspective, I would love to find a group or start a group of some kind focused on higher ed and what accessibility means for, in particular, the marketing materials that we send out. I think higher ed has done accessibility very well on the learning side. But for reaching out to prospective students, many universities have been doing it, but not necessarily in a standard way. We all sort of pick and choose which standards we want to reach. 

The great thing about higher ed is universities love to collaborate with each other and user groups are a great way to go. People love to share information, and I simply just have not stumbled on it. Maybe it's out there. So if one of the listeners knows and wants to ping me at Kettering, I'd be happy to take a look. But to me, it's the amount of information. I think people look at it and they simply go, whew, I'm not going to worry about it until somebody points a finger and says you can't do that. We have to figure out as a group, how do we do this so that people are proactive about the issues rather than trying to be reactive to either a complaint that's come through or somebody who has noticed something saying thou shall not.

Shrop: It sounds like accessibility is very challenging, especially in a university setting. With that challenge, do you know of any cases where legal action has been taken against the school or lack of accessibility compliance?

Donna: The US Department of Education will randomly select some schools to tell them that they may open an investigation. We ourselves received a notice about a year and a half ago, and then they did follow through with an investigation. That sounds very scary. And it was kind of a long involved process, but the US Department of Education will work very well with you. They meet with you, they go through everything that they found, and that's not just necessarily on one web property. They will look at multiple web properties. If you've got a PDF that you've linked to, they will look at that and run their accessibility tools against it. 

For us, most of the corrections could be taken care of within a matter of days. The problem that I was running into is that the site that I was using at the time really hadn't been developed with an accessibility focus. It had the tools for me there to use, but it wasn't forcing me to use them. And as we all know, we get in a hurry and it's easy to skip that alt tag. It didn't force me to use certain colors, so we would start getting into color contrast issues.

This came at a time when we were working with Mediacurrent to move to and develop a Drupal 8 site. One of the first things we did was create a whole style guide around ensuring that we were going to meet those minimal accessibility standards that everybody should be meeting.

Susan: You mentioned alt tags as low-hanging fruit for accessibility. What are some other simple improvements that higher ed websites should be thinking about making that can really make a big difference in someone's experience using the sites?

Donna: One of the things that anyone should be testing as soon as you've created navigation and or a page, is just to do that simple tab, keyboard, accessibility test. So you're just taking the tab key and tabbing through the page. Color contrast -- that's a no-brainer. Our site was developed with a color palette. I can't stray off that, as much as I might want to! That way, I know if I'm putting text on top of a color, that it will need the highest level of accessibility. Another issue that I've run into is when our marketing department develops images for social media or digital ads where they have taken this wonderful graphic and put all this text in it. I simply won't use it on the website anymore. That text is either too long for an alt tag or there is no reason for the text to be embedded. That’s another win. Don’t use images with words in them. You want to make sure you’re keeping images as clean as possible for every visitor on the site.  

Susan: We have one final question for you that's not necessarily related to accessibility, but it is related to marketing in general. What's something that you think every marketer should read, listen to, or watch this month?

Donna: Besides this podcast? [laughing] For me, one of the things that I have found I've been doing for the past month so I was, I've also been looking at SEO and what we need to do for SEO and stumbled onto Google Trends. It is absolutely fascinating to me to go out every day and see what's been trending on Google for the past day or past week, or what's actually currently trending on Google.

I recommend it highly - anybody who's in marketing should be looking at Google trends. We can't always tell people they should be interested in us; we have to figure out what they're interested in and show how we're relevant to those interests

Shrop: Thanks again so much for your time today, Donna, this is fascinating learning more about accessibility in higher ed. I know Susan and I learned a lot about it.

May 18 2021
May 18

php code on a laptop screen

To keep your organization at the forefront of open source security and innovation now's the time for a Drupal upgrade or migration to Drupal 9. Drupal 7’s end-of-life is November 2022, but if you’re currently on Drupal 8 the end-of-life hits in November 2021.

In this guide, we’ll cover Mediacurrent’s tried and tested approach to upgrading sites of all sizes. Kick-off with a codebase audit. Then, tackle code and compatibility issues. In the final mile, run a first-attempt upgrade to find and fix any remaining issues. And finally, the actual Drupal 9 upgrade.


As you think about your upgrade path (whether moving from Drupal 7 or 8), a good starting point in preparing for Drupal 9 is performing a readiness audit. An audit will assess the level of effort and provide recommendations and preparations for a smooth upgrade or migration path to Drupal 9.

At a high level, a Drupal 9 upgrade process would look like this:

  1. Audit the codebase for deprecated code

  2. Audit the codebase for composer compatibility

  3. Fix deprecated code issues

  4. Fix composer compatibility issues

  5. Attempt Drupal 9 upgrade and see what’s left

  6. Perform actual Drupal 9 upgrade

In the first blog post of this Drupal 9 Upgrade series, I will focus on the first two steps and show you how to audit a codebase for Drupal 9 readiness. By the end, you will have a better understanding of the process and level of effort required for a successful upgrade and be more prepared to estimate a budget and timeline.

Audit for Drupal 9 Readiness

Performing an initial audit on the codebase is straightforward. This process should result in tickets in your task management system of updates to be performed way before the actual Drupal 9 upgrade release date.

Scan for deprecated code

Drupal-check is an invaluable tool for scanning files in a codebase to check their Drupal 9 readiness by looking for deprecated code -- basically code that was previously lingering around in Drupal 8 but is now removed from Drupal 9.

If drupal-check helps you during this process, and I’m sure it will, consider sponsoring the ongoing development and improvements of the project.

Install drupal-check

The most typical way to install drupal-check is to install it as part of the project via composer as a dev requirement. Be sure to review the drupal-check installation documentation.

composer require --dev mglaman/drupal-check

Run drupal-check

The drupal-check command can be run on any single file or directory. These steps assume it was installed in the project with composer, therefore the executable exists in the “vendor” folder and can be run as follows.

Here is an example of running the command against a contributed module that contains some deprecated code issues:

vendor/bin/drupal-check docroot/modules/contrib/allowed_formats

drupal-check error report

Now would be a good time to create a task in your task management system for addressing that deprecated code issue. Thankfully a solution already exists for the Allowed Formats contributed module that fixes this one particular issue.

That issue and fix were found by visiting the module’s project page that you are working on making Drupal 9 ready, search for “drupal 9” in the issue search box, and review what Drupal 9 related issues exist.

Allowed Formats module drupal 9 issue search

There is typically an issue labeled “Drupal 9 Deprecated Code Report”, but it may be named something else, and there may also be multiple related issues.

Allowed Formats module Drupal 9 issue list

Here is another run of drupal-check against another contributed module, which in this case, has no deprecated code issues.

vendor/bin/drupal-check docroot/modules/contrib/crop

drupal-check success report

While it appears at this time that this module is Drupal 9 ready per the drupal-check tests, it may not be completely Drupal 9 ready yet. In the next section, we’ll look at ways to check composer compatibility, which once the module is both composer compatible and no code deprecations present, it will be in great shape for the Drupal 9 upgrade.

Good, but not perfect

The drupal-check tool is very helpful, but it is not perfect. Again, consider sponsoring the project to help continue future development and improvements!

One of the false positives drupal-check may report relates to class usage. For example, it may be validating a class that is used by a module that no longer exists in the codebase, e.g. old code from a Drupal 7 migration that’s no longer used, so there’s nothing to do about that.

Also, sometimes drupal-check does not catch certain issues. For example, the codebase had a custom module that still contained a call to the `path.alias_manager` service, but that service is no longer available in Drupal 9 and was moved to `path_alias.manager`. However, drupal-check did not report this as an issue - I only found out about this issue once the Drupal 9 site was built and I tried to access the page that was controlled by the code that contained that old, removed service class call.

An alternative to drupal-check is to use the contributed module, Upgrade Status, to check on the Drupal 9 readiness of your existing site.

You should now have a good understanding of what custom and contributed packages need work to make them Drupal 9 ready. Be sure to keep notes or skip to the Issue Tracking section below.

Check composer compatibility

In addition to the deprecated code issues, the codebase also needs to be compatible with Drupal 9 from a composer perspective. Without packages being Drupal 9 supported in composer, composer will simply not allow the codebase to upgrade to Drupal 9.

What’s Not D9 Compatible?

A quick test you can do right away is to run this command, which will list all packages that are only supported by Drupal 8. These will need to be updated to also support Drupal 9.

composer why drupal/core | grep -Ev "\^9"

Essentially, this command tells us which other packages depend on Drupal core that do not yet have a 9 version in its composer metadata. Composer will not allow a Drupal 9 upgrade. Read more about the Composer Why command.

The output of the command will look something like the following:

Composer compatibility check results

These values come from the composer.lock file and are basically the list of packages used in the codebase that depend on drupal/core, specifically packages that only work with Drupal 8. This should be pretty much all of the themes, modules, and profiles, unless they have been kept updated on a regular basis and when security releases are available and necessary.

Just to be clear, the first lines that start with “drupal/core” can be ignored, the only ones to focus on are the other lines that reference contributed (or custom) modules.

For instance, in the example above the Facets module has a current version of “1.4.0”, or 8.x-1.4. This module will need to be updated to a later version, or a patch added that makes it Drupal 9 compliant; it might also be worth testing the current dev snapshot, the necessary fixes might have been committed, just not available as a full release yet. It appears for Facets module, the 8.x-1.5 version adds the Drupal 9 support.

Results in this output should be added as new tickets in the ticket management system of packages needing updates to address the deprecated code and composer compatibility issues.

Issue Tracking

To track the status of packages and their Drupal 9 readiness, I recommend creating a spreadsheet that helps track the ongoing upgrade process and what needs to be done. The below is just a small subset of changes needed, but I do recommend having multiple rows per package, in the cases where there may be multiple Drupal.org issues to cover all the D9 related fixes you’ll need.

Without getting too deep into it right now (saving for the next blog post), I’ve seen deprecated code issues be addressed in one Drupal.org issue, and the fix was committed to the latest version. But simply updating to the latest version did not make it Drupal 9 ready, because there were still composer compatibility fixes, and in some more rare cases, even still some deprecated code issues that were missed in the first pass. So, those issues may be split among multiple issues on Drupal.org.

Tracking Drupal 9 issues in spreadsheet

This planning, tracking, and documentation will help you as you continue through the Drupal 9 Upgrade process and keep tabs on what is remaining along the way. It may also serve as a good starting point or baseline for the next Drupal 9 upgrade process you may be involved in.


This blog post focused on the up-front audit process and preparation work required to understand the amount of work required to get into Drupal 9 readiness status. In the next blog post in this Drupal 9 Upgrade series, we will work on fixing the deprecated code and composer compatibility issues we discovered and documented as a result of this audit process.

Mediacurrent is a top 10 contributor on Drupal.org and has created solutions to accelerate, ease, and enhance the upgrade process. We can help you prepare for a Drupal 9 upgrade. Reach out anytime if you want to discuss your Drupal upgrade path or are interested in our team performing a Drupal 9 audit on your site and how we can help you succeed.

May 18 2021
May 18
[embedded content]

Don’t forget to subscribe to our YouTube channel to stay up-to-date.

Creating a block using views is pretty straightforward. You could create a block to display a list of published articles or ones that have been promoted to the front page. Then you can add that block into any theme region.

But you may encounter a situation where you no longer have any articles which are published and then you end up with an empty block.

Views comes with a feature that allows you to hide a block if no results are returned and this is what will be covered in this tutorial.

Drupal Views Series

Table of Contents

Getting Started with a Simple Example

We need to display a block that lists all articles that have been promoted to the front page. This can easily be achieved by using a custom views block

The views configuration will look something similar to the following:

This is a block created from views, and we can place the block on the sidebar, like the following:

The criteria of the views setting is based on some articles having the ‘Promoted to front page’ option checked.

The Problem

However, sometimes articles may not be promoted at all.  As a result, there are no results returned from the views setup above, and the block will look like this:

How to Fix It

To avoid this situation, we can choose to Hide the Block when no results are returned.  In fact, there is an option of ‘Hide block if the view output is empty’ at the bottom corner of the views setting, which a lot of people might easily overlook.

Simply enable this option, and it is done.

With this option enabled, the block will disappear when the view returns no results, like the image below:


This ‘Hide block if the view output is empty’ option is actually one which is very useful, but it can be easily overlooked.

May 14 2021
May 14

When you are used to working in Drupal 8 and beyond, having to make changes to custom Drupal 7 code can be unpleasant. If you’re lucky, the code was well written and maintained and you can make your changes without feeling like you’re adding to a house of cards. Too often, though, the code is in a state where it could really use refactoring.

One of the many nice changes Drupal 8 brought about was changing most of the code over to object-oriented programming, or OOP. There are many benefits to this and one of them is that it organizes most of the code into classes. In Drupal 7, all that code was dumped into the .module files because that’s how things were done back then. But it doesn’t need to be that way.

Why Add OOP?

Drupal 7 may not have the OOP framework that Drupal 8 built, and you still need the hooks, but there are benefits to adding OOP to your refactor:

  • Upgrades - It gets your custom code closer to Drupal 8/9. If there is any thought of an upgrade in the site’s future, having the custom modules as close to Drupal 8/9 as possible will make that upgrade easier.
  • Clean Code - It makes your Drupal 7 code cleaner and easier to maintain. Even if an upgrade is a long way off, having clean and organized code is much easier to maintain and reduces the chance of knocking down that house of cards when you need to make a change.
  • Easier Refactoring - It makes refactoring easier because you can work on a copy of the code that is moved to a new place rather than trying to do everything in place. As you move and refactor each function, you can easily see what code is refactored and what is still the old code.
  • Testing - It makes it easier to test your refactored code. There’s more on that in the “Testing the refactoring” section below. If you are following along with this blog post and making changes to your module as you go, you’ll want to read that section before you start.

An Example Module

For the purpose of examples, let’s say we are refactoring a custom module called XYZ Events. Our site is for company XYZ and this module is where we stored all the custom functionality related to our events.

This module has custom menu items, blocks, and a bunch of miscellaneous helper functions all sitting in the .module file and we want to clean that up.

I’ll reference this fictional module to provide examples along the way.

Make class loading simple

To make using classes much easier, start with a very handy contributed module: X Autoload. X Autoload lets you make use of the automagic class loading that Drupal 8 has just by putting your classes in the proper directories and setting the namespace. With that in place, you are ready to start moving your code into classes.

Whenever you add a new class, be sure to clear the cache before you try to use it.

Services for all the miscellaneous functions

While hooks and a few other things need to stay in the .module file, chances are there are a lot of miscellaneous functions that can be organized into one or more service classes. These won’t be true D8/9 services with the service.yml and all of that but they serve the same purpose. In theory, you could write your own service container if you wanted to push this even further but even just regular classes help.

Make the events service:

  • Add the directory “src” to the root of the xyz_events directory.
  • In there, add EventsService.php. It’s not required to have “Service” in the name but it helps make the purpose clear.
  • The basic outline of the class looks like this:

Move the code:

For each of the non-hook, non-callback functions in the .module file (and .inc files), copy it into the appropriate class. Some functions might make more sense in a site-wide utility class if they aren’t directly related to the module’s “theme”. Once it’s in its new home, do the cleanup and refactoring:

  • Change the function names to camel case and remove the module name (ie: xyz_events_get_event_list() becomes getEventList())
  • Add the public, protected, or private designation to the front. Since these used to be in a .module file, most of them are likely to be public. But, if any functions are only used by other functions that are now in the same class, those could be changed to protected or private.
  • Now is a good time to clean up any coding standards issues. I like to use Drupal 8/9’s standards if I know I’m on a PHP version that supports it such as using short array syntax. This gets it as close to D8/9 as possible.
  • Do whatever refactoring is needed to make the code easier to follow, improve performance, fix bugs, etc.

Update calls:

Using grep, check your whole site to find out all the places where that function was being called. For any place it’s being called that isn’t already in the class, change the call from the old function to the new method:

  • Add $events_service = new EventsService(); if that isn’t already in scope.
  • Change xyz_events_get_event_list() to $events_service->getEventList()

If the call is within the class already, change it to use “$this” instead of the service reference variable:

  • xyz_events_get_event_list() to $this->getEventList()

You now have all the miscellaneous custom code in a service (or multiple services if it makes sense to divvy them up). When moving to Drupal 8/9, all that’s needed is to update the class so that it’s a proper service container service and then change the calls to go through the container rather than using “new SomeClass()”.

Block classes

Drupal 8 introduced blocks as classes which is much cleaner than the old style that used multiple hooks. If you have multiple custom blocks each with a chunk of code, hook_block_view() can get quite long and hard to follow. While the hooks themselves are still needed, the actual code can be split off into classes. hook_block_info() stays the same but hook_block_view() becomes much simpler. 

  • If you haven’t already, add a directory “src” at the root of the module directory.
  • In “src” add a directory structure “Plugin/Block”.
  • For each block in hook_block_view():
    • Add a file in “Block” that is BlockNameBlock.php. Like services, the “Block” at the end isn’t required but makes it clearer what the class does. For our example module, we end up with UpcomingEventsBlock.php and FeaturedEventsBlock.php.
    • Take all the code for generating that block out of the hook and put it in the class.
    • Replace the content in the hook with a call to the class.
  • If your blocks have a lot of similar functionality, you can take advantage of inheritance and move the common functionality into a base block. In our case, since both blocks are listing events, we add EventListingBlockBase.php.

In the .module file we have:

 * Implements hook_block_info().
function xyz_events_block_info() {
  $blocks = [];

  $blocks['upcoming'] = [
    'info' => t('Show upcoming events'),

  $blocks['featured'] = [
    'info' => t('Show featured events'),

  return $blocks;

 * Implements hook_block_view().
function xyz_events_block_view($delta = '') {
  $block = [];

  switch ($delta) {
    case 'upcoming':
      $block_object = new UpcomingEventsBlock();
      $block = $block_object->build();

    case 'featured':
      $block_object = new FeaturedEventsBlock();
      $block = $block_object->build();

  return $block;

And then our blocks:


EventsService = new EventsService();

   * Builds the content for the block.
  abstract public function build();
   * Format the content into the array needed for the block.
   * @param string $title
   *   The block title.
   * @param array $items
   *   The complete list of items.
   * @param string $empty
   *   The text to print if there are no items.
   * @param string $theme_hook
   *   The theme hook for the block content.
   * @return array
   *   The block content array.
  protected function formatContent(string $title, array $items, string $empty, string $theme_hook) {
    // Only keep the empty text if there are no items.
    $empty = (count($items) == 0) ? $empty : '';

    $variables = [
      'items' => $items,
      'empty' => $empty,

    $content = [
      'subject' => $title,
      'content' => theme($theme_hook, $variables),

    return $content;


UpcomingEventsBlock.php and FeaturedEventsBlock.php both use the following code, just altering the “upcoming” to “featured” as appropriate.


    // What it should print if there aren't any.
    $empty = t('There are no upcoming events.');

    // The theme hook to use to format the contents of the block.
    $theme_hook = 'xyz_events_upcoming_events';

    return $this->formatContent($title, $items, $empty, $theme_hook);


Now all the content for building each block is encapsulated in the class for that block. When moving to Drupal 8/9, add the block annotation that it uses to identify blocks and remove the block-related hooks from the .module file.

If your blocks need configuration, this can be taken a step further by adding the form code and save code as methods on the block class and then referencing those from hook_block_configure() and hook_block_save().

Menu items to controllers

While hook_menu itself usually doesn’t get too overwhelming due to the actual code for the menu items being in separate functions, it does contribute to the .module file bloat. It’s also a lot nicer to have the menu items be in individual controllers like in Drupal 8/9.

To make this happen:

  • If you haven’t already, add a “src” directory at the root of your module.
  • Add a “Controller” directory under that.
  • For each menu item, add a file in there that is SomeController.php. Like services, “Controller” isn’t required but it makes it clearer. Another option is to use “Page” if the item corresponds to a viewable page rather than an API callback. For our example module, we end up with “UpcomingEventsController.php” and “FeaturedEventsController.php”.
  • As with blocks, a base controller can be used if the controllers have similar code.
  • Replace the hook code with a reference to the class (explained below).

There are two ways that the hook_menu() code can reference your class. Using a static function on the class and calling it directly or using a wrapper function to call the object.

Static method:

  • In hook_menu:
    'page callback' => 'UpcomingEventsController::build',
  • The build method on the class needs to be static.

Wrapper method:

  • In hook_menu:
    'page callback' => 'xyz_events_controller_callback',
    'page arguments' => ['controller_class' => 'UpcomingEventsCoursesPage'],
  • function xyz_events_controller_callback() needs to be in the .module file. (see below)
  • The build method on the class does not need to be static as we are instantiating an object.

In the .module file:

 * Implements hook_menu().
function xyz_events_menu() {
  $items = [];

  $items['events/upcoming'] = [
    'title' => 'Upcoming events',
    'page callback' => 'xyz_events_controller_callback',
    'page arguments' => ['controller_class' => 'UpcomingEventsController'],
    'type' => MENU_NORMAL_ITEM,

  $items['events/featured'] = [
    'title' => 'Featured events',
    'page callback' => 'xyz_events_controller_callback',
    'page arguments' => ['controller_class' => 'FeaturedEventsController'],
    'type' => MENU_NORMAL_ITEM,

  return $items;

 * Menu callback that wraps the controllers.
function xyz_events_controller_callback($controller_class) {
  $controller_class = "\\Drupal\\xyz_events\\Controller\\$controller_class";
  $controller = new $controller_class();
  return $controller->build();

The classes:


eventsService = new EventsService();

   * Builds the content for the page.
  abstract public function build();

UpcomingEventsController.php and FeaturedEventsController.php have the same code with “upcoming” changed to “featured” as needed.


    $content = theme('xyz_events_upcoming_events', ['items' => $items]);
    return ['#markup' => $content];


The rest of the hooks

While Drupal 7 relies on a lot of hooks and these need to be in a .module or .inc file so they can be found, there’s nothing requiring the actual code for the hooks to live in the functions. Like we did with blocks and menu items, the hook functions can serve as a wrapper around a call to a class where the actual code lives.

Testing the refactoring

While writing actual tests is the best way to test, that isn’t always possible with time and budget considerations. Still, you want to be sure your refactored code gets you the same results as the old code. Moving functions into classes while refactoring helps with that.

  • Add an include file to the root of the module. Ex: xyz_events_replaced_functions.inc
  • At the top of the .module file, add include_once 'xyz_events_replaced_functions.inc';
  • As you move functions into the classes, copy them into this file instead of deleting them from the .module file.

This keeps all the old functions active at the same time as the new ones which lets you test them in parallel within the same site.

Add this to the top of the module file:

 * Implements hook_menu().
function xyz_events_menu() {
  // Adds a testing page for dev use.
  $items['admin/code-test'] = array(
    'access arguments'  => array('administer content'),
    'description'       => 'Place to test code.',
    'page callback'     => xyz_events_test_code',
    'title'             => 'Code testing',

  return $items;

 * Place to put test code that is called from admin/code-test.
function xyz_events_test_code() {
  print("Test completed.");

Within xyz_events_test_code() you can do something like this:

Within xyz_events_test_code() you can do something like this:

$events_service = new EventsService();
$old_list = xyz_events_get_event_list();
$new_list = $events_service->getEventList();

Set a breakpoint at the top of the function and then visit /admin/code-test on the site. You can then step through and compare what you get running the original function vs running your refactored function and make sure the result is either the same or has any differences that you intended with the refactor.

Once you have finished and are ready to commit your refactor, delete the include file, the include line, and the testing code.

Wrapping up

At this point, your .module file should be much smaller, consisting of just hooks and things like callback functions that can’t be moved into a class. Your directory structure should look a lot like a Drupal 8/9 module with all the code wrapped up into classes. There will still be work needed to move to Drupal 8/9 in dealing with the API changes but the actual structure of the code and where things are found shouldn’t need much changing. And maintaining the Drupal 7 code until that time should be a much more pleasant experience.

Further reference

This blog post came from actual client work but that work was inspired by others. These two were my biggest sources for reference:

I didn't get into forms above but here's an article that covers them: https://roomify.us/blog/object-oriented-forms-in-drupal-7/

May 12 2021
May 12
[embedded content]

Don’t forget to subscribe to our YouTube channel to stay up-to-date.

When someone shares a Facebook post with a link to your website, Facebook lets you control how your website content appears to others by parsing your Open Graph (OG) markup.

By doing some minimal configuration changes on your Drupal site using the Metatag Module and the Metatag: Open Graph sub module, you can define what specific content can be shown on Facebook regardless of whether it’s shared from the desktop or mobile web or a mobile app.

It is easier to explain by showing the end result of what we are trying to accomplish. For example, the homepage of www.webwash.net has the following OG markup inside of the :

If someone posted www.webwash.net to Facebook, then Facebook would parse the OG markup like this:

And the end result would look like this:

You can clearly see the corresponding OG tags for the content.

If you want to learn more about the OG tags. Click here for a detailed list and explanations of the Facebook OG tags.

In this tutorial, we are going to show you how to configure a content type to dynamically populate the Facebook OG tags using the Metagtag module and Metatag Open Graph sub module.

Table of Contents

Getting Started

The Metatag module has a dependency on the Token module. However, if you download and enable the Drupal module using composer and drush, the dependency is automatically taken care of as we will show you now.

Use Composer to download the module:

composer require drupal/metatag

Once the Metatag module is downloaded using composer, the Token module, which is a dependency, will be downloaded automatically.

Then enable the “Metatag: Open Graph” sub module:

drush en metatag_open_graph -y

The above drush command will automatically enable the Metatag: Open Graph sub module, Metatag module and Token module.

Finally, it is always a good idea to clear the cache after enabling Drupal modules:

drush cr

By default, Open Graph can be added to any content type. We will now configure Open Graph for the Article Content type.

1. Go to Configuration > Search and meta data > Metatag and click on “Add default meta tags”.

2. On the next page, select “Article” (or whatever content type you want to configure)  from the Type dropdown.

3. Then click on Save. This is required for the correct tokens to appear in the “Browse available tokens” window.

4. Edit the “Content: Article” configuration from the Metatag page.

5. Then in the Open Graph fieldset on the same page, click to expand it. You will now notice quite an exhaustive list of OG tags that you can populate. Firstly, we are going to demonstrate how to populate the Image OG tag.

For this to be successful, your Article content must have at least an image field. We will show you how to use Token to grab that image data.

Click on “Browse available tokens”.

From the Token window click on Nodes to drill down and find the content type fields.

NOTE: If you can’t see “Nodes”, this means you need to save the “default meta tag” option first then edit it again.

Fill in the following fields:

  • Content type: article
  • Page URL: [node:url]
  • Title: [node:title]
  • Description: [node:summary]
  • Image URL: [node:field_image] (adjust the field name accordingly)

Find Image Field Token

To use an image stored in an image field, click on “Browse available tokens”.

Then drill down by going to Nodes -> Image. This assumes you’re using the Image (field_image) field on the Article content type.

The token should be [node:field_image].

Find Image Field Token on Media Asset

If you’re using a media field instead of an image field for handling assets, then use the following token, [node:field_media:entity:thumbnail] (change the field_media name accordingly).

6.After you fill out all of your OG tags fields, click on Save and clear the Drupal cache. If you do not clear your cache, the OG fields may not populate for existing content.

7. Once you have filled out the other OG fields with their respective token values, you should validate the resulting OG markup using the Facebook Sharing Debugger tool. We will now show you how to validate your OG markup.

NOTE: Your website has to be publicly accessible for the debug tool to work.

8. First we need to create a test Article node (make sure to upload an image to our image field). Our test article looks like this:

9. Paste the url for this node into the Facebook Sharing Debugger tool. The output should look like:

As you can see, Facebook successfully parsed our OG markup and displayed the information correctly.


Facebook lets you control your website’s content whenever someone’s shares a link to your content regardless of whether it’s shared from the desktop or mobile web or a mobile app. Facebook does this by parsing the Open Graph (OG) markup provided by your website. We have shown how you can use the Metatag module and Metatag Open Graph sub module to configure Drupal 8 to correctly generate the OG markup needed by Facebook and we have also shown how to validate your OG markup to ensure Facebook correctly parses your website content.


Q: I changed the default meta tag configuration, but the tags are not changing?
Try clearing the site cache. Go to Configuration > Performance and click on “Clear all caches”.

May 11 2021
May 11

Workflow automation is key in saving time, and money, in all aspects of a business. Accounting is one department that benefits from automation and our Quickbooks integration for Drupal can help remove manual data entry and free staff up to focus on other business objectives.

Automating accounting workflows with Quickbooks integration for Drupal

We all know as business owners that time is money. The more time we can save, the more time we have to work on other tasks for our business.

This is common sense, and is something every business owner should be looking to improve on every single day.

  • How can you save time?
  • What can you automate?
  • What type of processes can you create to become more efficient?
  • What systems and softwares can you use to become more organized?

These are things that you need to be looking at to not only save time for you and your staff, but so you can get things done right the first time. Having solid processes, automation and efficiency is how you create a smooth running business, that's why we decided to help out.

How Acro Media is contributing to workflow automation

Still learning? Find more info on business automation >While it’s hard for us to know what specific needs, systems and processes your business would need in order to save time, we have been looking for a solution to help the majority of our clients.

One category we know every business could use some help on, and by help I mean automate, is accounting and bookkeeping. This can be a huge time suck.

Manually inputting product orders, customers, refunds, credit memos, and invoicing takes time. If you use Quickbooks and don’t have any type of automation or integration setup with your Drupal site, these tasks can eat up a lot of manpower every month. Manpower that could be used to hunt new accounts, research better products or services and in general find ways to make you business better, instead of doing menial tasks.

Not to mention, if you are doing all of these tasks manually, there is always a chance for human error, and we know, all of humans make mistakes.(Frantically searches for typos, again.)

This is why Acro Media has made an effort to develop a module that can integrate and connect your Drupal site straight to your Quickbooks account. This module eliminates any chance of human error and will save you a HUGE amount of time every month as all your data from your Drupal site will be automatically pushed into your Quickbooks account.

If your business is a little unique or you require functionality that our module doesn't currently have, we can build it for you. Gotta love open source!

To get a better visual idea of what our new Quickbooks module can do, have a look at the infographic below.


How much time can you expect to save?

While there is no way for us to determine how much time you can save each month, we have put together a rough formula to see how this module can help you and your team save countless hours every single month.

We calculated the median time spent manually creating the following bookkeeping essentials:

  • Creation of an invoice or sales receipt: 2.5 min/order
  • Manual credit memo or credit note: 1 min/order
  • Payment processing or annotation: 1 min/order

Time saved = [amount of orders each month] X 4.5min

So, let’s turn that formula into a good old grade-school word/math problem:

You have a healthy ecommerce business, and your online store alone is generating 2,500 sales a month.

2,500 x 4.5 min is equal to 11,250 minutes a month. Or, 187.5 hours a month.

That means you are freeing up 1 full-time staff member and 1 part-time staff member every month by having your ecommerce site integrated and talking directly to Quickbooks. Not to mention the reduction in human error, the better data you will get out of your sales reports and the time your staff can now dedicate to anything other than manual data entry!

What’s next?

If you're looking for ways to save time in your business and focus on what matters most, reach out to our team and let’s see if this module is a right fit for your business.

Talk soon, and remember... time is of the essence.

Still have questions? Check out our business automation page >

Editor’s Note: This article was originally published on August 24, 2016, and has been updated for freshness, accuracy and comprehensiveness.

May 05 2021
May 05

Selecting a CMS for a university can be a challenging decision. There are so many needs and nuances to consider - costs of implementation and maintenance, a wide range of technical ability among site administrators, developers, and content editors, a variety of end-users looking for different information...and the list goes on and on. While your answer likely isn’t as easy as, “let’s just do what everyone else is doing,” better understanding why other universities made the choice they did can shed light on your decision-making process. 

Drupal is far and above the most used CMS in higher education - 26% of all .edu domain sites are in Drupal, including 71 of the top 100 universities. 

So why are universities like MIT, Georgia Tech, Butler, Stanford, Harvard and the rest of the Ivy League universities choosing Drupal? 

Simply put, Drupal makes good business sense, especially with the added benefits of Drupal 9. At Mediacurrent, we believe your website is your greatest digital asset and can be leveraged to accomplish organizational-wide goals. Drupal makes that possible. Here’s how:  

Communicate With All Students - Prospective, Current, and Alumni 

If you want to reach your full recruiting and fundraising potential, you need to communicate with your entire audience. There are a variety of Drupal features that ease the stress of common communication challenges. 


Not only are their multiple languages spoken within the U.S., but our country hosts over a million international students. Drupal makes creating a multilingual digital experience simpler. Native language handling is built directly into Drupal 8 and 9 core APIs, giving you over 100 languages to choose from. With that functionality, it is easier than ever to engage with prospective students across the globe in a meaningful way.


The CDC estimates that 20% of U.S. adults identify as having a disability. These disabilities often hinder people’s ability to interact with the average website. Drupal is an inclusive community and has committed to ensuring that all features of Drupal conform with w3C and WCAG 2.0. Pair Drupal’s built-in accessibility tools with a strong higher-education-focused accessibility strategy and your potential audience could grow by 20%. The Siteimprove Drupal module can help you keep a close and proactive eye on your overall web accessibility. 


 According to the College Explorer Market Research Study, the average college student owns 5.6 devices and spends 137+ hours on them! This may seem like common sense now, but if you want to engage with students, you need to account for a variety of screen sizes. Thankfully, Drupal 8 was designed with a mobile-first mentality and includes out-of-the-box responsive functionality.  And that mobile mindset continues with Drupal 9. Features like editorial workflows, Layout Builder, and media management can support content delivery that is optimized for mobile access.  


 Universities face added complexity when it comes to digital strategy due to the broad audiences they appeal to. With so many unique people coming to the same pages, content strategy, conversion path mapping, and optimization, and defining strong calls to action can be a struggle. By incorporating personalization into your content strategy, whether that is personalized based on user authentication or by integrating tools like Acquia Personalization or Salesforce Marketing Cloud, you can speak to the masses but make them feel like you’re speaking specifically to them. 

Reduce Overhead Costs + Increase Operational Efficiencies with Drupal

Drupal can have a dramatic impact on reducing overhead costs and increasing operational efficiency. Universities have a big need for multiple websites: departments, colleges, libraries, and student organizations all want their own website. The direct cost of supporting this many sites along with resourcing the training and support is expensive and encourages unnecessary technology sprawl. As an open source technology (no licensing fees!) along with the multisite feature, creating sites for these different groups is exponentially easier, more cost-effective, and ensures brand consistency. 

You can also increase efficiency, ensure content consistency and improve the user experience by creating a “source of truth”.

Write content once and publish it anywhere it’s relevant.

Having to update content such as a curriculum or an academic calendar on multiple pages is inefficient and unnecessary. Write once, publish everywhere, save time. 

Improve Brand Equity + Amplify Digital Strategy

As a university, your brand is a powerful asset. You spend significant energy and resources on building loyalty to bolster several organizational goals from recruiting efforts, engaging current students on campus, and fundraising among alumni.

With your website being the hub of your marketing strategy, it is critical for your CMS of choice to play nice with your marketing efforts.

Drupal is very SEO-friendly out of the box. There are also advanced configuration options available to support a more sophisticated SEO strategy. You can amplify your digital strategy by integrating your marketing tools and communication platforms directly with Drupal. And the 26% percent of other .edu sites using Drupal make integrating your university-specific tools to your website easier. 

Reduce Risk

I’d be remiss without mentioning open source security and GDPR compliance. As a university, you hold sensitive information about the students who have attended your school and they are trusting you to keep that secure.

The Drupal community is passionate about security and has an industry leading global security team to ensure your site is protected.

Additionally, as the landscape of privacy rights changes around the world, it’s in your best interest to stay on top of it and reduce the risk of being penalized for data collection practices. 

Speed up Your Time to Launch 

RainU logo

Drupal has a lot to offer to universities from the moment of install. We created RainU CMS to bring that out-of-box experience to the next level with a tailored approach. RainU is Drupal-based development platform that helps colleges and universities accelerate the web development process. 

Have questions about how Drupal and RainU can benefit your university? Let us know. We’d be happy to chat. 

Editor’s note: This post was originally published on July 18, 2018, and has been updated for accuracy and comprehensiveness.

May 05 2021
May 05

I proposed this session to DrupalCon, but it was not selected. I think that is good. I have had my fair share of stage time in DrupalCons in the past, new contributors should take the lead. However, I still did the work of creating the presentation, then recorded myself giving the talk.

This is a re-post of the article on the Lullabot blog.

Slides available here.

Drupal projects can be challenging. You need to have a lot of framework-specific knowledge or Drupalisms. Content types, plugins, services, tagged services, hook implementations, service subscribers, and the list goes on. You need to know when to use one and not the other, and that differs from context to context.

It is this flexibility and complexity that allows us to build complex projects with complex needs. Because of this flexibility, it is easy to write code that is hard to maintain.

How do we avoid this? How do we better organize our code to manage this complexity?

Framework logic vs. business logic

To start, we want to keep our framework logic separate from our business logic. What is the difference?

  • Framework logic - this is everything that comes in Drupal Core and Drupal contrib. It remains the same for every project.
  • Business logic - this is what is unique to every project—for example, the process for checking out a book from a library.

The goal is to easily demarcate where the framework logic ends and the business logic begins, and vice-versa. The better we can do this, the more maintainable our code will be. We will be able to reason better about the code and more easily write tests for the code.

Containing complexity with Typed Entity

Complexity is a feature. We need to be able to translate complex business needs to code, and Drupal is very good at allowing us to do that. But that complexity needs to be contained.

Typed Entity is a module that allows you to do this. We want to keep logic close to the entity that logic affects and not scattered around in hooks. You might be altering a form related to the node or doing with access or operate on something related to an entity with a service.

In this example, Book is not precisely a node, but it contains a node of type Book in its $entity property. All the business logic related to Book node types will be contained in this class.

final class Book implements LoanableInterface {
  private const FIELD_BOOK_TITLE = 'field_full_title';
  private $entity;

  public function label(): TranslatableMarkup {
    return $this->entity
      ->value ?? t('Title not available');

  public function author(): Person {...}
  public function checkAvailability(): bool {...}


Then, in your hooks, services, and plugins, you call those methods. The result: cleaner code.

// This uses the 'title' base field.
$title = $book->label();

// An object of type Author.
$author = $book->owner();

// This uses custom fields on the User entity type.
$author_name = $author->fullName();

//Some books have additional abilities and relationships
if ($book instanceof LoanableInterface) {
  $available = $book->checkAvailability() === LoanableInterface::AVAILABLE;

Business logic for books goes in the Book class. Business logic for your service goes in your service class. And on it goes.

If you are directly accessing field data in various places ($entity->field_foo->value), this is a big clue you need an entity wrapper like Typed Entity.

Focusing on entity types

Wrapping your entities does not provide organization for all of your custom code. In Drupal, however, entity types are the primary integration point for custom business logic. Intentionally organizing them will get you 80% of the way there.

Entities have a lot of responsibilities.

  • They are rendered as content on the screen
  • They are used for navigation purposes
  • They hold SEO metadata
  • They have decorative hints added to them
  • Their fields are used to group content, like in Views
  • They can be embedded

Similar solutions

This concept of keeping business logic close to the entity is not unique. There is a core patch to allow having custom classes for entity bundles.

When you call Node::load(), the method will currently return an instance of the Node class, no matter what type the node is. The patch will allow you to get a different class based on the node type. Node::load(12) will return you an instance of the Book class, for example. This is also what the Bundle Override module was doing.

There are some drawbacks to this approach.

  • It increments the API surface of entity objects. You will be able to get an instance of the Book class, but that class will still extend from the Node class. Your Book class will have all of the methods of the Node class, plus your custom methods. These methods could clash when Drupal is updated in the future. Unit testing remains challenging because it must carry over all the storage complexity of the Node class.
  • It solves the solution only partially. What about methods that apply to many books? Or different types of books, like SciFiBook or HistoryBook. An AudioBook, for example, would share many methods of Book but be composed differently.
  • It perpetuates inheritance, even into the application space. Framework logic bleeds into the application and business logic. This breaks the separation of concerns. You don’t want to own the complexity of framework logic, but this inheritance forces you to deal with it. This makes your code less maintainable. We should favor composition over inheritance.

Typed Entity’s approach

You create a plugin and associate it to an Entity Type and Bundle. These are called Typed Repositories. Repositories operate at the entity type level, so they are great for methods like findTaggedWith(). Methods that don’t belong to a specific book would go into the book repository. Bulk operations are another good example.

Typed Entity is meant to help organize your project’s custom code while improving maintainability. It also seeks to optimize the developer experience while they are working on your business logic.

To maximize these goals, some tradeoffs have been made. These tradeoffs are consequences of how Drupal works and a desire to be pragmatic. While theory can help, we want to make sure things work well when the rubber meets the road. We want to make sure it is easy to use.

Typed Entity examples

Your stakeholder comes in and gives you a new requirement: “Books located in Area 51 are considered off-limits.”

You have started using Typed Entity, and this is what your first approach looks like:

 * Implements hook_node_access().
function physical_media_node_access(NodeInterface $node, $op, AccountInterface $account) {
  if ($node->getType() !== 'book') {

  $book = \Drupal::service(RepositoryManager::class)->wrap($node);
  assert($book instanceof FindableInterface);
  $location = $book->getLocation();
  if ($location->getBuilding() === 'area51') {
    return AccessResult::forbidden('Nothing to see.');

  return AccessResult::neutral();

You already have a physical_media module, so you implement an access hook. You are using the global repository manager that comes with Typed Entity to wrap the incoming $node and then call some methods on that Wrapped Entity to determine its location.

This is a good start. But there are some improvements we can make.

We want the entity logic closer to the entity. Right now, we have logic about “book” in a hook inside physical_media.module. We want that logic inside the Book class.

This way, our access hook can check on any Wrapped Entity and not care about any internal logic. It should care about physical media and not books specifically. It certainly shouldn’t care about something as specific as an “area51” string.

  • Does this entity support access checks?
  • If so, check it.
  • If not, carry on.

Here is a more refined approach:

function physical_media_node_access(NodeInterface $node, $op, AccountInterface $account) {
  try {
    $wrapped_node = typed_entity_repository_manager()->wrap($node);
  catch (RepositoryNotFoundException $exception) {
    return AccessResult::neutral();

  return $wrapped_node instanceof AccessibleInterface
    ? $wrapped_node->access($op, $account, TRUE)
    : AccessResult::neutral();

If there is a repository for the $node, wrap the entity. If that $wrapped_entity has an access() method, call it. Now, this hook works for all Wrapped Entities that implement the AccessibleInterface.

This refinement leads to better:

  • Code organization
  • Readability
  • Code authoring/discovery (which objects implement AccessibleInterface)
  • Class testability
  • Static analysis
  • Code reuse

How does Typed Entity work?

So far, we’ve only shown typed_entity_repository_manager()->wrap($node). This is intentional. If you are only working on the layer of an access hook, you don’t need to know how it works. You don’t have to care about the details. This information hiding is part of what helps create maintainable code.

But you want to write better code, and to understand the concept, you want to understand how Typed Entity is built.

So how does it work under the hood?

This is a declaration of a Typed Repository for our Book entities:

 * The repository for books.
 * @TypedRepository(
 *    entity_type_id = "node",
 *    bundle = "book",
 *    wrappers = @ClassWithVariants(
 *      fallback = "Drupal\my_module\WrappedEntities\Book",
 *      variants = {
 *        "Drupal\my_module\WrappedEntities\SciFiBook",
 *      }
 *    ),
 *   description = @Translation("Repository that holds business logic")
 * )
final class BookRepository extends TypedRepositoryBase {...}

The “wrappers” key defines which classes will wrap your Node Type. There are different types of books, so we use ClassWithVariants, which has a fallback that refers to our main Book class. The repository manager will now return the Book class or one of the variants when we pass a book node to the ::wrap() method.

More on variants. We often attach special behavior to entities with specific data, and that can be data that we cannot include statically. It might be data entered by an editor or pulled in from an API. Variants are different types of books that need some shared business logic (contained in Book) but also need business logic unique to them.

We might fill out the variants key like this:

variants = {

How does Typed Entity know which variant to use? Via an ::applies() method. Each variant must implement a specific interface that will force the class to implement ::applies(). This method gets a $context which contains the entity object, and you can check on any data or field to see if the class applies to that context. An ::applies() method returns TRUE or FALSE.

For example, you might have a Taxonomy field for Genre, and one of the terms is “Science Fiction.”

Implementing hooks

We can take this organization even further. There are many entity hooks, and Typed Entity can implement these hooks and delegate the logic to interfaces. The logic remains close to the Wrapped Entity that implements the appropriate interface.

The following example uses a hypothetical hook_entity_foo().

 * Implements hook_entity_foo().
function typed_entity_entity_foo($entity, $data) {
  $wrapped = typed_entity_repository_manager()->wrap($entity);
  if (!$wrapped instanceof \Drupal\typed_entity\Fooable) {
    // if the entity not fooable, then we can't foo it

This type of implementation could be done for any entity hook.

Is this a good idea? Yes and no.

No, because Typed Entity doesn’t want to replace the hook system. Typed Entity wants to help you write better code that is more efficient to maintain. Reimplementing all of the hooks (thousands of them?) as interfaces doesn’t further this goal.

Yes, because you could do this for your own codebase where it makes sense, keeping it simple and contained. And yes, because Typed Entity does make an exception for hooks related to rendering entities.

Rendering entities

The most common thing we do with entities is to render them. When rendering entities, we already have variants called “view modes” that apply in specific contexts.

This is starting to sound familiar. It sounds like a different type of wrapped object could overlay this system and allow us to organize our code further. This would let us put everything related to rendering an entity type (preprocess logic, view alters, etc.) into its own wrapped object, called a renderer. We don’t have to stuff all of our rendering logic into one Wrapped Entity class.

Typed Entity currently supports three of these hooks:

  • hook_entity_view_alter()
  • hook_preprocess()
  • hook_entity_display_build_alter()

Renderers are declared in the repositories. Taking our repository example from above, we add a “renderers” key:

 * The repository for books.
 * @TypedRepository(
 *    entity_type_id = "node",
 *    bundle = "book",
 *    wrappers = @ClassWithVariants(
 *      fallback = "Drupal\my_module\WrappedEntities\Book",
 *      variants = {
 *        "Drupal\my_module\WrappedEntities\SciFiBook",
 *      }
 *    ),
 *    renderers = @ClassWithVariants(
 *      fallback = "Drupal\my_module\Renderers\Base",
 *      variants = {
 *        "Drupal\my_module\Renderers\Teaser",
 *      }
 *    ),
 *   description = @Translation("Repository that holds business logic")
 * )
final class BookRepository extends TypedRepositoryBase {...}

If you understand wrappers, you understand renderers.

The TypedEntityRendererBase has a default ::applies() method to check the view mode being rendered and select the proper variant. See below:

These renderers are much easier to test than individual hook implementations, as you can mock any of the dependencies.


Typed Entity can help you make your code more testable, discoverable, maintainable, and readable. Specifically, it can help you:

  • Encapsulate your business logic in wrappers
  • Add variants (if needed) for specialized business logic
  • Check for wrapper interfaces when implementing hooks/services
  • Use renderers instead of logic in rendering-specific hooks
  • Add variants per view mode.

All of this leads to a codebase that is easier to expand and cheaper to maintain.

Photo by James Harrison on Unsplash

Apr 30 2021
Apr 30

This DrupalFest series of posts is about to end and I thought that a fitting end would be to talk about the future of Drupal. I have already written a bit about this in my previous post: what I want to see in Drupal 10. However, this post is more aspirational and even dream-like. Some of these may sound really far-fetched and it may not even be clear how to get there. For the purposes of this post, that’s fine. I will not only worry about the how; just the what.

Modular code

Drupal is already modular; in fact, it is rather well designed. As Drupal grows and adds new features, the boundaries need to be redefined. The boundaries that made sense years ago for a set of features may need to be different today. The challenge is in maintaining backwards compatibility for the existing code ecosystem around Drupal. It also means fundamentally rethinking what are Drupal’s constructs. The transition from Drupal 7 to 8 was iterative and in many cases, the systems were just replaced from procedural to object-oriented. We need to rethink this. We should not be afraid to use the newest trends in programming and features from PHP, and rethink what architecture makes sense.

If you’re thinking this sounds too much like rewriting Drupal, you’re right. And maybe the time isn’t right for that, yet. I do believe there will be a time when this will become important. This will also help with testability which was the topic of my previous post about Drupal 10.

Assemblable code

Once we have code that’s modular, we can break it off into packages that can be reused widely. This is already in minds of several core developers and the reason why you see the Drupal\Component namespace. I want to see more systems being moved out not just in a different namespace but in different packages entirely.

The direct upshot of this is that you can use Drupal’s API (or close to it) in other PHP frameworks and applications. But that is not my main interest here. My interest in seeing this happen is that forcing the code to be broken this way will result in extremely simple and replaceable code. It will also result in highly understandable and discoverable code and that is what I want. Drupal core is opaque to most people except those who directly contribute to it or to some of the complex contrib modules. I believe that it doesn’t have to be and I wish we get there soon.


Taking this even further, I would like to see some way to break down Drupal’s functions over different servers. I am thinking there could be a server dedicated to authentication and another for content storage. This is a niche use case and therefore a challenge to implement in a general-purpose CMS such as Drupal. This would need kernels that can run in a stateless way and also breaking systems so that they can be run independently using their own kernels. The challenge is that all of this will have to be done in a way that won’t increase the complexity of the existing runtime. This, as you might have guessed, is contradictory.

More themes

I might not have thought about this sometime back. But with a renewed interest in the editor and site-builder, I think it makes sense to improve the theme offerings available to Drupal. There were many times when I build powerful functionalities but then show them in a completely unimpressive look. Olivero and Claro are big steps in this direction and I am hoping for more of the same quality. If there were, I wouldn’t have used Contrib Tracker for over 3 years with the stock bootstrap theme (even the logo was from the theme until recently).

Unstructured Content

Drupal is great at structured content but I see Drupal used more and more for unstructured pages. The way we do this now is using structured bases such as paragraphs to represent components but this method has its shortcomings. Paragraphs and similar concepts quickly get too complicated for the editor. Editing such pages is very painful and managing multiple pages with such content is tricky.

We now have the Layout Builder that is a step forward in addressing this problem. The ecosystem around the Layout Builder modules is scattered right now, in my perception, and I would love to see where the pieces land (pun intended). I would like to see Drupal fundamentally recognize these pages as separate from structured data so that the editing workflows can be separate as well. More in the next section.

Better media and editor experience

I know media is a lot better today than it was before but there’s still a long way to go. When working with pages (not structured content), I would like a filtered editing experience that lets me focus on writing. WordPress does this part well, but WordPress has a specific target audience because of which it can make this decision. This is the reason I previously said I would want Drupal to treat unstructured pages differently.

With a more focused editor experience, I would want better media handling as well. I want to paste images directly into the editor without worrying about generating resized versions. I also want pasted images to be handled somewhat similarly to the current media elements so that we can still deduce some structure. Even tiny things like expanding tweets inline and formatting code correctly could be supported in the editor and that could make a big difference.

Starter kits

We need ways to spin up sites for varied purposes quickly but I don’t think distributions are a good answer, at least not the way they are implemented right now. Once you install a distribution, you are stuck with it and would have to rely on distribution maintainers for updates. I think that’s a waste of effort. I know it’s possible to update parts of distribution without waiting for a release but the process is harder. And if a distribution is going out of support, it is difficult to remove it; it is almost impossible if the distribution authors don’t design for it. We already have challenges with migrations and upgrades, why add the distribution on top of that?

Instead, I would like to see some support for starter kits within Drupal core. Instead of distributions, you would install Drupal from a starter kit which would point to modules and contain configuration. Once installed, it would be as if the site was installed manually. I believe a lot of such solutions are also possible outside Drupal core (using drush, for instance) but it would be nice to have some sort of official interface within the core.

What else?

I know that all of the things I mentioned are possible in part or have challenges that involve tradeoffs. It’s not easy to figure out which tradeoffs we should make considering that Drupal’s user base is massive. For example, what I wrote about today are my wishlist items for Drupal. They may be something completely different for you and that’s okay. I believe the above are already aligned with the vision set for Drupal by Dries and the core team (ambitious experiences, editor-first, site-builder focused, etc). With that as the North Star, we should be able to find a way forward.

That is it for now. I can dream more about the removal of features (such as multisite) but that’s for some other day. Let me know what things you would like to see in Drupal.

Apr 29 2021
Apr 29

The configuration API is one of the major areas of progress made in Drupal 8. It addresses many challenges of managing a site across environments for Drupal 7 and before. It’s not perfect. After all, it’s just version 1 and there is work going on in CMI 2 to fix the problems in the current version. That is not the subject of this blog post, however. In this post, I want to talk about one of the lesser understood features of configuration management: overriding.

Most site builders and developers interact with the Drupal configuration API with “drush config-export” and “drush config-import”. Except for a minor exception, Drupal configuration is an all-or-nothing deal, i.e., you apply the configuration as a whole or not at all. There are modules like config_ignore and config_split to work around all these limitations. These modules allow ignoring parts of configuration or splitting and combining configuration from different locations. Further, Drupal allows overriding specific configuration through settings.php. A combination of all of these makes the Drupal configuration workable for most complex site-building needs.

The Configuration API

The configuration API provides ways to support all of the different scenarios described above. There are very simple constructs that are comparable to Drupal 7’s variable_set and variable_get functions. If you want to write a simple module that needs access to configuration, the documentation is enough to work out all of the details for you. Yet, there are some lesser understood parts of how the configuration handles cases such as overriding and other edge cases. I have seen this often in interviewing several people and even though it is well documented, its lack of visibility explains why people are not aware.

As I said before, I will mainly talk about the overriding system here. You are welcome to read all about the configuration API from the documentation. Specific areas I would recommend reading about are:

The configuration API needs to handle overriding specifically because they could affect exported configuration. If you are overriding configuration in the settings.php file, and if the config system didn’t know that, those values would be exported to the configuration file. This is not what you want. If your intention was to export it, then there was no reason to set it in the settings.php file. That is why the configuration API needs a mechanism to know about this.

Overriding configuration

The configuration API can handle these overridden values separately and also make them available to your code. This is why if you are exporting configuration after setting the values in settings.php, the overridden values won’t be present in the exported YML files. As a site builder, you won’t have to worry about this. But if you are a module developer, it helps to understand how to differentiate between these values.

Before I talk about the code, let’s consider the scenarios why you would need this. As a module developer, you might use the configuration in different ways and for each, you may need either the overridden data or the non-overridden (original) data.

  • For using the configured value in your logic, you would want the overridden data. Since you are using the value in your logic, you want to respect Drupal’s configuration system of overriding configuration.
  • For showing the value in a form, you might want to show the original data. You can choose to show overridden data but Drupal core shows the original data. There is an issue open to change this. Right now, there is a patch to indicate that the data is overridden and changes won’t take effect on the current environment.
  • While saving the values to the configuration, it will always be the original data. As a module developer, you cannot affect the overridden value through the configuration API. In fact, to save the configuration, you would need to call getEditable and that will always return the original data. When you set the new value and save it, you will change the value in the configuration storage. Yet, the override from settings.php will take precedence.

Accessing overridden values

If you have built modules, you might already be aware that you can use a simple get call on the config service to read a value from the configuration (see example). This will return an immutable object which is only useful for reading. To save it, however, you would need to go through the config factory’s getEditable method (example). This will return an object where you can set the value and save it.

While it may seem obvious that this is the only difference between “get” and “getEditable” methods, there is a subtler difference. The “get” method returns the overridden data whereas the “getEditable” method returns the original data. This means, there is a chance that both of these methods might return different values. As a module developer, it is important to understand this difference.

What if you wanted to get an immutable object but with original data? There’s a method for that: getOriginal (see example). Most modules won’t need to worry about the original data in the configuration storage except when saving. For that reason, it is not common to see this method in use. Even if a module were to indicate the differences in original and overridden configuration, it can use getEditable in most cases.

The difference between “get” and “getEditable” has been the trickiest interview question I have ever asked. Out of hundreds of interviews, I have only occasionally seen someone answer this. I hope this post helps you understand the difference and why the subtlety is important to understand.

Apr 28 2021
Apr 28

open waters podcast logo

Open Waters: Season 2, Episode 1 

Welcome to season two of Mediacurrent's Open Waters podcast! In this episode, we welcome Sheree and John G from our creative team. If you are a marketer, designer, or tech lead in the higher ed space, this episode is for you.

Episode Transcript 

Susan Cooper: Welcome to season two of Mediacurrent's Open Waters podcast! Mario Hernandez and Mark Shropshire will be coming to you each month to explore the intersection of open source technology and digital marketing. In today's episode, we'll be speaking with Sheree Hill, Creative Director at Mediacurrent, and John G, Digital Designer at Mediacurrent. Both have been doing extensive work in higher education - building design systems, addressing pain points of scale and velocity, and bringing brand stories to life.


Susan Cooper: We will explore some of the challenges facing marketers and designers in higher ed, touch on learning modalities, and how they function in web and marketing teams, as well as some quick and easy tips to help sharpen your school's brand strategy and maximize some production workflows. If you are a marketer, designer, or tech lead for higher ed, this episode is for you.

Susan Cooper: Glad to have you here. Can you tell us about yourself? What are your roles?

Sheree Hill: I'm Sheree Hill and I am the Creative Director here at Mediacurrent. For those of you who might not be familiar with what creative directors do... We work with awesome designers like John and some of our UX and UI designers to help bring creative visions to life. We help to establish colors and themes and really design brand experiences that are memorable and connect to audiences.

John G: I'm a Digital Designer here at Mediacurrent. I work directly with Sheree to produce branded elements, both in house and for clients.

Challenges in Higher Ed Web Design 

Mario Hernandez: Great. Well, thanks for being here, both of you, we really enjoy and appreciate you taking the time to join us. The first question that I have, I know there's always challenges when it comes to design or working on that project, but can you give us a little bit of information about some of the challenges that our client's face, especially higher education clients, when it comes to design?

Sheree Hill: Right now clients in higher ed are really facing challenges when it comes to pivoting from what's happened with COVID and building coursework that connects with students online. There are different audiences in higher ed and different challenges with those audiences. For example, for the content authors or for the marketer, there are certain challenges that they have in producing content, as well as reaching leads and reaching students versus a faculty member who might be wanting to share some of the knowledge that they're building and to find the best students, their programming. Some of the other challenges that are faced are really looking at creating consistent experiences across different channels. And that's something that John and I have been able to work with on a few different clients. 

Sheree Hill: John, do you want to talk a little bit about how the design debt is managed for schools?

John G: Yeah, absolutely. So design debt is a pretty big problem with a lot of education facilities starting from the top all the way to the bottom. Everybody needs different branded content, you know, emails, papers, that sort of thing, and trying to keep everything consistent so that you've got a brand that everybody recognizes and understands is pivotal.

Sheree Hill: And then when you think about producing content, this is something that everyone in digital, every brand faces today, and that's content production. Back in the day schools or universities or different brands would have a designer on staff and they would produce an annual report or there would be flyers that would be produced. That's not how it is today. Today, the cadence is that on social media, there are daily postings on different websites. We really need to look at how schools can scale and how is work produced across teams? Because marketers aren't the only ones that are producing content. Brand ambassadors at schools, teachers, students, they're all producing content that helped the schools reach new prospects and help to build the school's reputation. So it's important that any brand has the tools that they need to be able to create consistent brand experiences across channels.

Branding Strategies

Mario Hernandez: As a follow-up, let me ask you, how does your team work on addressing these challenges that you just outlined?

John G: One of the first things that we do in order to establish that brand is we have brand workshops that inform all of our design decisions and asset production. And then we develop that into an entire brand guide that helps kind of, kind of reduce that design debt and keep everybody consistent. So they've all got that same page to follow.

Sheree Hill: When you think about the voice and the personality of your brand, every brand sounds different. When you think about Harvard, for instance, the institution is very traditional. It has a lot of legacy and a lot of history that it's rooted in and its mission and vision is going to be different than a modern art school like RISD (Rhode Island School of Design). It's important to understand what a voice sounds like. And we can explore that through the brand workshop that John just mentioned, and we do that through design thinking and what's great about design thinking is everyone has a voice. So because of COVID, as we mentioned earlier, we're able to do these virtually and we do virtual brand workshops in Mural, and everyone uses different sticky notes, just like if we were in a classroom doing it together and we can gather those findings and then distill it into the brand strategy.

Sheree Hill: And those guidelines define everything from how the logo looks to how the brand sounds to all of the different distinct brand elements. So the different designs, the actual grid, the typography, all the things that you see in different design elements are defined in the brand guide.

Creating Design Systems 

Susan Cooper: Awesome. So tell us a little bit more about designing for higher ed.

Sheree Hill: One of the things that's unique in service-based design is that we're creating a service and a system, right? So that's different from product design that reaches the consumer. Amazon, when you think about a business to consumer it's different challenges. In services, and we're looking at providing a service to schools, providing education as a service. But we also productize it and by creating digital products like component-based design. As we define the system and the design system and all of the elements we call it atomizing the design system, right? We're not really building so much on templates anymore. We're really creating those key elements that are used throughout the system. When you think about challenges like scale or velocity, and being able to produce that content quickly and have the teams produce the thought leadership and the content, we create the systems that allow the team members to do that. 

Sheree Hill: John, do you want to talk a little bit about the challenges that you've seen in producing and working with higher ed institutions?

John G: I think the two main challenges that I've seen are first off content migration. And so with educational systems, we've got hundreds of pages of content. We've got blogs, we've got books, eBooks, we've got all of these different classes and classwork. And along with that comes the second challenge, which is division of labor. And so in order to get all of that content migrated, we have to work directly with the school's team. And we also have to build out a team of internal people to kind of work up a system, to get all of that content moved in an orderly fashion. And so one of the things that really helps with that is component based design so that we can drag and drop. So that it's easy for, for everybody, not just developers, but people on their team to help us with that lift. That's great.

Collaboration Tools 

Mario Hernandez: You mentioned that nowadays there are a lot more people involved in the content creation process. What are some of the tools that can help marketing teams in their productivity?

John G: Cloud collaboration for starters, cloud collaboration is extremely important these days. So one of the things that we did for an online college is we developed these Google doc templates for their eBooks, for their internal communication, for their external communication, so that they have this kind of rigid structure based on their brand guidelines that everybody can modify, not just people with Adobe cloud software, but also people on the ground level.

Sheree Hill: And hand in hand with that, one of the things we think about, cause we have training here at Mediacurrent when we build Drupal systems, but we also create processes for cloud collaboration. For example, one of the things that we found here in our brand, our own brand evolution moving from one brand to another is that there is a level of effort when it comes to obtaining documents. A cool hack that John discovered is a methodology to update different brand elements to the new brand. And so we've captured those findings from what we've learned and we create recreated processes that we can share with marketing departments and with schools so that it's a lot faster and easier to update those documents. Historically it has taken hundreds of hours. It can take hundreds of hours to update on old brands, to new brands when there are different flyers and documents. And it's not just letterhead anymore. When you think about schools there's so much information and content that’s shared that has to be updated. We've worked to build those processes that are quick, easy, and efficient.

John G: And alongside that with cloud collaboration in mind, we have also found ourselves using Canva an awful lot. I mean, like I said, not everybody has access to Adobe cloud software and Canva really helps people keep digital graphics consistent. We've got graphics for email graphics for social media, we've got animated graphics. And if you use the brand guide to build out a brand, a kit in Canva, you can kind of establish these parameters that makes it a lot easier for people to follow and also helps reduce that design debt.

Sheree Hill: One of the things that we talk about here is does it pass the litmus test? How can you tell your content from another school's content? It's so important any time there is a brand moment like there's a moment that you are speaking or reaching out to a prospective student, that's called an impression you're making an impression of who you are as an institution and the value that you can add to their life. It's important that your brand stands apart and has those different elements of identification so that you're easily recognizable.

Branding with Purpose 

Susan Cooper: Many marketers and brands these days are placing higher importance on mission and values. Why is that important for higher ed and how do they apply that to a design system?

Sheree Hill: Absolutely. As a brand, any brand, your mission is your guiding light. It's why you get up in the morning. It's really why you do what you do and your mission will help to inform how you make decisions. There are so many different points of decisions for brands and organizations and team members. And the vision really helps us keep the story. The mission really helps us keep aligned in that and the vision is how you do it. When you think about what that looks like the vision is really how that would look in the future. So when we think about how that informs the design system, we think about how it feels, right? Because the design system really has a lot to do with emotion. 

Sheree Hill: For example, when we were working with Emory Goizueta Business School, their vision is really about preparing principal leaders and they're known for being rigorous. When we created the design system, we selected and created images that reflected passion and discipline, and collaboration, which are all characteristics that are representative of principal leadership. And we carry that throughout the design system. And then when we think about the different shapes, we used different angles that were pointed upwards that were inspirational and driving, and motivating. That really helps to tell the brand story without using words, it's an energy, it's an emotion of how you connect with the audience.

Mario Hernandez: You know, I had the pleasure of working on that project. And it was a very challenging project from a design and development point of view. But I, at the end of the day looking at the end product of the project, I really thank you for pushing us because that was something that really pushed our team and, you know, it was challenging, but at the end of the day, it just, it made us so much better. That project came out really nice. And I was very happy with the decisions that you made from a design point of view there. So how, how do schools build that brand story as a service organization? How is that brought to life?

Sheree Hill: Absolutely. That's a great question. What we do when we look at the brand story is we examine the different facets of the value system of the school. Schools all have a value system that helps you inform your brand strategy. We look at all of those different pieces and we build out a complete brand strategy and that brand strategy, we look at different personality values and those different personality values. 

Sheree Hill: We have a workshop where we place images with those different values and we create a mood board and that mood board is then shared with the team and we get feedback. And that's something that John was able to work with an online college on and really help create a unique design system for them that doesn't look like any other school that I've seen. John, do you want to talk a little bit about that process and what that looked like?

John G: Once we put the mood board together, we can start using their mission and vision to kind of inspire the visualization of developing design elements and bring that across the entire system. For example, right now we're working on a campaign for DrupalCon and we've got this system that's based entirely around open source and open source expansion. And so we're creating visuals that kind of follow along with that mission and expanding on the expansion element of it.

Sheree Hill: Some of the visuals that John selected have outer space and rocket ships, and really the idea of going where people haven't gone before because that's really what open source is, right? It's us collectively exploring and building new frontiers together. We're able to harness the excitement of that and just use these beautiful visuals of space that light the imagination to inform the design system for the event campaign. So that's everything from a virtual booth to different media types to ad placements, to email campaigns all of the different parts of the system.

Open Source Design 

Mario Hernandez: So Mediacurrent is pretty big. It sets up, you know, we set ourselves apart because we have a huge commitment to the open source community and giving back to the community. Are there any tools that your team has either put together or found that you would with the community that can help other organizations implement the systems that you have?

Sheree Hill: Well, yes, we do. In fact, from the project that we worked on together, we built out the Rain CMS component matrix template from Emory Goizueta together. So that's something that we have created into a tool that we've designed into a tool. We can share that with anyone that's listening to the podcast. And then the other piece is the brand strategy guide. We have that as a template as well. We'd be happy to share that with the community. [Author’s note: These resources are linked at the end of the post!]

Book Recs for Higher Ed Marketers 

Susan Cooper: I bet that'll be really useful for folks. So what's something that every marketer should read, watch or listen to. This is a question for both of you.

John G: Right now, one of the things that I'm really big into reading about is a book called What's Your Enneatype, which is an essential guide to the Enneagram. I've been reading an awful lot about personality typing and more importantly, how you can market to different kinds of personality types to really improve that follow-through. And I think that's something that's absolutely important for marketers is just learning as much as you can about personality types, learning how you can market to those people. There are so many different books and so many different methods of thought on each of those topics. It doesn't have to be Enneagrams. There's Myers-Briggs, there are all of the other different types, and none of it is an exact science, but it's something that'll put you on the right path.

Sheree Hill: It comes down to relationships, right? Sales and marketing are all about relationships. And it's about understanding who we are as people. And it's understanding how someone else thinks and really having empathy. I also read the Enneagram. It's something that I believe in, it's not just right for marketers to sell, but also to work in teams. It's something that John and I have worked on together, understanding who we are and, and how to work together, and how to motivate and collaborate. So it's great, not just for sales, but also for teamwork. 

Sheree Hill: The other piece that I would say to that, and that's something that we're doing as a team is the CXL coursework in digital psychology and persuasion. And what it is is it's a psychological framework to improve our different platforms like our websites. And it teaches us how to understand behavior as well and influence purchase patterns. So why that's important is because if we can understand behavior, then we can influence and we can help our clients meet their goals.

Susan Cooper: It's incremental, right? With behavior change. You can't have people completely change the way they go about their day or the way they approach something. It's, it's incremental. You can change one thing at a time to get them where you want them to go and not in a manipulative way, but in a way that is helping guide their experience.

Sheree Hill: Absolutely. Yeah. We call it nudging and we just about how can, how can we influence them? And, and that's really where that mission and vision comes to play as well. Because if we have a mission and a vision that is looking to change the world for good and looking to change people and help them grow, then that's incremental and we can help people reach the best version of who they are.

See you next time!

Susan Cooper: Well, thank you so much for joining us today. I'm excited to have you all on our first episode of the second season.

Mario Hernandez: That was a lot of great information guys. We look forward to making this available to our listeners.

Susan Cooper: You can find us at mediacurrent.com and subscribe on your favorite podcast app. If you liked this episode, share it with your friends and tag @ mediacurrent on Twitter.


Apr 28 2021
Apr 28

Just as I published yesterday’s article on the tech stack, I realized that I missed a few important things. I had said that the list was only a start, so I think it is fitting to continue it today. As such, today’s post won’t be as long as yesterday’s or even as long as my usual posts. I should also add a caveat that today’s post won’t make the list complete. With the industry how it is and the requirement of constantly learning, I don’t think such posts stand the test of time; not from a completeness perspective in any case.

Our target persona still remains the same as the last post. We are talking about a Drupal developer building sites and functionality for a complex Drupal website with rich content, workflows, editorial customizations, varying layouts, and more features typically found in a modern content-rich website. Since today’s post focuses on the fundamentals of working on the web, the skills may apply to more than a Drupal developer but we’ll focus on this persona for now.

These are also skills that are often hidden, aka non-functional requirements. It is very easy to forget about this (as was evidenced by my yesterday’s post) but this is probably the most important of any of the skills. Not understanding this sufficiently leads to significantly large problems. Fortunately, Drupal is a robust framework and system and is able to handle all such issues by default. It is still important to understand how to work along with Drupal.


Performance is a very interesting challenge for a large dynamic website. There are several layers to unravel here and the answer for poor performance could be at any of those layers. This means a developer needs to understand how the web works, how Drupal works, and how does Drupal attempt to optimize for performance.

It is shocking how many people are unable to clearly articulate how the Internet works. To me, the lack of clear articulation is a sign of gaps in understanding in the chain of all systems that make the Internet work. To begin with, understand what is the sequence of events that take place when someone visits a link. Understanding DNS is important too. I know no one really understands DNS fully but you don’t need that. Get familiar with the interactions that take place between the client and the various systems such as DNS. Similarly, get familiar with CDN’s and other caching techniques that you can use.

Scalability is a different problem than performance but still very important to understand. Understand what are load balancers and how do they decide to route traffic. Also, understand how can you configure an application to work in such an environment. For this, you also have to understand the concept of state. Fortunately, PHP is already designed to be stateless and has a natural aptitude for such scalability (and serverless paradigm).

On the application front, understand how JavaScript and other assets can impact the rendering of your page. How would you find out if the front-end code is a bottleneck and if it is, what do you do about it? Same for back-end code. Understand how would you utilize caching at multiple layers to deliver performance to the user. Figure out what scenarios are better served with a reverse proxy cache like Varnish or an application cache such as Redis or memcached.


Accessibility is not an afterthought. Unless you are willing to review each line of code later, start with accessibility in mind from the first day. Again, Drupal meets many of the accessibility standards when you use the themes that ship with Drupal. The framework also supports many of the constructs that make writing accessible interfaces easier. Drupal 7 onwards has committed to meeting WCAG 2.0 and ATAG 2.0. Read the Drupal documentation to know more about how you, as a module developer, can write accessible code.


Again, security is not an afterthought and many people who treat it as such have a fair share of horror stories. And just like before, Drupal provides constructs that make it very easy to write secure code. With Drupal 8 and the introduction of Twig, it became significantly harder for developers to write insecure code. However, it is important to understand what Drupal does for security, otherwise, you will be fighting against the core to make your code work.

Understand Drupal’s philosophy of content filtering of filtering on output, not input. Understand how to use PDO and DBAL to work with databases safely. Learn how to use the Xss helpers to write HTML output safely. Understand how you would use Drupal’s permissions and roles system to provide access control for your code.

Again, these are vast topics but I am only beginning to introduce them here. Do follow the links above to specific Drupal documentation pages to understand the topic better.

Apr 27 2021
Apr 27
[embedded content]

Don’t forget to subscribe to our YouTube channel to stay up-to-date.

File Management Series

Removing files from Drupal is more tricky than you might think. There has been another tutorial about this using the module File Delete.  It requires going through a cycle of minimum 6 hours.  By default, Drupal protects files from removal which are still being used and referenced in other content. Instead of directly deleting a file, the linked usages need to be cleared first, and the files marked as temporary, then finally the system will remove them during cleanup.

This is actually a good policy. However, sometimes it’s annoying to wait for a few hours before these files are being cleaned up. In particular, if we are sure these files are unused or orphaned, there is another module called Fancy File Delete, which solves this problem.

Fancy File Delete allows you to delete files straight away without having to wait.

However, great care must be taken when using this module, because it has a ‘force delete’ option. Use of this module should be restricted to experienced administrators.

Table of Contents

Getting Started

Before we begin, go download and install Fancy File Delete.

Using the following Drush commands:

composer require drupal/fancy_file_delete

NOTE: The module requires the Views Bulk Operations (VBO) module which will be downloaded when you run the above command.

Deleting Files

To follow a proper procedure to delete files, administrators should still go through the proper file handling process by removing them from the nodes and the media library first, even though these processes can be bypassed using this module.

After installing and enabling the modules, go to Admin >> Configuration >>  Content authoring >> Fancy File Delete. In the first tab ‘Info’, it shows a brief description on how to use the module.

Enter the ‘List’ tab, a list of all the files in the system can be found from here.  Select the file(s) to be deleted using the checkbox in front of each file, then select ‘Delete Files’ in the ‘Action’ option on the top of the page, then click the ‘Apply to selected items’ button.

Note that there is another option for Action, which is ‘FORCE Delete Files (No Turning Back!)’.  When a file cannot be deleted, try this option but handle with care.

Can’t See Action Drop-Down

If you can’t see the Action drop-down on the list page that means you’ll need to reconfigure the view.

1. Edit the List view by clicking on the pencil icon.

2. Once you’re editing the view, click on the “Views bulk operations” field.

3. Enable the actions by clicking “Select all”.

Then save the view and you should see the Action drop-down.

Delete Files manually by FID

As can be seen above, there is a File ID for each file.  Files can be deleted using this FID by entering them under the ‘Manual’ tab. Just enter the FIDs of the files to be deleted, one per line, and press the ‘Engage’ button.

Deleting Orphaned and Unmanaged Files

Additional options are available to delete orphaned and unmanaged files if the system detects them.

Deleting Files from the ‘Files’ or ‘Image’ Fields

Note that in the above procedure using ‘Fancy File Delete’ module, it is not a requirement to remove them from the nodes first:

  • It bypasses the default file delete procedure in Drupal, and therefore it should be handled with care.
  • Files deleted will also be removed from previous node revisions too.
  • Files deleted will also be removed from the list of files under Admin >> Content >> Files
  • Files deleted are permanently removed totally from the system, including the physical file in the server.
  • It does not require waiting for the minimum 6 hours requirement.

When the files are uploaded through the media module and deleted without first removing them from the nodes and the media library first, this ‘Fancy File Delete’ module still remove the files same as above, except the following:

  • Files deleted will still be removed both physically from the server and from the list of files under Admin >> Content >> Files, like above.
  • The file will not be shown in node because it is empty, but an empty entity will remain both in the node and in the media library.

Using Drush

If you use Drush, you can delete files straight away using the “drush entity:delete” command.

For example:

drush entity:delete file 1

This command will remove the file from the Files page and delete it from the file system and you won’t have to wait.


This module offers a more straightforward and efficient way to remove files from a Drupal site permanently. It is powerful and capable of bypassing the default file handling procedures in Drupal. But that also means bypassing the file protection mechanism of Drupal. It handles file deletion in an efficient manner which is an advantage, but it is also a disadvantage at the same time.

On a large site where there are more users and content authors. When deleting files are granted to more people, it is difficult to guarantee that everybody is careful enough to understand the underlying structure and relationships between files and content. There is a higher risk of accidental deletion of files. In such situations, a better protection mechanism might be necessary.

On a small site or in a small team where content is easier to manage and control, efficiency might be preferred.

Apr 27 2021
Apr 27

The title of this post is not really accurate, but I can’t think of another way to say it. This post is related to my earlier one on what a Drupal Developer does day-to-day. Here, I will talk about some of the skills required of a Drupal developer. I am not aiming for completeness in this post (that’s a goal for another time) but I will try to list all skills required to build a regular Drupal site, deploy it, and keep it running. Some of these skills are foundational whereas others may be only needed for specific requirements. Moreover, not all skills are required at a high expertise level. For some roles, even awareness is enough.

This post would be useless without a target persona. Different organizations have different needs and what works at one organization may not work at another at all. Similarly, different roles within an organization have different needs. For example, at Axelerant, we do not have a dedicated site-builder role but this is something that is expected of a Drupal Developer. Such an arrangement may not work at all for your organization nor can I say this arrangement will work forever for Axelereant. In fact, it is even weird to use the word “forever” here.

The target persona for this post is a Drupal Developer building sites and functionality for a complex Drupal website with rich content, workflows, editorial customizations, varying layouts, and more features typically found in a modern content-rich website. Since this is Drupal we are talking about, the above definition is actually quite broad. It includes a web presence for organizations from publishing, healthcare, higher-education, finance, government, and more. With that settled, let’s look at the skills.


A Drupal developer would need to have the following skills related to site-building. Even if a developer does not build sites, there is a good chance they would be interfacing with these aspects from code. Hence, most of these are foundational.

  • Content modelling: Understand what makes a good content structure for a site. You should be able to determine if the content structure you are building is the relevant one for the requirements.
  • Content moderation: Most sites need this. I have seen this being used even on simple sites when there is more than one type of user. Understanding how the moderation workflow works and how it ties with the entity-field structure along with its revisions is important.
  • Multiple languages: It is important to understand how Drupal implements multilingual functionality at both interface and content (translation) level. Depending on the requirements, certain aspects of how translated content is stored in fields could be very relevant. At a basic level, you should also be aware of how Drupal determines the language when it renders a page or response.
  • Configuration Management: While this may seem more to do with developers, it is important to understand this from a site building perspective. You need to understand how the content types you create are stored in configuration and how is it different from how, for example, site information is stored. This means you need to understand configuration entities and simple configuration. You also need to understand how configuration can be changed depending on the environment and how it could be overridden.
  • Common solutions like views and webforms: Before you set about developing for some functionality, you have to make sure if there is a solution out there already. You also need to know how to pick modules for your problems.


I don’t think this section needs any explanation as the entire post is about this. So let’s jump in.

  • PHP: This might seem like a no-brainer. Drupal is written in PHP so it is a good idea to be very comfortable with PHP. Understand object-oriented programming, how Drupal uses different constructs such as traits. Also, understand patterns such as dependency injection and observer pattern (hooks and event subscribers are based on this). Then, keep up with what’s new in PHP, if possible, and use it.
  • Composer: Arguably, this is a part of site-building as well but there is a good reason to keep it here. Apart from using composer to download modules, understand how it helps in writing the autoloader. Also, understand how composer works to select a module or a package and what are the reasons it might fail. Most of this comes with experience.
  • Caching: This is probably the most important part to understand about Drupal. Caching is deeply ingrained at multiple levels in Drupal and it is important to understand how it works. Almost all your code will need to interact with it even if you aren’t planning to cache your responses.
  • Other Drupal API’s: There are some common API’s you should be familiar with; for example, Form API and Entity API come to mind. But also be aware of other API such as Batch, Queue, plugins, Field, TypedData, etc. You should know where to look when you need it for a problem.
  • Automated testing: The Drupal core has a very vast collection of test cases and that means you may only have to write functional test cases for your site. You should understand the different tools that you can use to write them.


You have to understand where your site is going to live to build it well. We don’t live in that age where you would write code and throw it over a wall to the ops team for them to deploy it. You may not be deploying it but you have to understand the concepts.

  • Servers: Understand how servers work. You don’t need to know enough to configure one securely (unless that’s your job) but you should know enough to understand the terms. For example, you should know what are the common web servers and how they may be configured to run PHP. Also, understand what kind of configuration Drupal needs to run.
  • High Availability: Given Drupal’s market, there is a good chance that the site you are building will need to run in a highly available environment. Understand what it means and what that implies for your Drupal site. Most of these issues may be resolved for you if you are using one of the PaaS providers but if you are building your own server(s), you should understand how to configure Drupal to run on multiple servers. Even if you are using PaaS, you should still understand how running on multiple servers could affect how you write code, e.g., how you work with temporary files.
  • CI/CD: Continuous Integration is very common today and it is important you understand it to be a productive developer. There are dozens of solutions to choose from and most have some kind of a free offering. Pick one and try it out.

And more…

Like I said before, I am not aiming for completeness here but only in making a start. Please let me know if I have missed something obvious. Given the nature of these posts, I can only spend 1-2 hours planning and writing these, so there is a very good chance I have missed something. Let me know.

Apr 26 2021
Apr 26

Now on Drupal 9, the community isn’t slowing down. This month, we continue our interview with Angie Byron, a.k.a Webchick, a Drupal Core committer and product manager, Drupal Association Board Member, author, speaker, mentor, and Mom, and so much more. Currently, she works at Aquia for the Drupal acceleration team, where her primary role is […]

The post Community Corner: Interview with Angie Byron, Part Two appeared first on php[architect].

Apr 26 2021
Apr 26

Over the years, I have significantly lesser time for development and an increasing need to move around. After dealing with back-pain due to the weight of my Dell laptop while travelling for conferences, I bought a 15″ MacBook Pro. More recently, with the issues with Docker performance on Mac, I have been thinking of getting a Linux box. I was further motivated when I bought an iPad last year and wanted to use that for development. Now, with my old MacBook Pro failing because of keyboard and hard disk, I have a new MBP with the M1 chip and just 8 GB RAM. I am more and more interested in making remote development work efficiently for me.

It is not hard to set up a remote machine for development in itself. The problem I want to solve is to make it easy to spin up machines, maintain them, and tear them down. I also want to make it easy to set up a project along with the necessary tooling to get it running as quickly as possible. For now, the only problem I am solving is to set up the tooling quickly. I am calling this project Yakht (after yacht, as I wanted a sea-related metaphor).

Current workflow

While it’s far from the level of automation I am thinking of, it’s not too bad. I was able to set up a machine for use within a few minutes. This is what the process looked like:

  1. Create a 1 GB instance on DigitalOcean in a nearby region (for minimum latency).
  2. Add a wildcard DNS record for one of my domain names so that I can access my projects on ..
  3. Set the domain name and IP address in my Ansible playbook’s variable files and inventories.
  4. Run the Ansible playbook.

These steps had a machine ready for me with all tools required for Drupal development using Docker (Lando in my case). The Ansible playbook installs a bunch of utilities and customizations along with the required software like PHP, Docker, composer, Lando, etc. Only PHP CLI is installed because all development happens within Docker anyway. It also configures Lando for remote serving and sets the base domain to the domain I have configured, which means I can access the URLs generated by Lando (thanks to the wildcard DNS). With the Drupal-specific tooling we have written (some of which I have written before), setting up a new project is fairly quick.

A lot of these tools are somewhat specific to me (such as fish-shell and starship). I need to make it customizable so that someone else using it can pick a different profile. That’s a problem for another day.

Current trials

I have been using this machine for a long time now which is not how I intend for this to be. I am trying out a few tools and customizations before putting them in the Ansible playbook. Most notably, I am trying out cdr and using it as an online IDE which is very similar to vscode. It took a little effort to serve it via Caddy, it works well most of the time. It times out frequently but I think this is because this instance only has 1 GB of RAM. When it times out, the connection breaks and you need to reload which can get frustrating. Fortunately, this happens frequently for a while and then it works fine for long periods of time. In any case, I doubt if this will happen on an instance with a reasonable amount of RAM.

Screenshot of cdr running in Chrome

Screenshot of cdr running in Chrome

I know that VS Code has good support for remote development over SSH but I also want to be able to use the IDE over iPad and a browser-based IDE solves that. I am also considering trying out Theia and Projector but that’s for another day.

It’s also missing a few things I want in my development machines such as my dotfiles and configuration for some of the tools (such as custom fish commands). For now, all of this is set up manually. Of course, my intention is to automate all of these steps (even DNS).

Current problems

The general problem with these kinds of tools is to maintain a balance between flexibility and ease of use. By ease, I mean not having to configure the tool endlessly and frequently to make it do what you want. But that’s exactly what flexibility needs. For now, I am not trying hard to maintain flexibility. Once I have something that works with reasonable customization, I will figure out how to make it much more customizable.

Another problem is accessing remote servers from this machine. Right now, I am using SSH agent forwarding to be able to access remote servers from my development instance without having the SSH key there (and it works). But this doesn’t work if I am using the terminal in cdr. I am still looking for a solution to this problem that doesn’t involve me copying my keys over to the development instance. One idea is, if forwarding is not possible at all, to generate new keys for every instance and give you public keys that you can paste in services you want. This is secure compared to copying the private key but definitely a hurdle to get over.

I am excited by this project and hope to have more updates over time. For now, I hope you find the Ansible playbook useful. Also, I am looking for ideas and suggestions in solving this general problem of remote development. Please let me know via comments or social media what you think.

Apr 25 2021
Apr 25

I thought I was done with the series of posts on object-oriented programming after my last one. Of course, there is a lot we can write about object-oriented programming and Drupal, but that post covers everything noteworthy from the example. There is a way which is old-school but works as it should and another which looks modern but comes with problems. Is there a middle-ground? Tim Plunkett responded on Twitter saying there is.

There's a third way! See https://t.co/cFizL60Loy and https://t.co/so2syXyXZS

— timplunkett (@timplunkett) April 24, 2021

At the end of the last post, I mentioned that the problem is not with object-oriented programming. It is with using something for the sake of using it. If you understand something and use it judiciously, that is more likely to result in a robust solution (also maintainable). Let’s look at the approach mentioned in the tweet in detail.

The fundamental difference

The problem with the version with objects in the last post was not because it used objects. It was because it overrode the entry point of the form callback to change it. Using classes has its advantages, most notably that we can use dependency injection to get our dependencies. For more complex alterations, it is also useful to encapsulate the code in a single class. But the approach with the entry point made the solution unworkable.

On the other hand, the form_alter hook is actually designed for this purpose. Yes, it cannot be used within classes and you have to dump it in a module file along with all the other functions. But it works, and that’s more important. There is no alternative designed for this purpose. So, in a way, the fundamental difference is that this method works whereas the other doesn’t. It doesn’t matter that we can’t use nice things like dependency injection here if it doesn’t even work.

Bringing them together

The two worlds are not so disjoint; PHP handles both brilliantly, after all. If you want to encapsulate your code in objects, the straightforward solution is to write your code in a class and instantiate it from your form_alter hook. Yes, you still have the hook but it is only a couple of lines long at most and all your logic is neatly handled in a class where it is easy to read and test. The class might look something like this.

namespace Drupal\mymodule;
use Drupal\Core\Form\FormStateInterface;
class MySiteInfoFormAlter {
  public function alterForm(array &amp;$form, FormStateInterface $form_state, $form_id) {
    // Add siteapikey text box to site information group.
    $form['new_element'] = [ '#type' =&gt; 'textfield',
      // ... more attributes

And you can simply call it from your hook like so:

function mymodule_form_system_site_information_settings_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $alter = new \Drupal\mymodule\MySiteInfoFormAlter();
  $alter-&gt;alterForm($form, $form_state, $form_id);

You can save the object instantiation if you make it static but let’s not go there (you lose all advantages of using objects if you do that).

Dependency Injection by Drupal

This is already looking better (and you don’t even need route subscribers). But let’s take it a step further to bring in dependency injection.

We can certainly pass in the dependencies we want from our hook when we create the object, but why not let Drupal do all that work? We have the class resolver service in Drupal that helps us create objects with dependencies. The class needs to implement ContainerInjectionInterface but that is a very common pattern in Drupal code. With such a class, you only need to create the object instance using the class resolver service to build it with dependencies.

function mymodule_form_system_site_information_settings_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
    -&gt;alterForm($form, $form_state, $form_id);

For better examples, look at the links Tim Plunkett mentioned in the tweet: the hook for form_alter and the method.

I hope you found the example useful and a workable middle-ground. Do let me know what you think.

Apr 24 2021
Apr 24

Update: Read the follow-up to this post where I discuss a mixed approach combining both of the approaches here.

I previously wrote about how the object-oriented style of programming can be seen as a solution to all programming problems. There is a saying: if all you have is a hammer, everything looks like a nail. It is not a stretch to say that object-oriented programming is the hammer in this adage. That post was quite abstract and today I want to share a more specific example of what I mean. More specifically, I’ll talk about how using “objects” to alter forms without thinking it through can cause harm.

But first some context: this example comes from my reviews every week of code submitted as part of our interview test. This has happened frequently enough that I think that this is actually a recommendation somewhere. Even if it is the case of people copying each other’s work, it certainly is evidence that this has not been thought out. In fact, this makes for a good interview question: where would this method fail? I am going to answer that in this post.

The traditional method

Let’s look at the traditional method first. Drupal provides hooks to intercept certain actions and events. For example, Drupal might fire hooks in two situations: in response to events like saving a node, or to collect information about something (e.g. hook_help). You will find a lot more examples about the latter and that is what we are going to talk about today.

Drupal fires a few different hooks when a form is built. Specifically, it gives the opportunity to all the enabled modules to alter the form in any way. It does this via a hook_form_alter hook and a specifically named hook_form_FORM_ID_alter. So, for example, to alter a system site information form, either of the functions below would work:

function mymodule_form_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  if ($form == "system_site_information_settings") {
    $form['new_element'] = [ /* attributes */ ];
// ... OR ...
function mymodule_form_system_site_information_settings_alter(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['new_element'] = [ /* attributes */ ];

Adding elements or altering the form elements in any way is a simple affair. Just edit the $form array as you want and you can see the changes (with cache clear, of course). This is the old-school method and it still works as of Drupal 9.

The OOPS approach

More often than not, I see the form being altered in a much more involved way. Broadly, this is how it looks:

  1. Create a form using the new object-oriented way but extending from Drupal\system\Form\SiteInformationForm instead of the regular FormBase.
  2. Define an event subscriber that will alter the route using the alterRoutes method.
  3. In the event subscriber, override the form callback to your new form.

This gist contains the entire relevant portion of code.

After doing all this, you might expect that the code should at least work as expected. Many people do. But if you have been paying close attention, you might see the problem. If not, think about what would happen if two modules attempt to alter the same form this way. Only one of them would win out.

If there are two modules altering the same route, the last one to run will win and that module’s form changes will be used, The form controllers from the previous modules will never be executed. You could extend the first module’s form controller in the second module (so that changes from both modules take effect) but that is not reasonable to expect in the real world with varied combinations of modules.

So, we shouldn’t use objects?

I am not saying that. I am saying that we should think how we are applying any programming paradigm to build a solution and where it might fail. In our example, if Drupal supported an object-oriented version of form alters, that would have been safe to use (there is an open issue about this.) In fact, there is discussion to use Symfony forms and also some attempts in contrib space. Until one of those solutions get implemented, the form_alter hook is the best way to alter forms. And there is a good chance that such hooks get replaced in time. After all, the event-based hooks did get replaced by events in most cases.

For now, and always, use the solution that fits your needs. Using objects or using functional programming doesn’t necessarily make a program better. It is using our skills and our judgement that makes a program better.

Update: Read the follow-up to this post where I discuss a mixed approach combining both of the approaches here.

Apr 23 2021
Apr 23

I have been contributing to Drupal in a few different ways for a few years now. I started off by participating in meetups, and then contributing to Drupal core whenever I found time. Eventually, I was even contributing full-time courtesy of Axelerant, my employer. At the same time, I started participating in events outside my city and eventually in other countries as well. I was speaking at most of the events I attended and mentored at sprints in many of these events. I have written about this in detail before in different posts about my Drupal story and a recent update to that.

It was only with the support my wonderful family and also from Axelerant in the early years that enabled me to contribute in this way. As my responsibilities grew, I had to find focus in where to contribute. My kids were growing up and I wanted to spend a lot more time with them. At the same time, I started picking up managerial responsibilities at Axelerant and was responsible not just for my work, but for a team. I was approaching a burnout quickly and something had to go. It was at this time I rethought on how to sustainably contribute to open-source.

Long story, short…

The story is not interesting. Honestly, I barely remember those years myself. I know they were essential for my growth and they came at a significant price. But we know that nothing worth doing is easy. As a mentor to a team and even bordering on a reporting manager, I had the privilege to multiply my efforts through them. I am proud to see how many of them have built their own profiles in the community and continue to do so.

My recommendation to my team and myself is now to stop thinking of contributing as “contribution” but as a part of our work. The word “contribution” implies giving something externally. People are hesitant to make this external action when they already are very busy with bugs, deliveries, and meetings. We all have a limited working area in mind to think about the code and all the complexity. Thinking about something external is very difficult in these circumstances.

Don’t hack core

One reason this feels so external to us is because of how we treat Drupal core and contrib. We drill in the notion in newcomers that we should never hack core. While there is a good reason for this but it results in the perception that the core (and contrib) cannot be touched. It is seen as something external and woe befall anyone who dareth touch that code. It is no surprise that many people are intimidate by the thought of contributing to the Drupal core.

My workflow

The trick is to not think of it as external. I use the word “upstream” instead of contrib projects when talking about Drupal core or modules. I find that some people think of “upstream” as a little closer to themselves than “community contribution”. Thinking about it this way makes the code more real, not something which is a black box that can’t be touched. We realize that this code was written by another team consisting of people who are humans just like us. We realize that they could have made mistakes just the way we do. And we realize that we can talk to them and fix those mistakes. It is no different than working in a large team.

Yes, this means that we don’t have people who are dedicating time to contribute. That is a worthy goal for another day. I am happy with this small victory of getting people familiar with the issue queues and the contribution process on drupal.org. I have seen these small acts bubble up to create contrib modules for use in client work (where relevant). Eventually, I see them having no resistance with the idea of contribution sprints because the most difficult part of the sprint is now easy: the process. They are familiar with the issue queue and how to work with patches (now merge requests); if it is a sprint, the only new thing they are doing is coding, which is not new to them at all.

I realize that this is not a replacement to the idea of a full-time contributor. We need someone who is dedicated to an initiative or a system. These contributors are needed to support the  people who will occasionally come in to fix a bug. But we need to enable everybody to treat the core as just another piece of code across the fence and teach them how to open the gate when necessary.


About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web