May 17 2019
May 17

Although web accessibility begins on a foundation built by content strategists, designers, and engineers, the buck does not stop there (or at site launch). Content marketers play a huge role in maintaining web accessibility standards as they publish new content over time.

“Web accessibility means that people with disabilities can perceive, understand, navigate, and interact with the Web, and that they can contribute to the Web.” - W3

Why Accessibility Standards are Important to Marketers

Web accessibility standards are often thought to assist audiences who are affected by common disabilities like low vision/blindness, deafness, or limited dexterity. In addition to these audiences, web accessibility also benefits those with a temporary or situational disability. This could include someone who is nursing an injury, someone who is working from a coffee shop with slow wifi, or someone who is in a public space and doesn’t want to become a nuisance to others by playing audio out loud.

Accessibility relies on empathy and understanding of a wide range of user experiences. People perceive your content through different senses depending on their own needs and preferences. If someone isn’t physically seeing the blog post you wrote or can’t hear the audio of the podcast you published, that doesn’t mean you as a marketer don’t care about providing that information to that audience, it just means you need to adapt in the way you are delivering that information to that audience.

10 Tips for Publishing Accessible Content

These tips have been curated and compiled from a handful of different resources including the WCAG standards set forth by W3C, and our team of accessibility gurus at Palantir. All of the informing resources are linked in a handy list at the end of this post. 

1. Consider the type of content and provide meaningful text alternatives.

Text alternatives should help your audience understand the content and context of each image, video, or audio file. It also makes that information accessible to technology that cannot see or hear your content, like search engines (which translates to better SEO).

Icons to show image, audio, video

Types of text alternatives you can provide:

  • Images - Provide alternative text.
  • Audio - Provide transcripts.
  • Video - Provide captions and video descriptions in action.

This tip affects those situational use cases mentioned above as well. Think about the last time you sent out an email newsletter. If someone has images turned off on their email to preserve cellular data, you want to make sure your email still makes sense. Providing a text alternative means your reader still has all of the context they need to understand your email, even without that image.

2. Write proper alt text.

Alternative text or alt text is a brief text description that can be attributed to the HTML tag for an image on a web page. Alt text enables users who cannot see the images on a page to better understand your content. Screen readers and other assistive technology can’t interpret the meaning of an image without alt text.

With the addition of required alternative text, Drupal 8 has made it easier to build accessibility into your publishing workflow. However, content creators still need to be able to write effective alt text. Below I’ve listed a handful of things to consider when writing alt text for your content.

  • Be as descriptive and accurate as possible. Provide context. Especially if your image is serving a specific function, people who don’t see the image should have the same understanding as if they had.
  • If you’re sharing a chart or other data visualization, include that data in the alt text so people have all of the important information.
  • Avoid using “image of,” “picture of,” or something similar. It’s already assumed that the alt text is referencing an image, and you are losing precious character space (most screen readers cut off alt text at around 125 characters). The caveat to this is if you are describing a work of art, like a painting or illustration.
  • No spammy keyword stuffing. Alt text does help with SEO, but that’s not it’s primary purpose, so don’t abuse it. Find that happy medium between including all of the vital information and also including maybe one or two of those keywords you’re trying to target.
Illustration of red car with flames shooting out of the back, flying over line of cars on sunny roadway.Example of good alt text: “Red car in the sky.”
Example of better alt text: “Illustration of red car with flames shooting out of the back, flying over line of cars on sunny roadway.”

3. Establish a hierarchy.

Upside down pyramid split into three sections labeled high importance, medium importance, low importance

Accessibility is more than just making everything on a page available as text. It also affects the way you structure your content, and how you guide your users through a page. When drafting content, put the most important information first. Group similar content, and clearly separate different topics with headings. You want to make sure your ideas are organized in a logical way to improve scannability and encourage better understanding amongst your readers.

4. Use headings, lists, sections, and other structural elements to support your content hierarchy.

Users should be able to quickly assess what information is on a page and how it is organized. Using headings, subheadings and other structural elements helps establish hierarchy and makes web pages easily understandable by both the human eye and a screen reader. Also, when possible, opt for using lists over tables. Tables are ultimately more difficult for screen reader users to navigate.

If you’re curious to see how structured your content is, scan the URL using WAVE, an accessibility tool that allows you to see an outline of the structural elements on any web page. Using WAVE can help you better visualize how someone who is using assistive technologies might be viewing your page.

5. Write a descriptive title for every page.

This one is pretty straight forward. Users should be able to quickly assess the purpose of each page. Screen readers announce the page title when they load a web page, so writing a descriptive title helps those users make more informed page selections.

Page titles impact:

  • Users with low vision who need to be able to easily distinguish between pages
  • Users with cognitive disabilities, limited short-term memory, and reading disabilities.

6. Be intentional with your link text.

Write link text that makes each link’s purpose clear to the user. Links should provide info on where you will end up or what will happen if you click on that link. If someone is using a screen reader to tab through 3 links on a page that all read “click here,” that doesn’t really help them figure out what each link’s purpose is and ultimately decide which link they should click on.

Additional tips:

  • Any contextual information should directly precede links.
  • Don’t use urls as link text; they aren’t informative. A
  • void writing long paragraphs with multiple links. If you have multiple links to share on one topic, it’s better to write a short piece of text followed by a list of bulleted links.

EX: Use "Learn more about our new Federated Search application" not "Learn more".

7. Avoid using images of text in place of actual text.

The exact guideline set forth by W3 here is “Make it easier for users to see and hear content including separating foreground from background.” 

There are many reasons why this is a good practice that reach beyond accessibility implications. Using actual text helps with SEO, allows for on-page search ability for users, and creates the ability to highlight for copy/pasting. There are some exceptions that can be made if the image is essential to include (like a logo). Providing alt text also may be a solution for certain use cases.

8. Avoid idioms, jargon, abbreviations, and other nonliteral words.

The guideline set forth by W3 is to “make text content readable and understandable.” Accessibility aside, this is important for us marketers In the Drupal-world, because it’s really easy to include a plethora of jargon that your client audience might not be familiar with. So be accessible AND client-friendly, and if you have to use jargon or abbreviations, make sure you provide a definition of the word, link to the definition, or include an explanation of any abbreviations on first reference.

Think about it this way: if you are writing in terms people aren’t familiar with, how will they know to search for them? Plain language = better SEO.

9. Create clear content for your audience’s reading level.

For most Americans, the average reading level is a lower secondary education level. Even if you are marketing to a group of savvy individuals who are capable of understanding pretty complicated material, the truth is, most people are pressed for time and might become stressed if they have to read super complicated marketing materials. This is also important to keep in mind for people with cognitive disabilities, or reading disabilities, like dyslexia.

I know what you’re thinking, “but I am selling a complicated service.” If you need to include technical or complicated material to get your point across, then provide supplemental content such as an infographic or illustration, or a bulleted list of key points.

There are a number of tools online that you can use to determine the readability of your content, and WebAIM has a really great resource for guidelines on writing clearly.

10. Clearly label form input elements.

If you are in content marketing, chances are you have built a form or two in your time. No matter whether you’re creating those in Drupal or an external tool like Hubspot, you want to make sure you are labeling form fields clearly so that the user can understand how to complete the form. For example, expected data formats (such as day, month, year) are helpful. Also, required fields should be clearly marked. This is important for accessibility, but also then you as a marketer end up with better data.

Helpful Resources

Here are a few guides I've found useful in the quest to publish accessible content:

Accessibility Tools

May 17 2019
May 17

In our booth during DrupalCon Seattle this year, we had the pleasure of speaking with people in the Drupal community about our new Support & Maintenance offering. The response we heard most often was, “Doesn’t Lullabot already do support and maintenance?” The short answer is yes. We have supported and continue to support our clients and maintain their websites and applications, but never before have we intentionally started working with a new client on a strict support and maintenance basis, until now.

Over the past eight years, our primary focus has been engaging with clients as early as possible, often beginning with Strategy and Design and then implementing that vision with our Development team. We would perform or augment large capital web projects and then roll off when the project moved into a day-to-day operations mode, handing it back to internal resources or even sometimes to other Drupal shops for long-term maintenance.

Why Support & Maintenance

For the past couple of years we’ve seen:

  • Increasing requests for smaller engagements,
  • Drupal 7 and 8 coming to end-of-life, and
  • Clients wanting us to remain in a limited capacity to support their team long after the site is “done.” 

To meet these needs, we’ve assembled a team of experienced developers with a good mix of project management, front-end, and back-end expertise, as well as a strong emphasis on communication. Some of us have even taught college classes. We’ve chosen team members who are cross-functional; while they are experts in some areas they possess a strong comprehension of all areas related to enterprise development, deployment, and best practices. Surprisingly, Support & Maintenance has done a lot more mentorship than initially anticipated. (We love to teach and share what we know.) As with all of our clients, those working with our Support & Maintenance department have access to our hive mind, which includes the leads of multiple Drupal core initiatives, maintainers of popular modules, conference speakers, and authors of numerous Drupal publications.

Tools and Process

Each project and each client is different. For that reason, we endeavor to be flexible. Some clients may already be using their own instance of Jira for ticketing, some may have no ticketing system at all. We endeavor to learn our client’s existing processes before recommending changes. If there’s a process issue that’s preventing us from being effective, we’ll let you know and make suggestions for improvement. Some of our clients use Pantheon or Acquia, while others may deploy sites on AWS or their own internal infrastructure. Our Support & Maintenance team is aware of these differences and we pride ourselves on being adaptable and diverse in our areas of expertise. We’re able to adjust quickly to fit the needs of each individual client and project.

Next Steps

If your organization has worked with us in the past and wants to work with us again, or has always wanted to work with us but feared your project or budget was not enough to justify a full-time developer, please reach out to our team to see if Support & Maintenance might be a good alternative. 

David Burns


That special place where people, code, and business requirements meet is the place that I want to be.

May 17 2019
May 17

At DrupalCon Seattle this year, Mediacurrent was excited to unveil our latest distribution and Gatsby integration. Rain is a group of prepackaged, pre-configured components vetted by our development team and sourced from the open source community.

Our goal it to help web teams create, configure, and deploy websites faster. This tutorial will show you exactly how to get up and running end-to-end. You can also follow along with our tutorial videos

Step-by-step guide to get started with Rain, Gatsby, and Netlify 

  • Installing the Rain distribution
  • Enable JSON:API
  • Hosting integration
  • Setup Gatsby
  • Configure Netlify
  • Connect Drupal 8 to Netlify

Step 1 - Installing the Rain distribution

[embedded content]

There are many ways to spin up a new Drupal 8 instance. In this tutorial we will use Mediacurrent’s open source Drupal project template which is available for download on Bitbucket. This repository includes everything you will need to get up and running including VM, Guardr security integration, the Rain install profile and more.

First you will want to create a repository wherever you typically host your Git projects (i.e. Github, Bitbucket or Gitlab). Once you have that setup you can clone Mediacurrent’s repo and point the origin back to your Git repo.


git remote set-url origin [email protected]:mediacurrent/shortcode_project.git

Next you will want to initialize the project. You can do that by running the following commands with your local host name and IP.


composer install
composer drupal-scaffold
./scripts/hobson project:init example.mcdev

Finally, to build the project and run the install you can simply run “./scripts/” which runs composer install as well as the Drupal install. Note that the project README has more detailed instructions but this will give you an idea how to get up and running quickly.

Once you have completed your install you will want to push updates to your git origin.

Step 2 - Enable JSON:API

[embedded content]

In order to make our Drupal 8 site provide data to the Gatsby frontend we will enable the JSON:API module added to core in version 8.7. For now the Gatsby JSON:API source plugin is the most well-supported way to ingest content from Drupal but eventually a GraphQL module-based source plugin will replace the need for JSON:API.

Mediacurrent has a Packagist feature module that makes this process a little bit easier because it will also add some test content we need to get Gatsby running out of the box. Otherwise, you would have to manually create any paragraph being used in our Gatsby starter.

To add the Rain Gatsby feature simply run the following command:

composer require mediacurrent/rain_gatsby

After the Rain Gatsby feature is downloaded you will enable the feature which in turn enables JSON:API and creates 1 test page with paragraphs. When you have completed this step, be sure to export your configuration and push any file updates to origin.

Step 3 - Hosting integration

[embedded content]

Most Drupal web hosts (e.g Acquia, Pantheon, etc.) have their own git repository they use for deploying artifacts to the server. This includes all  the actual Drupal files that make up core, contributed modules and libraries. We don’t want our source git repository to store artifacts or conform to the folder layout required by the web host. Instead, we execute deploy commands to build the artifacts from Composer and commit them to the appropriate destination git repository. To make that process easier we have some additional configuration to add to our config.yml file that instructs how and where code should be deployed.

The key aspects to both the Acquia and Pantheon configuration is pointing the release repo to the appropriate git URL provided by your host, the name of the host and the release drupal root directory. Our examples use Acquia and Pantheon but also support generic git artifact repositories like AWS.

Acquia config:

project_repo: [email protected]
release_repo: [email protected]:mcABCProject.git
release_drupal_root: docroot
deploy_host: Acquia

Pantheon config:

project_repo: [email protected]
release_repo: ssh://
release_drupal_root: web
deploy_host: Pantheon

Additionally for Pantheon you will need to add a pantheon.yml file to the root directory with the following values:

api_version: 1
web_docroot: true
php_version: 7.1 (or latest PHP version supported)

This command also needs to be run in order to clean up the Pantheon git repo prior to our first deployment:

rm -r README.txt autoload.php core example.gitignore index.php modules profiles robots.txt sites themes update.php vendor web.config

Now we are ready to build and deploy for the first time. We do this with two commands, one to build the artifacts and one to push files to the release git repository.

Example (using Pantheon):

./scripts/hobson release:build Pantheon develop
./scripts/hobson release:deploy Pantheon develop -y

After you have deployed code to Acquia or Pantheon you should be able to run a clean install using either the sample Rain child install profile (mis_profile) or cloned profile you have created (see Rain README for more details).

Step 4 - Setup Gatsby

[embedded content]

To connect your Drupal instance to Gatsby, at a minimum you just need the Gatsby source plugin pointed to Drupal’s JSON:API endpoint. For those new to Gatsby, it can be a lot of work to map your components to Drupal content using GraphQL.

In order to make this whole process quicker and easier, Mediacurrent created a Gatsby starter (available at that does a lot of the initial component development for you. Our Gatsby starter includes React components with GraphQL that maps to the Paragraphs data incoming from the Rain install profile. Any time you change a Paragraph you will need to adjust your components and GraphQL but it’s much easier than building everything from scratch. The components also include basic markup, styles and in some cases Javascript to give developers something working right out of the box.

Spinning up the Gatsby + Rain starter is very simple, and uses the same syntax as other Gatsby starters. See the example below:

gatsby new my-rain-starter

In the next step, we will point Gatsby to the appropriate JSON:API feed coming from our Drupal environment. Since this value will change per environment we have already created a variable named “BASE_URL” in our gatsby-config.js file. To set this value, you simply add BASE_URL to a .env variable in your docroot. Important: remember to include the trailing slash and you do not need to add “/jsonapi” to the path. See below:


To test simply run the following commands (note that this assumes you have NVM installed):

nvm use
nvm install
npm install
npm run develop

If you are able to run without error you are in good shape! Remember to commit any updates made but you will want your local “.env” file ignored.

Step 5 - Configure Netlify

[embedded content]

Now that we have Rain and Gatsby connected locally we will want to prepare our static host. There are many options available, but we like Netlify because it’s free and easy to set up.

Once you sign up for a free account you will have an option to create a new site. You should see a similar screen as below.

config netlify

Mediacurrent uses Bitbucket for our git repositories but you can connect to any of the popular Git hosts from this screen. You will want to make sure to select the git repo you set up earlier that contains all of your Gatsby files. When you get to the last step you need to add two additional configuration settings.

additional config settings

For build command you will add “npm run build” and in the next box you will add “public” as your publish directory. This tells Netlify how to build Gatsby and where your public docroot lives.

Finally, we need to set up our “BASE_URL” variable in Netlify to point to our public Drupal instance. To do this we will add a netlify.toml file to our Gatsby repo with our host name.

Example netlify.toml:


  BASE_URL = ""

We need to tell Netlify to look for BASE_URL in this value so we will configure that in the “Environment” area on the project settings page. See below:

Netlify environment

To give it a whirl, go to “Deploys” and manually trigger a deployment. You will see in the console log whether it was able to read in JSON from your Drupal 8 site. Note: a good option to add some additional security is to add an htaccess password to your Drupal site and make sure that you are accessing that JSON endpoint over https.

Step 6. Connect Drupal 8 to Netlify

[embedded content]

By this point we have everything spun up connected but Netlify only builds when we manually trigger a build. In this step, we will point Drupal 8 directly to Netlify so that we can programmatically tell Netlify when to build. This is accomplished with the “Build Hooks” module.

The Build Hooks module is very flexible and can point to any environment which has a URL that triggers a Gatsby build. For Netlify we will be using the build_hooks_netlify submodule that provides direct access to Netlify using their API.

To enable API access we need to create a personal access token from your account. This is found under User Settings, Applications underneath the “Personal access tokens” area of the page. After clicking the “New access token” button you will see the following screen:

create new personal access token

All you need to do is name your token and you will be presented with the token value that the Build Hooks module needs to connect to Netlify.

Next we need to create a build hook trigger that is set up underneath the “Build & deploy” settings for your application. This is the URL that we are going to ping from Drupal in order to tell Netlify when to rebuild.

build hook trigger

Now let’s hop on over to our Drupal site and get things set up there. After adding and enabling the build hooks module (“composer require drupal/build_hooks”) and Netlify submodule you will be ready to configure the Netlify settings. This is where you will plug in the personal access token just created (see below):

build hook netlify setting

Once we do that we still need to set up the Build hooks environment. We will add a Frontend environment using the “Netlfy” environment type in the Build Hooks configuration.

From there we need to supply a few settings including the frontend URL, Build hook URL, API id and Git branch. The API ID value is found on the main “Site details” page for your Netlify app (see screenshot below).

site details

The interesting thing about the Build hooks module is that we have options for how we want to trigger Netlify’s build. We can manually trigger a build from Drupal 8 clicking a button, or we can auto-trigger builds every time content is saved or after cron runs. For our purposes we can select “When content is updated” but the beauty here is that you could set up a test environment that auto-builds while only updating production when manually triggered. That is the power of Gatsby + Drupal!

One additional step is we can prevent the auto-save setting locally by adding one line of configuration to our local settings.php. This effectively overrides that auto-save trigger. For that you will want to add the following line:

$config['build_hooks.settings']['logging']['entity_types']['node'] = 0;

Wrap-up - Final Testing

The last thing we need to test is to make sure that saving a piece of content in our Drupal host will trigger a new build in Netlify. To do that we click on any sample node on our test site with a small change such as an updated title. The first thing you should see is a message indicating that a change has been pushed to your Frontend environment. If that works we will want to check our Netlify “Deploys” tab to see if the build has been triggered successfully. If you run into any issues, you will want to double check your configuration and Drupal logs for errors.

Still having trouble? For Rain specific issues, please create a ticket in our project issue queue on For Gatsby related questions or problems, we have an issue set up on our Gatsby + Rain starter repository

May 17 2019
May 17

This past week I had the pleasure of attending Drupaldelphia, a great event that is part of Philadelphia Tech Week. This helped introduce the Drupal community to a broader audience from the Philadelphia area. It was nice to see new attendees curious to learn about Drupal and what we’re doing. It was a pleasure to be able to meet, and greet, many of these individuals throughout the event.

Some beloved community members like Tim Plunkett, Chris Urban, and Anson Han call Philadelphia home. All participants got first hand exposure to our community in Philadelphia, which I consider to be vibrant and growing. It was great for those of us local to Philadelphia, and those we welcomed that came from afar.

Community Discussion

There was something for everyone and it’s always refreshing to see how much cool stuff is happening within the community. Here are a few of the talks I enjoyed this year:

If you were not able to attend, never fear. Kevin Thull recorded all talks, which are now up on


Hook 42 at Drupaldelphia

Thanks to Hook 42 for sponsoring an event near and dear to me. I live in Pennsylvania and consider this event one of my local camps. It’s not a large event, but it is made up for in the connections forged and overall quality of the event. I’m glad to have been able to speak twice this year.

For my first talk, I spoke about I shared historically where the system has been, what challenges we face today, and where we’re heading. The system represents a labor of love on my part and I’m grateful to be able to spend some of my community time at Hook 42 helping maintain it. The system has a vibrant future and we’re doing some really great things with TugboatQA, one-click demos, Drupal 8, and an Open Collective that should help pave the way for a future inclusion program. 

The second talk was titled, “Impact Through Contribution: A Community for All.” During this talk, I present a path to contribution as “A Hero’s Journey”. This is a known storytelling technique written by Joseph Campbell where characters follow a conventional arc to achieve deeply impactful transformation. I shared stories of those who have had a huge impact and talked about some of the creative efforts happening in the community. I offered some thoughts on areas of growth and improvement for our community. It’s my belief that everyone can have an impact and bring new, creative ways to contribute that make our community stronger. We need to do everything we can to help make that happen.

Final Reflections

It’s such a great time to be with people, talk about cool things we’ve been doing, and help our community progress together. As an example, attendees were able to come together and discuss some outstanding issues on Layout Builder where consensus was formed on some next steps. Taking this conversation purely outside of the issue queue allowed people to learn and help move forward one of the most innovative new tools offered by Drupal.

I had a lot of fun in the city of Philadelphia as well. I can get good cheesesteaks in Central PA, so I needed to think bigger for my time there. I went to not one, but two, different Belgian restaurants where I enjoyed mussels and fries. For breakfast, I enjoyed excellent coffee and an almond croissant that was acquired from Bluestone Lane.

Another great Drupaldelphia came and went. The sessions were great and it was spectacular to connect with those that attended. It had a friendly, lighthearted, low-key feeling that allowed everyone to get something meaningful from the event. I thank the organizers, sponsors, and attendees who made it possible. I’m already looking forward to attending this jawn next year.

May 17 2019
May 17

In my experience, a big part of making a Drupal 8 site usable for content editors is customizing the WYSIWYG, which usually includes adding a couple additional CKEditor plugins.

Of course, you can simply download the plugins into the 'libraries' folder, and that's fine. But these days, it's becoming best practice to pull in all of your site's dependencies using Composer.

Adding 'package' repositories to your composer.json for the CKEditor plugins (the current best practice) works fine - but only for your individual site.

It doesn't work so well if you want to install:

  • A Drupal "Feature" (like with the Features module) that configures the WYSIWYG, including adding some CKEditor plugins, or
  • A Drupal distribution (like Panopoly or Lightning)

In those cases, you can't depend on what the individual site may have in its top-level composer.json, and asking the user to manually copy-paste a bunch of 'package' repositories in there may create enough confusion or problems that potential users will just give up.

Well, I've got an possible solution to this problem: an experimental Composer repository which includes CKEditor plugins for use on a Drupal site.

It works better for Feature modules and distributions, but can also make life easier for individual sites too.

Read more to find out how it works and how to use it!

This all started with porting the Panopoly WYSIWYG (panopoly_wysiwyg) feature module to Drupal 8...

Panopoly WYSIWYG provides a highly usable (and re-usable!) WYSIWYG configuration, originally based on Wordpress's WYSIWYG. It's part of the Panopoly distribution, but can be used on vanilla Drupal sites, or in other distributions.

In order to work, it needs a number of CKEditor plugins. In the old world order, we used Drush .make files to pull in any necessary plugins, and this is how it still works for Drupal 7. However, with Drupal 8, this needs to be done via Composer.

We could put a requirement into panopoly_wysiwyg's composer.json, like:

    "require": {
        "drupal-ckeditor-plugin/colorbutton": "4.*"

However, unless the user first added the necessary 'package' repository to their top-level composer.json, the installation will fail, because there isn't any package on Packagist called 'drupal-ckeditor-plugin/colorbutton'.

Adding those 'package' repositories would work, but it poses a number of problems...

For an individual site - nothing!

But there's a few issues for a reusable module:

  1. 'package' repository definitions are long and contain a lot of stuff. This may sound like a minor thing, but if you're asking your users to copy-paste something into their composer.json, the smaller and simpler the content can be, the harder it'll be to mess it up and lead to bad experiences and support requests. Panopoly WYSIWYG uses 6 plugins, and all the necessary 'package' repositories definitions amount to like 2 pages of text. :-)
  2. Different people may do them differently, either on purpose or accident. Since this would need to be defined in each and every site's composer.json, it can be made different. Maybe one site owner decides to pull in a different version of a plugin, or name it differently, or give it a different 'type' (to control where it goes in the code base). This creates inconsistency, which can, again, lead to bad experiences and support requests.
  3. We can't change them over time. If we find out that there was a better way to do the definition, well, then we have to tell everyone to go update their composer.json files in a specific way. Most people probably won't get the message, and it's another error prone step where the site owner could make a mistake.
  4. We can't add to them over time. Panopoly WYSIWYG currently uses 6 plugins - what if we want to add another? Well, 'composer update' will fail until the user adds the new 'package' repository to their composer.json.
  5. The plugin versions need to match the CKEditor version in Drupal core. Drupal core frequently updates the version of CKEditor in minor releases. For example, Drupal 8.6 uses CKEditor 4.10.1 and Drupal 8.7 uses CKeditor 4.11.3. If you're using a "core" CKEditor plugin (one that's bundled in the CKEditor source code) you should use the same version of the plugin as CKEditor. This means you need to update the versions in your 'package' repositories when updating to a new Drupal core minor, and creates challenges for a package like panopoly_wysiwyg that aims to work with either version.

So, in the context of a reusable feature or distribution, this is definitely not ideal.

A Composer repository is basically a remote collection of package definitions. is the main Composer repository where package definitions are pulled from by default, but it's also possible to use additional repositories. For example, provides a Composer repository that includes all Drupal modules, themes, etc from

Pointing your composer.json to an additional Composer repository, involves either (a) adding about 4 lines to your composer.json, or (b) running a single 'composer config' command.

It's easy to explain, simple to do, and hard to get wrong.

Also, since the the actual data is stored remotely, that means:

  1. Lots of people can share this same repository
  2. We can update it over time, adding or removing CKEditor plugins, or changing how they are defined
  3. We can add multiple versions of the same plugin with different requirements, for example, declaring which version of Drupal core they work with.

So, we created an experimental Composer repository with package definitions for CKEditor plugins, which is hosted on GitLab pages here:

This is generated using satis, based on some simple configuration files stored in this GitLab repository:

Using GitLab CI, any time we commit a change to that repo, it'll regenerate the Composer repository. So, if you want to see any CKEditor plugins added or contribute to this project, please submit an MR to that project. :-)

So, while the idea for this came from wanting a better solution for Feature modules or distributions, it can also be used on an individual site to install CKEditor plugins, and it is easier than the old recommended way.

To add the repository, run this command:

composer config repositories.drupal-ckeditor-plugins composer

And to install a CKEditor plugin - for example, the 'colorbutton' plugin - run this command:

composer require drupal-ckeditor-plugin/colorbutton:4.*

This will put the right plugin version for your version of Drupal core into your 'libraries' folder, and you didn't have to manually edit your composer.json at all.

And, if you update your Drupal core version, composer will know that you also need to update your CKEditor plugins to match.

To use with a Feature module or distribution, you need to do only two things:

  1. Add a requirement on a CKEditor plugin from the repository, like "drupal-ckeditor-plugin/colorbutton" (for the 'colorbutton' plugin, for example)
  2. Tell your users to run this command before installing your module or distribution:
composer config repositories.drupal-ckeditor-plugins composer

Optionally, if you provide a Composer project template for starting new sites (like the panopoly-composer-template), you can add the repository to that composer.json, so that new users don't need to follow any steps at all!

Every time I've referred to this Composer repository above, I've called it "experimental".

This is because, while this seems to work, we haven't really used it in practice yet. After spending some weeks or months using this with real modules and sites, we may find out that there was a better solution.

So, while I really encourage you to try it out, please know that this is the early stages, and doesn't (yet) change any of the best practices.

However, I will say that I don't ever intend to take this down.

It's hosted on GitLab Pages, so as long as continues to exist, this Composer repository will also exist. So, if you start to depend on it, it isn't going to go away.

But, just a warning: at some point, it could become deprecated if a better solution to these problems is found.

Please let me know your thoughts in the comments below or in issues/MRs for the project on GitLab!

May 17 2019
May 17

Earlier this week, The Cut ran a piece about a “Tinder Hacker” who created a fake profile with his roommate’s photos, then hooked a piece of code up to the Tinder API and did some very simple string substitutions so that men who messaged “her”–after “she” swiped right on them–were tricked into actually talking to other men who did the same. In brief, he put strangers in contact with each other under false pretenses, rerouted and surveilled their communications without consent, and proceeded to use this as a bragging point on dates and in interviews.

One might take exception to a number of elements of this story, but let’s start with its terminology. “Hacking” is a word whose meaning has broadened beyond all practical use, but in no sense did “Sean”, the pseudonymous subject of the story, “hack Tinder.” He relied on someone else’s reverse engineering to write some buggy code that ran against its API. That’s all.

The article itself seems confused about whether the Tinder API, or Application Program Interface, only exists to allow homebrew apps on Windows Phone. But an API is just a set of commands made available by a server, like the Tinder mothership, to accept instructions from client apps, like the many copies of the Tinder app that run on all kinds of phones. Almost all the apps on your phone are clients that work this way, and APIs are ubiquitous. Even the Drupal and Wordpress sites we build each have their own versions.

The code described in the article fits less within the definition of a hack than that of a bot. It would live on a server, persist as a service, wait for triggers–like incoming messages–and then respond to them according to certain rules. Some bots are used for automated customer service; some are used for art projects; some are used for jokes. Many, many, many bots are used for spam or other malicious purposes.

The ethics of bot development are not always simple, but they’re not new territory either. That’s the second and most glaring exception to be taken here: Sean’s assertion that his bot was at the “gray hat” level of malice in terms of its exploitation of code. Bot creator and Portland local Darius Kazemi wrote a thoughtful piece about considering and refining the possibility space of joke bots toward kindness in 2015. That in turn references fellow creator Leonard Richardson’s seminal 2013 post “Bots Should Punch Up”, which contains a telling bit with regard to the color of that hat:

“Hackers and comedians and artists are always attracted to the grey areas. But your bot is an extension of your will, and if you're a white guy like me, most of the grey areas are not grey in your favor.”

Perhaps it’s assuming too much to conclude that Sean, a San Francisco programmer whose race is not mentioned in the article, is a white guy. Perhaps not. Technology as a field in the US is overwhelmingly full of white men, offering most of the benefits of the biggest wealth creation engine in history to the people who were already granted our society’s highest levels of privilege. That privilege, and power, means that thoughtless choices have more potential to do harm: by default, they’re punching down.

But even if that weren’t the case, as an educated and socialized human adult, it shouldn’t have been hard to see that writing a service solely to entice, deceive, manipulate and mock people in a vulnerable space like a dating app might have consequences. That is, unless you’ve spent a career being rewarded for ignoring consequences, because you work in tech. That’s the third exception to be taken. For pulling a prank like this, many people would be fired or sued. Instead, Sean got a better job.

I can admit that this story struck me on a personal level. Back before I had to quit Twitter, I used to write bots using their API myself. One of them, which I created in 2014, worked on a similar principle to the Tinder bot: it would receive a person’s message, put it in holding, and send them back a random held message from someone else in response. The juxtapositions were surreal, delightful, and often rewarding. And everyone involved was informed, consenting, and able to make use of built-in safety tools to report bad actors.

I’m not an ethicist or a researcher by training, but I knew to consider those aspects of my work because I have an interest in the history of the internet. According to the article, Sean does too–I’m willing to bet he and I read the same books about phone phreaks, blue boxes and Captain Crunch.

The phreakers he admires, by the way, were indeed “punching up” with their pranks–using low-rent tools to get one back at Bell, an exploitative tech monopoly that would eventually be broken up. Hey, there’s an idea.

People have made infamously bad choices like Sean’s before, and one might expect creators here in the future to work at avoiding their repetition. But instead, his story reflects the broader attitude of a tech sector that is not just ahistorical, but willfully naive and ignorant of the lessons of its past. (If you only read one thing linked in this whole piece, make it that last one. Go ahead, I’ll wait.)

The things I value about working at ThinkShout stand in opposition to all of that. My colleagues here are technical experts, but they’re also widely read, deeply informed, and always working to expand our collective view of the world in inclusive and considerate ways. That’s why we take pride in supporting progressive organizations like the Campaign Legal Center and ChangeLab Solutions. That’s why we focus on accessibility for all users as a core concern and increasing equity in our own job pipeline. That’s why we’re fine with being located far outside the insular centers of big tech culture, where it seems like people would rather try to land on the Moon than make change on the ground.

Even if the article in The Cut highlights the deep problems in the technology sphere that engulfs us all, there are certainly worse things on the internet than a man getting his kicks by trolling a bunch of other men. But there are better things too. If you’d prefer to join us on that side, please get in touch! We’re hiring, and we’d be glad to hear about how your hobby project brought a little kindness and empathy to the world.

Get In Touch

Questions? Comments? We want to know! Drop us a line and let’s start talking.

Learn More Get In Touch
May 16 2019
May 16

One of the best things about Drupal’s open-source ecosystem is that it empowers you to be open-minded. Given the vast array of solutions and modules available, users can customize their site to their whims. Alternatively, if you think up and code something new, your contributions can be shared online with other users. With all of the customization available, Drupal is a conducive platform for outside-the-box thinking.

federated search

Decoupling is a recent example of this philosophy. Where a standard Drupal website would feature a Drupal-powered front and backend, decoupling opens the door for a variety of possibilities. A decoupled site can utilize different platforms and technologies for both the front and backend. For example, a decoupled site could utilize Drupal’s backend CMS while running a React-powered frontend. Such is Drupal’s flexibility that it can power scores of different, user-facing channels from a single backend, including other sites, native apps, Internet of Things (IoT), and more.

This decoupled or “headless” concept has more applications than just for site design, though. The search function of a website, for one, can benefit from components that utilize this headless approach – and not a moment too soon. As Google has begun to sunset its Google Search Appliance offering, there is now a need for an open and flexible search tool with enterprise-level capabilities.

At this year’s Midwest Drupal Camp, the team from Palantir demonstrated that a decoupled approach to site search was viable. This solution, federated search, allows for indexing and searching across multiple sites. For organizations with a large web portfolio across different platforms, this open federated search solution can fill the gap left by Google.

Decoupled Drupal Facts & Myths

Understanding why federated search for Drupal is important requires an understanding of how regular site search functions operate. At the core, the search feature is built from three different components: the source, index and results. The source simply refers to all of the searchable content on a given site, from blogs to landing pages. The index is a compilation of metadata that makes the content form the source easier to parse. At Duo, we often use Apache Solr, a platform-agnostic, open source solution for indexing, as it provides speed, power and its own server capabilities. Finally, the results refers to the front-end experience that compiles and delivers the search results to the user.

The above setup will work fine for most simple websites, but larger organizations often require a more robust solution. With federated search, users can query across multiple sites across different platforms without placing much strain on Drupal, since Apache Solr is handling generating the index and providing results. This is accomplished through some tweaking of the basic site search formula.

Part of what makes this search so powerful is that it takes advantage of Drupal’s backend without relying on its frontend. For that, Apache Solr’s dedicated servers empower this new search solution by shouldering the burden of indexing and providing the results. Before it can work, though, some configuration is needed. Based on this configuration, Apache Solr can encompass searches across different sites – including sites that aren’t built with Drupal. Creating this custom solution, in conjunction with the Search API and Search API Solr modules, will ensure that the different data types being indexed will be standardized.  

As for the results section, the best approach is a decoupled one. Building out the front-end component in the React JavaScript library allows for robust searches without slowing down the rest of the site. By using Drupal’s CMS, Apache Solr and React’s power in coordination, any organization can create a search feature that quickly indexes vast ranges of data and delivers it in an easily digestible manner. For a deeper dive, Palantir has made their demo of federated search available.

This powerful and streamlined take on site search has a variety of applications. Before releasing the solution, Palantir originally developed federated search for the University of Michigan, as each department ran their own sites on different platforms. Federated search now allows users to seamlessly search for information across the entire school’s network, regardless of the technology used to deliver the content. Beyond university ecosystems, federated search also presents an opportunity for eCommerce. Using this solution, products from different vendors can be consolidated into a simple search.

Thanks to Drupal being open source, organizations can utilize federated search and any other contributed solution at any time. This level of openness is what makes Duo such champions of the Drupal platform. At Duo, we’re committed to exploring new features like this and helping each of our partners think outside the box. If you’re ready to start rethinking your website or sites, we’re just a click away.

Explore Duo

May 16 2019
May 16

Drupalcamp Spain 2019 took place last week in the beautiful city of Conil, in the South of Spain. We had not only great weather, food, company… but also great sessions! This year’s schedule also included the Spanish Splash Awards, Business Day and even a side-event for those accompanying attendees, called Family in Drupal, where they did activities such as yoga, surfing, horse-riding, etc.

Drupalcamp Spain was a great gathering of people from not only Spain but many other countries. In fact, they offered two separate tracks, one in Spanish and one in English. As usual, it was difficult to choose which sessions to attend, but I think I got a really good mix and enjoyed them all thoroughly.

It’s also worth mentioning the registration bag that included a (very discreet) T-shirt, a bottle of wine (so my wife would be okay with me leaving her with the kids), a bottle of olive oil, some local tuna (Conil is a fishing town) and some other goodies.


I especially enjoyed the Friday afternoon English-track, which was “all about decoupled”. We saw an example of a project which started as a Drupal commerce site with some React components, which eventually became an app built in React native, integrating seamlessly with Drupal via GraphQL.

That was the perfect introduction to my talk, which was up next, about “GraphQL and Twig”, where I went through the whole process of installing, configuring and using GraphQL queries in your Twig templates, as a way of soft-decoupling some parts of your site. You can view the slides here:



I was very glad to see that my session seemed interesting and useful to attendees and I enjoyed getting to answer some questions right after the session and the following day. People were surprised about how easy it is to get up and running and how powerful this combination can be as well. The closing session on Friday afternoon was about Drupal + GatsbyJS, showing how easy it is to connect those two technologies and doing a live demo about it.

Saturday was also loaded with interesting content, and I ended up going to sessions on topics ranging from QA, SEO, UX, Migrations, Continuous Integration, Content architecture… that’s a good mix for a day, isn’t it? The speakers were really engaging and I must say that I learned a lot on that day. I also enjoyed learning how other agencies work, how we all face similar problems and solve them in different (or sometimes similar) ways. It’s always refreshing to listen to other people's experiences. I must say that most of these learnings happened in-between sessions, chatting and walking around Conil, etc.

Attendees(Photo credit: Jorge Carpio)

I want to give a big, big thanks to all the people who made this event possible: organizers (Ruben Tejeiro, 1xInternet, Drupal association Spain), speakers, photographer (Jorge Carpio), volunteers and attendees from all over.

Looking forward to next year’s edition, ¡muchas gracias por todo!

May 16 2019
May 16

“ inclusive community, we are committed to making sure that Drupal is an accessible tool for building websites that can also be accessed by people with disabilities.”

Calling accessibility as one of Drupal's core values and principles, the Drupal community has always stood to comply with web accessibility standards. Although with an absence of hard and fast rules to adhere to, the community has faced backlash in recent times.

First, with adopting Gutenberg (editor) and second with the release of Layout Builder, there have been some important questions and concerns about accessibility in the community.

This Global Accessibility Awareness Day, an awareness day to focus on digital access and inclusion for the more than one billion people with disabilities and impairments, let's take a look at how close is Drupal to its commitment towards web accessibility.

The Accessibility Controversy

a black and white design with G written in centreIn 2018, with WordPress 5.0 prepared to be released, the Gutenberg editor, a decoupled React based editing experience, was out for testing. Among other concerns like inconsistent user interface behaviour, difficulties with keyboard navigation through blocks ( far too heavily reliant on hover-based functionality), complexity to use it, the assessors were quick to call it inaccessible.

Drupal’s adoption of Gutenberg, got it in the fallout.

In another instance, when Drupal 8.5 released Layout Builder, the lack of accessibility in the feature brought the community into the topic of debate - how strongly does Drupal commit to accessibility?

How Does Drupal Ensure Web Accessibility?

Accessibility is about promoting inclusion than benefitting a small set of people with disabilities. It is about ensuring equal and inclusive access to the web resources, for the widest possible audience, without any bias.

And this has been reiterated in the Web Content Accessibility Guidelines (WCAG), that explains how web content can be made more accessible to people.

Drupal, in its Values and Principles, effectively lays down their commitment towards creating software which conforms to the accessibility guidelines. It conforms to the World Wide Web Consortium (W3C) guidelines which address:

  • Authoring tools, as part of the Authoring Tool Accessibility Guidelines (ATAG 2.0)
  • Web content, as part of the Web Content Accessibility Guidelines (WCAG 2.0)

As a result, it can be used both by developers as well as the site visitors.

Drupal has its own accessibility team, which helps identify the barriers occurring at the code level and the awareness level, and also resolves them. A number of such issues in the core have been identified and resolved, while also creating awareness within the community.

Some of these improvements included: Search engine form and presentation, drag and drop, color contrast, image handling, form labelling and so on.

Accessibility for developers is another added feature in Drupal, and through D7AX, it is an easy job to find contributed modules and themes which also support the development of accessible websites.

Let’s take a deeper dive into the key modules and features of Drupal that help overcome web compatibility issues, and ensure easier web accessibility:

Key Modules

Automatic Alt text It automatically generates an alternative text for images when no alt text has been provided by the user.  Block ARIA Landmark Roles  It adds additional elements to the block configuration forms that allow users to assign an ARIA landmark role to a block.  CKEditor Abbreviation  It adds a button to CKEditor which helps in inserting and editing abbreviations in a given text.  CKEditor Accessibility Checker  It enables the Accessibility Checker plugin in your WYSIWYG editor, which then helps inspect the content accessibility level; and solve them.  High Contrast  It allows the user to quickly switch between the active theme and a high contrast version of it.  htmLawed  It utilizes the htmLawed PHP library to limit and filter HTML for consistency with site administrator policy and standards and for security.  Style Switcher  Themers can provide a theme with alternate stylesheets. Allowing special styling for some part of the site, the module presents all those styles as a block with links. So any site user is able to choose the style of the site he/she prefers.  Text Resize  It provides the end-users with a block for changing the font size of text on your Drupal site.  Accessibility  It gives a list of available Accessibility tests, aligned to guidelines like WCAG 2.0 or Section 508.

Key Features:

  1. Semantics in the Core

Drupal has been built to encourage and support the proper use of semantic markup. Thus composing semantically correct HTML informs the browser and the assistive technology about the type of content it is managing with, and how this relates to other content.

This helps the assistive technologies carry out its activity effortlessly since they now have a structure to work with.

 2. Aural Alerts

Drupal provides a method called “Drupal.announce()” which helps make page updates obvious, in a non-visual manner. This method creates an aria-live element on the page.

 3. Controlled Tab Order

Drupal’s TabbingManager is an awesome medium to direct both non-visual and non-mouse users on the page, to access the prime elements in a logical order. And thus permits more control while exploring complex UIs.

 4. Accessible Inline Form Errors

Drupal forms are now more open to the expansion of available inline form errors. So now, it is easier for everyone to identify what errors made while filling in a web form.

 5. Fieldsets

Fieldset labels are utilized as systems for gathering related segments of forms. When effectively implemented, these labels give visual diagrams around the shape field gathering.

Presently, Drupal uses fieldsets for radios & checkboxes in the Form API. This helps towards additionally upgrading forms in Drupal.

What was the Outcome of the Controversy?

As always, the community has stood by accessibility as one of the core tenets. In a blog, Drupal's commitment to accessibility, Dries Buytaert - Drupal Founder - writes on the issue and how seriously the community takes the commitment to accessibility.

With that said, he announced that the Layout Builder functionality would be in a "stable" state for production use after ensuring that it passes the accessibility gate (Level AA conformance with WCAG and ATAG). This holds for both the authoring tool itself, as well as the markup that it generates.

With accessibility maintaining team, it has been jointly agreed that:

  • The first priority is WCAG 2.0 AA conformance. This means that in order to be released as a stable system, the Layout Builder must reach Level AA conformance with WCAG. Without WCAG 2.0 AA conformance, a stable version of Layout Builder won’t be released. This happened with a stable release of Layout Builder in 8.7.
  • The next priority is WCAG 2.1 AA conformance. Because these guidelines are still new (formally approved in June 2018), the stable version of Layout Builder won’t be held on them but are committed to implementing them as quickly as possible, even if some of the items are after the initial release.
  • While WCAG AAA conformance is not something currently being pursued, there are aspects of AAA that we are discussing adopting in the future. For example, the new 2.1 AAA "Animations from Interactions", which can be framed as an achievable design constraint: anywhere an animation is used, it will be ensured that the designs are understandable/operable for those who cannot or choose not to use animations.

The commitment to this ideal, by the leadership at Drupal and by the larger community, has remained steadfast despite challenges. The announcement and commitment to conform to AA level has reinstated the faith in the community towards its values.  

Ready to build digital experiences that are truly great for your customers - frictionless, accessible, and inclusive? Drop us a line, and our Drupal experts will be in touch.

May 16 2019
May 16

Agiledrop is highlighting active Drupal community members through a series of interviews. Now you get a chance to learn more about the people behind Drupal projects.

We're very happy we got to speak with Tim Lehnen, the interim Executive Director of the Drupal Association. Tim is honored to be serving the Drupal community for the past 5 years and is looking forward to how Drupal will evolve alongside digital innovations. Read on to revisit a touching moment from a past DrupalCon and find out more about some of the Association's notable recent accomplishments. 

1. Please tell us a little about yourself. How do you participate in the Drupal community and what do you do professionally?

My name is Tim Lehnen, and I'm the interim Executive Director for the Drupal Association. Prior to that I was the Director of Engineering for the Association. The board has just recently announced that we've appointed a new executive director - so I'll be happy to be returning to my role on the engineering team in June. 

2. When did you first come across Drupal? What convinced you to stay, the software or the community, and why?

I first found Drupal in around 2006, around the time of the Drupal 4.7.0 release. At that time I was a student building websites as a freelancer to help pay for my education. I didn't know all that much about open source communities and collaboration at the time, and my early career actually diverged from Drupal quite a bit. However, even during that time I observed and admired the community the Drupal project had built.

In 2014 when I saw that the Drupal Association was hiring, I jumped at the opportunity to come home. Being able to engage with such a passionate (and compassionate) open source community has been very rewarding - and being able to do it for a living is a humbling privilege. 

3. What impact has Drupal made on you? Is there a particular moment you remember?

Having spent just about the last 5 years working full time to serve the Drupal community there are many, many moments I could point to. 

In particular, though, I'd like to highlight the #DrupalThanks campaign at DrupalCon Baltimore, where one of our partners and sponsors EvolvingWeb chose to use their sponsorship time at the keynote not for commercial promotion, but instead to give flowers to DrupalCon attendees to present to anyone else in the community that had made an impact on them and say 'Thank you.' 

It's all too easy to get caught up in what is difficult and hard about the work we do, and moments like these are wonderful reminders why it is worth it. 

4. How do you explain what Drupal is to other, non-Drupal people?

I echo the words of project founder Dries Buytaert. Drupal is a platform for ambitious digital experiences. That doesn't mean it's only for enterprise, or only for large end users. If you are a scrappy non-profit or start-up or really anyone with an ambitious idea for your digital presence - ambitious means you! 

And yes, this means websites, but increasingly it also means other kinds of digital experiences like voice-assistant interfaces, kiosks and information displays, in-flight entertainment - and even AR and VR experiences. 

On the flip-side, Drupal is not a platform for simple blogging or brochure-ware. If your needs are simple, a less sophisticated platform might serve you well. But when you're really trying to make a mark in the digital space, Drupal is your best choice. 

5. How did you see Drupal evolving over the years? What do you think the future will bring?

I feel that Drupal will continue to hone in on its strengths - its highly engaged and expert community, the quality of its underlying architecture, and its pivot towards web services and decoupled architecture. 

Drupal is years ahead of other solutions when it comes to robust omnichannel and decoupled solutions - and as our digital interaction models evolve further and further away from traditional keyboards and screens, I think we'll see Drupal evolve to be used in ways that couldn't have been predicted when Dries first built the platform in his dorm room 18 years ago. 

6. What are some of the contributions to open source code or to the community that you are most proud of?

I've never been more than a mediocre developer, but I've always tried to find ways to contribute my project management skills. My team at the Drupal Association is the best in the world, and together we've done some amazing things for the community. 

I'm particularly proud of the team's work to create the Drupal contribution credit system. It's an industry first in open source, and as far as I know we're still one of the only open source communities that allows our contributors to attribute their work as a volunteer, sponsored by an organization, or on behalf of a client customer. It's given us tremendous insight into the lifecycle of contribution for the Drupal project. 

I'm also very proud of the team's recent work to move the Git tooling for the Drupal project to GitLab. I think that's going to enable a lot of new collaboration tools and reduce friction for contributors to Drupal. 

As far as my own independent contributions, I was very happy to work on defining the JSON feed for the Open Demographics Initiative, to support our work to improve representation on user profiles. 

7. Is there an initiative or a project in Drupal space that you would like to promote or highlight?

There are few initiatives I'd love to give a shout out to: 

8. Is there anything else that excites you beyond Drupal? Either a new technology or a personal endeavor. 

I'm an avid geek when it comes to virtual reality and augmented reality. I think I have four or five different headsets right now. The ability to actually inhabit a virtual world and feel present in it is something I've dreamed about since childhood.

At the same time, it feels like a very dystopian technology, and I can see how people perceive it as being yet another layer of technological isolation and alienation. On the other hand, it also has tremendous potential to help people who might be otherwise unable to travel or even leave their homes take part in new experiences, both solo and socially. 

We'll have to see where it goes! As with every new technology I imagine we'll have to take the bad with the good. 

May 16 2019
May 16

We are on our journey to master the Drupal performance, after having our previous Part 1: Caching published a couple of weeks ago, we've been lucky enough to get into Issue 386 of TheWeeklyDrop newsletter, Planet Drupal, and got much love and good feedback on Twitter.

If you haven't already read the first part of the series, the ultimate guide for faster Drupal: Part 1 Caching, please feel free to read that article too.

Note: You don't necessarily have to do all of these, some items listed here are replaceable with each other as well, so proceed with caution!

Faster Drupal - Part 2: Aggregation and CDN

  • The one and the only holy grail: Advanced CSS/JS Aggregation
    Ok I know on every Drupal optimization post you’d read you have to setup and configure AdvAgg module, but you gotta do what you gotta do!
    AdvAgg features and core benefits are listed on the module page completely, so go ahead and read them all, configure it the way that works best for you and move on
    Advanced CSS/JS Aggregation Drupal module

    Note: If you have Mod Pagespeed you might not need AdvAgg module, make sure that you don't overlap your own work

    But that’s not all, if you are on Drupal 7, you should consider checking Speedy module as well, in some areas, this might work a bit better so make sure to check it out as well
    Speedy module

  • For good JavaScript minification in Drupal, you can use modules such as minify but we’d like to recommend minifyJS instead, they listed the differences and benefits on their module page so check it out
    Drupal MinifyJS module

  • CDNize the whole project, as much as you can! You may use CDN module too

  • Move JavaScript to the footer if necessary, some JS files need to be rendered in the head based on the use case and what does the JS do! Also in Drupal 8, it’s quite easy to append your necessary library (Read it JS files) in the footer in twig template files

  • Consider if you can make your own scripts defer/async (a new challenge when it comes to Drupal js aggregation)

Okay, this round was much easier thanks to AdvAgg module for taking care of half of the things we need to do for us! Note that on the frontend side you can Uglify, Minify and make sure everything that you code, will become compressed, whether it’s CSS, JS or even images or SVG files! Now let's get to it, Image optimization. 

Image optimization

  • Drupal 8: Use the Responsive Image module wherever possible and create the appropriate styles. It uses the <picture> tag which is what we really want

  • One might say we have one too many image optimization modules in Drupal, which is a good thing! For that we tested some, experienced with some of them and here’s what we suggest: Use blazy and lazyload_images (Drupal 8 that uses IntersectionObserver instead of scrolling events), Also consider: lazyloader and image_lazy_loader when using the picture module for responsive images in Drupal 7. There is also a lazy loading option that works well

  • Image optimization: for main images/icons used in the design (Yes you can optimize SVG files as well), also the best tool for that is not in Drupal, try ImageOptim desktop app, Also there’s an API-based service available with a Drupal 7 module, take a look here, might worth setting/selling this up to clients

    Also in the same context, we can use which is free (But should donate some beer to them)
    Drupal 7 Module, Drupal 8 Module

  • Image formats like JPEG 2000, JPEG XR, and WebP often provide better compression than PNG or JPEG, which means faster downloads and less data consumption. There's a really good module that help you serve WebP, it's called, you guessed it; WebP.

  • Serve WebP images with your web server with the MOD PageSpeed by Google for Apache and Nginx.
    Or conditionally serving WebP images with Nginx.

Bonus tip: Even favicons should be optimized, sometimes people ignore the weight of a favicon file, You shouldn’t! 


For the next week, we will be covering subjects regarding Drupal database/web server tweaks & improvements, stay tuned.


Written by Sohail LajevardiSohail Lajevardi
Developer at Ramsalt Lab


May 16 2019
May 16

“Never doubt that a small group of thoughtful, committed citizens can change the world; indeed, it's the only thing that ever has.”
        - Margaret Mead

Today marks the 8th annual Global Accessibility Awareness Day.

GAAD was inspired by a blog post written in November 2011 by Joe Devon, a Los Angeles based web developer who was frustrated about an overall lack of awareness about accessibility. He called for a day devoted to building a more inclusive digital world. 

About six months later, on May 9, 2012, the first Global Accessibility Awareness Day occurred with about a dozen virtual and in-person events. 

Today, there will be hundreds of GAAD 2019 events celebrated in every corner of the world. 

It’s wonderful that digital accessibility is inching it’s way into mainstream thinking, but too often, the time and resources associated with making sites and apps accessible is viewed as a burden -- a legal requirement that would gladly be avoided, if possible. The fact is, expanding digital accessibility represents a profound opportunity to take a more expansive, empathetic, and inclusive view of our world and that always leads to good.

Into the Light

Digital accessibility is emerging from a code-related "have-to" that happens behind the scenes. We need to talk about it more and see it as an opportunity. 

We are living in a digital world that shuts out or limits the ability to engage for an estimated 15 percent of the population -- customers, constituents, audiences. 

This translate into business. The disabled represent $490 billion in buying power. And millennials, who value inclusivity and social responsibility more than any generation that preceded them represent $3.28 trillion in buying power. 

Once we get it -- that ensuring digital accessibility is not only a legal requirement, it’s the smart thing to do and the right thing to do -- our passion for accessibility moves up several notches. And just as accessible ramps at entrances to public buildings serve far more than the wheelchair bound, it’s helpful to understand that accessibility is not just for the “disabled.”  Let’s consider some ways that accessibility modifications make digital experiences more engaging and flexible for people of all abilities.

  • Logical layouts and engaging designs are not just pleasant to look at. Any user can get annoyed when needed information is difficult to find and interactions are complicated, but users who have cognitive difficulties or limited computer skills can be frustrated beyond all measure. Be sure to evaluate the user experience from multiple perspectives and angles. 
  • Adequate color contrast is essential for enabling users with a wide range of visual impairments, such as color blindness, to read, navigate, or interact with a site. Low-contrast sensitivity becomes more common with age, but good contrast also ensures accessibility in low-lighting conditions and for users who could be experiencing any number of temporary visual challenges. 
  • Video captions are, of course, essential to enable the hearing impaired to understand the meaning of a video. They also enable videos to be accessible to viewers who are in particularly loud environments, or in settings where silence is required. 
  • Alternate text for photos makes a site more accessible for the visually impaired. It can also bring additional context and clarity to digital experiences.
  • Technology that converts text to speech is viewed as a requirement for the visually impaired. It’s also helpful for dyslexic users, people who prefer not to read, as well as people who want to multi-task. Coding websites and apps to convert text to speech has the added benefit of helping search engines to detect content.
  • Customizable text capabilities enable users to adjust the size spacing and color or text without loss of function or clarity. There are a wide range of visual impairments that make small text unreadable, and difficulties in reading small type inevitable accompany the aging process for everyone. 
  • Clear language is key to accessibility. Industry jargon and acronyms always need to be explained. Run-on sentences and paragraphs can frustrate users of all abilities and in particular those who have cognitive impairments or learning disabilities. In the current environment, there is no patience or inclination for unraveling complicated text. 

This is a lay person’s look at digital accessibility -- an issue in our modern world that’s inherently tied to the common good. 

Do you agree? Join the conversation and let us know how you have discovered digital accessibility to be a means to broaden outreach and build bridges.   

May 16 2019
May 16


We live in an age of Drupal complexity. In the early days of Drupal, many developers would have a single Drupal instance/environment (aka copy) that was their production site, where they would test out new modules and develop new functionality. Developing on the live website however sometimes met with disastrous consequences when things went wrong! Over time, technology on the web grew, and nowadays it's fairly standard to have a Drupal project running on multiple environments to allow site development to be run in parallel to a live website without causing disruptions. New functionality is developed first in isolated private copies of the website, put into a testing environment where it is approved by clients, and eventually merged into the live production site.

While multiple environments allow for site development without causing disruptions on the live production website, it introduces a new problem; how to ensure consistency between site copies so that they are all working with the correct code.

This series of articles will explore the Configuration API, how it enables functionality to be migrated between multiple environments (sites), and ways of using the Configuration API with contributed modules to effectively manage the configuration of a project. This series will consist of the following posts:

This article will focus specifically on how developers can manage, declare, and debug configuration in their custom modules.

Configuration Schema

Configuration schema describes the type of configuration a module introduces into the system. Schema definitions are used for things like translating configuration and its values, for typecasting configuration values into their correct data types, and for migrating configuration between systems. Having configuration in the system is not as helpful without metadata that describes what the configuration is. Configuration schemas define the configuration items.

Any module that introduces any configuration into the system MUST define the schema for the configuration the module introduces.

Configuration schema definitions are declared in [MODULE ROOT]/config/schema/[MODULE NAME].schema.yml, where [MODULE NAME] is the machine name of the module. Schema definitions may define one or multiple configuration objects. Let's look at the configuration schema for the Restrict IP module for an example. This module defines a single configuration object, restrict_ip.settings:

  type: config_object
  label: 'Restrict IP settings'
      type: boolean
      label: 'Enable module'
      type: string
      label: 'Contact mail address to show to blocked users'
      type: boolean
      label: 'Log blocked access attempts'
      type: boolean
      label: 'Allow IP blocking to be bypassed by roles'
      type: string
      label: 'Action to perform for blocked users when bypassing by role is enabled'
      type: integer
      label: 'Whether to use a path whitelist, blacklist, or check all pages'
      type: integer
      label: 'Whether to use a whitelist, blacklist, or neither for countries'
      type: string
      label: 'A colon separated list of countries that should be white/black listed'

The above schema defines the config object restrict_ip.settings which is of type config_object (defined in core.data_types.schema.yml).

When this module is enabled, and the configuration is exported, the filename of the configuration will be restrict_ip.settings.yml. This object has the keys enable, mail_address, dblog etc. The schema tells what type of value is to be stored for each of these keys, as well as the label of each key. Note that this label is automatically provided to Drupal for translation.

The values can be retrieved from the restrict_ip.settings object as follows:

$enable_module = \Drupal::config('restrict_ip.settings')->get('enable');
$mail_address = \Drupal::config('restrict_ip.settings')->get('mail_address');
$log = \Drupal::config('restrict_ip.settings')->get('dblog');

Note that modules defining custom fields, widgets, and/or formatters must define the schema for those plugins. See this page to understand how the schema definitions for these various plugins should be defined.

Default configuration values

If configuration needs to have default values, the default values can be defined in [MODULE ROOT]/config/install/[CONFIG KEY].yml where [CONFIG KEY] is the configuration object name. Each item of configuration defined in the module schema requires its own YML file to set defaults. In the case of the Restrict IP module, there is only one config key, restrict_ip.settings, so there can only be one file to define the default configuration, restrict_ip/config/install/restrict_ip.settings.yml. This file will then list the keys of the configuration object, and the default values. In the case of the Restrict IP module, the default values look like this:

enable: false
mail_address: ''
dblog: false
allow_role_bypass: false
bypass_action: 'provide_link_login_page'
white_black_list: 0
country_white_black_list: 0
country_list: ''


As can be seen, each of the mapped keys of the restrict_ip.settings config_object in the schema definition are added to this file, with the default values provided for each key. If a key does not have a default value, it can be left out of this file. When the module is enabled, these are the values that will be imported into active configuration as defaults.

Debugging Configuration

When developing a module, it is important to ensure that the configuration schema accurately describes the configuration used in the module. Configuration can be inspected using the Configuration Inspector module. After enabling your custom module, visit the reports page for the Configuration Inspector at /admin/reports/config-inspector, and it will list any errors in configuration.

The Configuration Inspector module errors in configuration schema definitions

Clicking on 'List' for items with errors will give more details as to the error.

The 'enable' key has an error in schema. The stored value is a boolean, but the configuration definition defines a string

Using the Configuration Inspector module, you can find where you have errors in your configuration schema definitions. Cleaning up these errors will correctly integrate your module with the Configuration API. In the above screenshot, then type of data in the active schema is a boolean, yet the configuration schema defines it as a string. The solution is to change the schema definition to be a boolean.


In this final article of this series on the Drupal 8 Configuration API, we looked at configuration schema, how developers can define this schema in their modules and provide defaults, as well as how to debug configuration schema errors. Hopefully this series will give you a fuller understanding of what the Configuration API is, how it can be managed, and how you can use it effectively in your Drupal projects. Happy Drupaling!

May 15 2019
May 15

Before I dive into our Mental Health Initiative, I'll tell you how it came to exist. Leading up to our annual team retreat, I send a team survey to discover what excites or worries people. The questions change year to year, but here are what appear to be the perennial questions. I'll include the majority response from the team to each item as well.

This survey has had a significant impact on where we've put our focus and attention this year. We've created a support and maintenance offering and continue to find ways to celebrate our team for all the hard work and effort they put into their projects. But when I asked the question about making one change to our company, a couple of people responded with "better support for mental health." Having recently attended DrupalCorn in Iowa and listening to J.D. Flynn's inspiring and courageous presentation "Erasing the Stigma, Mental Health in Tech," I worried that we might not be doing enough, but I also didn't know if it was a problem—because we don't talk much about mental illness.

There's a stigma connected to mental illness, even when it's a sickness...not a weakness. Thinking of mental illness as a weakness is like telling someone who is wearing glasses that they aren't looking hard enough and shouldn't need glasses in the first place. As a company, it makes sense to help your team stay healthy, happy, and reduce the number of sick days people need to take. Depression, anxiety, and mood disorders all actively work to undermine performance and contribute to burnout. Burnout is awful.

Mental health is as essential for knowledge work in the 21st century as physical health was for physical labor in the past. As psychiatrist Dr. Michael Freeman writes:

By the end of the twentieth century, creativity became the driving force behind America's explosive economic growth. The creativity that drives economic growth is also a common feature of people with bipolar spectrum conditions, depression, substance use conditions, and ADHD.

In other words, there's likely a correlation between the rise of and demand for creative work and mental illness. Further, for as much as remote work lowers stress levels, it can foster loneliness and isolation, which left unchecked, can lead to anxiety and depression. Or as the CEO of Doist, Amir Salihefendic said, "When you don't see your coworkers in person every day, it's easy to assume that everything is ok when it's not."

So in August of 2018, I put out a call to action to form a Mental Health Initiative at Lullabot and many people stepped forward to better understand the issues surrounding mental health. Something useful from the beginning was to have a Human Resources representative as part of the team because many of the questions and insights led back to insurance-related questions. And, since we have insurance coverage for people in the US, Canada, and the UK, it can get confusing.

Phase 1: Forming a mission statement

After several meetings, we defined the purpose of the group.

To promote optimal mental health at Lullabot and reduce the stigma of mental illness by raising awareness, providing resources, and increasing support.

The first part of the mission statement acknowledges that we have two goals: to promote optimal mental health and to reduce the stigma of mental illness. In other words, this isn't just for people with a diagnosed illness. We also want to provide support for any mental health issues, which could be other stressors or challenges. Our strategy to make this happen is made of three parts:

  1. Raising awareness

  2. Providing resources

  3. Increasing support

With a three-pronged strategy in place, we could begin to categorize the services and support we currently provide.

Phase 2: What do we currently provide?

After we formed our mission statement, it was time to audit our existing support and services. We basically looked at everything we did for mental health and mapped them to each of the three strategies outlined in our mission statement.

We found that we did a lot as a company to increase support and provide resources. At the top of those lists were things like creating a #being-human Slack channel, team calls, manager one-on-ones, and so on. For resources, we provide health insurance with coverage for mental health services, an employee assistance program, and a handbook. Where we noticeably fell short was on raising awareness. We didn't really have anything on that list.

Next, we did a quick brainstorm of the things it might be helpful to add. Some examples were taking mental health first aid classes, increasing our education and awareness on mental health, discussing burnout and so on. But before we went any further, we knew it was time to get insight and direction from the team.

What does our team need?

While we have lots of ideas on ways we can improve mental health, none of it matters if it doesn't help the team. Nothing beats asking people for input over making assumptions on their behalf. So we created a survey to benchmark and set goals for future improvement. The study was anonymous and optional, with the results only available to Human Resources. And the poll was primarily modeled from the fantastic work of the Open Source Mental Health Initiative.

Phase 3: Next steps

Currently, we're in the process of aggregating the survey feedback from our team. Some of the broad takeaways so far:

  • Many team members found our insurance coverage lacking support for mental health needs. Specifically, some said the remaining cost after deductibles were still too high.

  • 75% of the team wants to learn more about our insurance coverage as it relates to mental health. We need to learn the kinds of questions people need answering and make it easy for them to get that information.

  • A little less than half the respondents said mental health issues sometimes interfere with work productivity. A "mental health issue" can be anything from daily stressors, challenges with working remotely, and finding coping mechanisms, to not-yet-diagnosed mental health conditions.

  • 12% of the team said they would not feel comfortable discussing a mental health issue with a supervisor.

  • 70% of the team was interested in learning more about burnout, anxiety, depression and understanding mental illness in general. This speaks to a significant educational opportunity.

It's scary to find out we’re not doing enough. But we would have never made it this far if we hadn't brought it up in the first place, and ignorance isn't an option. There is a lot to unpack in the five bullet points above. Is health coverage worse for certain countries? What does supplemental care look like? How does workers compensation help, if at all? Is there training we can offer managers to understand mental health issues better and cultivate compassion? How do we best spread awareness of mental health? How do we keep these conversation engaging and not too heavy?

We don't have all the answers, but we've lifted the veil of ignorance and set a clear path forward with actionable steps we can take. We also hope that sharing our efforts will contribute to reducing the stigma of mental illness. If you have resources or ways you can help support our initiative, please let us know. For example, if you are someone who routinely speaks to others about mental health, we'd love to connect and possibly have you talk to our team during a lunch-and-learn. Meanwhile, we will continue to share our insights with our broader communities as well.

Huge thanks to J.D. Flynn who paved the way for us to have this conversation by presenting the topic with courage and compassion. Please consider supporting him so he can continue his mental health advocacy efforts. And thank you to the work of the OSMI group who paved the way for our internal survey. Finally, we wouldn’t have made any progress without the leadership of Kris Konrady and Marissa Epstein. Huge thanks to the rest of our Mental Health working group: Angus Mak, Greg Dunlap, Chris Albrecht, Juan Olalla, Dave Reid, and James Sansbury.

May 15 2019
May 15

Our normally scheduled call to chat about all things Drupal and nonprofits will happen tomorrow, Thursday, May 15, at 1pm ET / 10am PT. (Convert to your local time zone.)

Feel free to share your thoughts and discussion points ahead of time in our collaborative Google doc:

We have an hour to chat so bring your best Drupal topics and let's do this thing!

Some examples to get your mind firing: how do I recreate [feature] on my Drupal 7 site in Drupal 8? I need to explain [complicated thing] to a non-technical stakeholder -- any advice? How can I get Drupal and my CRM to play nicely?

This free call is sponsored by but open to everyone.

View notes of previous months' calls.

May 15 2019
May 15

Acquia acquires Mautic

Recently, Acquia has acquired Mautic, an open source marketing automation platform. With this acquisition, Acquia is planning on disrupting the market and its closed technology stack competitors in the automation market. Acquia is a leading provider of digital experience solutions based on open source software Drupal. Now, Acquia product offering will be complemented by the newly acquired automation and campaign management platform, further adding more value proposition to the solutions offered by Acquia. This will provide marketers with a seamless experience, from designing and managing websites, to managing and tweaking communication campaigns across different platforms and digital channels. It seems that Acquia is dead set on making the future of marketing open source.

Here at Sooperthemes we're very excited about this move, because we've been interested in Mautic's development from the beginning and are looking forward to a closer Drupal integration.

Marketing automation is an emerging term in the marketing community. It promises solutions to age-old challenges that marketers face in their daily jobs. But what exactly is marketing automation?

What is marketing automation?

Marketing automation refers to software that aims to automate repetitive tasks. For example marketing involves a lot of repetitive tasks such as qualifying leads, emailing, social media posting and other editorial actions. Marketing automation helps to reduce the workload and makes it easier to bring those tasks to completion in a fast and efficient way.

Reasons for using marketing automation

Marketers can use automation paired with inbound marketing to increase the amount of qualified leads. Furthermore, it is easier to drive qualified leads through the sales funnel. Qualified leads have a lower churn rate than unqualified ones. Moreover, when it comes to nurturing these leads, it can involve loads of mundane tasks, which takes time and is inefficient. However, by using marketing automation, it frees precious time for the marketer to be able to undertake more strategic tasks.

Comparison of marketing automation software

HubSpot, Marketo, Pardot and Mautic are major players in the marketing automation market. In this article, there is going to be presented a comparison between the 4 automation platforms.


Hubspot Screenshot

HubSpot is a sales and marketing automation platform that is an all-rounder right out of the box. Out of the box, HubSpot is checking all the requirements for the most common tasks. Furthermore, it has unrivaled training, support and content. It also offers an easy to use interface for marketers, which is easy to use for even the most non-tech savvy of employees. A drawback of using HubSpot is that the contract is for at least 12 months, essentially locking up the customers to use the product. Furthermore, the pricing is also based on contacts, which can increase steeply. On top of that it also has some social media limitation when posting or tagging.


Marketo Screenshot

Marketo is the marketing automation solution from Adobe. It was acquired by Adobe in October 2018. Marketo has a starting price of $895 per month. It is a great mid-range solution for companies which require a robust solution but don’t want to spend more than necessary. As its drawbacks, it has a poor landing page and form builder. On top of that, it has limited reporting and analysis functionality. Furthermore, there are steep increases in prices for just some added features.


Pardot Screenshot

Pardot is the marketing automation and lead management solution from Salesforce. It has a starting price of $1250 for the most basic package. It allows marketing and sales teams to create and deploy online marketing campaigns in an easy and intuitive way. On top of that, Pardot brings the power to visually test the campaigns that are built, from the perspective of the client. On top of that, with the power of automation and segmentation, Pardot brings the power of smart lead management and generation to the table. Essentially giving the user the capability to nurture a lead based on different triggers that are activated during his customer journey on your website. Drawbacks of the platform include the fact that it lacks the tools for social media management. Furthermore, for A/B testing, user have to get the PRO subscription starting at 2000$ per month that is billed annually.


Mautic Screenshot

Mautic has recently been acquired by Aqcuia. The goal here is to deliver the first ever open source marketing cloud to the market. Mautic is an open source software with that has self hosting capabilities. What this means is that companies that are using it, will not have to outsource the servers from the software providing company. This gives the users an increased sense of security, since the data will not be stored on different servers other than their own. On top of that, being open source, the code is available for everyone to see. This means that people have the flexibility to contribute and adapt the code to best suit their business or personal needs. On top of that, Mautic has a great degree of integration, making it easy to integrate with different content management systems such as Drupal, WordPress, Joomla, TYPO3, etc.

One drawback that Mautic encounters is the fact that the installation process can be tricky for a person that is not working in the IT department. This coupled with the fact that Mautic does not have the best available documentation to guide the user to the process, can result in a frustrating experience.

Here is a visual comparison of the features provided by each platform:






Starting price





Lead scoring





Lead segmentation





SMS marketing





Personalize web content





Predictive analytics





Event management





Sales reports





Bi-directional CRM syncing





Create invoices





Split testing





Social CRM





Future-proofing Marketing

Given the fact that the forecast for the marketing automation market is going to grow and reach $32.6 billion by 2024, it’s safe to say that marketing automation is a growing trend. What this means is that more and more companies will start adopting marketing automation means in order to better and more efficiently fulfill daunting marketing task. Now, with the knowledge of the most important players in the field, you have taken the first step towards an automated future.

May 15 2019
May 15

The Drupal Event Organizers Group had a very productive DrupalCon Seattle (look for a blog post soon) and is taking the momentum from our in-person meetings to keep the initiative moving forward. Our next step is to create an official charter (similar to that of the CWG) to solidify our mission, process, and membership.

To that end, the Event Organizers Group is putting out a call for members of our Formation Board. This small group will be tasked with drafting a charter, reviewing it with the larger group, and then getting approval from Dries, the Drupal Project Lead, within the next few months.

We have representation from the US, and our immediate need is for members across the globe. If you're passionate about event organizing in your area and would like to be involved, please reach out to Avi Schwab on the Event Organizers Slack. We'll be having meetings at least bi-monthly and working asynchronously between them to develop the charter. We're committed to ensuring global accessibility, and as such will be alternating meeting times across the globe.

May 15 2019
May 15

There are Drupal modules loved by both developers and content editors. One of them is Layout Builder. It allows you to create page layout templates of various complexity via a handy drag-and-drop interface. The ability to do it with a built-in user-friendly tool is among the greatest benefits of Drupal.

We celebrate the news that Layout Builder in Drupal 8.7 core has become stable, which means it is officially ready for production sites. Let’s take a closer look at layout creation with this tool.

Layout Builder in Drupal 8 core: stable and feature-rich

Up to this moment, Layout Builder has gone a great path from an experimental module in Drupal 8.5 core. After a number of significant improvements and fixes related to keyboard accessibility, permission granularity, layout storage, translations, usability, and more, we now see Layout Builder in Drupal 8.7 core as a stable module.

Layout creation functionality is also found in popular contributed modules like Panels, Panelizer, Paragraphs, and Display Suite. Layout Builder inherits the best practices from them, and resembles them in many ways, while staying unique. So let’s review this intuitively understandable and powerful module has to offer.

Main features of Layout Builder

Layout Builder works with fieldable Drupal entities like content, users, comments, taxonomy, and so on. This “Lego box” allows you to:

  • compose the page layout with predefined sections
  • populate the sections with blocks that are various Drupal elements
  • configure each block
  • drag and drop the blocks to rearrange them

and much more.

The module can be used for these scenarios:

  • creating a layout for all entities of a certain type (e.g. all blog posts)
  • creating different layouts for different display modes (e.g. blog post’s teasers)
  • overriding the layout just for one entity of a type (e.g. just one blog post)
  • creating a layout for an individual entity (e.g. one landing page)

The last point deserves a special note. As Drupal creator Dries Buytaert wrote in his article “Why Layout Builder is so powerful and unique,” many of competing CMSs don’t offer a templated approach to layout creation from the browser. They only allow layouts for individual pages — in other cases developer input is needed. Drupal’s Layout Builder allows you to do both from the UI, which really makes Drupal stand out!

A tour on layout creation with Layout Builder

Let’s now have a look at how to create a simple layout with Layout Builder in Drupal 8.7.

1) Enabling the necessary modules

The layout creation story starts with enabling the stable Layout Builder and Layout Discovery modules in Drupal 8 core. 

enabling layout builder and layout discovery modules drupal core
2) Enabling Layout Builder for a content type

We want to create a template for all items of a content type. In our case, this is the “Tour” content type.

tour content type drupal8

In Structure — Content types — Tour, we select the “Manage display,” check “Use Layout Builder,” and click “Save.” 

enabling layout builder for drupal8 content type

Note: If we wanted to make each content item individually customizable, we would also check the other option “Allow each content item to have its Layout customized."

We no longer see content type fields, but no worries — they will be available in the Layout Builder UI where we can now go by clicking “Manage Layout.”

manage layout of content type drupal8
3) Composing our Layout with sections

Once moved, we can already see some sections made of existing “Tour” content type fields. We can use these or add new sections for 1, 2, 3, or 4 number of columns by clicking “Add section.” We can also add a couple of sections if we want to combine them vertically.

сompose layout with sections drupal8

When choosing the section, we can set the width proportion of its columns.

set column width layout builder drupal 8

4) Populating the Layout sections with blocks

Each section can be populated with blocks. These are not (or not only) Drupal blocks in the usual meaning — these are actually all Drupal website elements that are the building bricks for our Layout.

By clicking “Add block,” we see our content fields, lists (views), users, user fields, forms, menus, system elements, and so on. Blocks can be found by name. Custom blocks can also be created.

We have chosen a two-column section and we would like it to have the following blocks:

  • “Tour” image, “Tour” body, and Footer block for contacts (in the left column)
  • The “Venice stories” View that we have prepared (in the right column)

adding blocks to layout sections drupal 8

5) Configuring the Layout blocks

The familiar quick edit pencil above each block offers us to configure, move, or remove it. By choosing to configure, we see a configuration tray to the right. It has options in accordance with the formatters that the block has. For example, we can select the image style for our Tour image or hide the label in the “Venice stories” block.

configuring layout blocks drupal8

6) Brushing up the Layout structure

The blocks are draggable throughout the layout if we want to rearrange them. We then look through the page to see if it only has the needed sections and blocks, and remove the extra ones.

7) Saving the Layout and viewing our content

When we are done, there is no forgetting to click “Save layout” and then we can go and see how our content looks in our new template.

layout builder drupal 8 example

Get attractive Drupal 8 layouts!

We can all enjoy great opportunities for layout creation with the stable Layout Builder in Drupal 8.7 core. In our today’s example, we have just touched the tip of the iceberg of its capabilities.

Ask our Drupal development team to create magnetically attractive layouts for your Drupal 8 website, and let your users enjoy working with your site and your conversions grow!

May 15 2019
May 15

Enterprises aiming to create interactive, and omnichannel user experiences through their website, often rely on Drupal’s decoupled architecture. It provides them the flexibility to innovate, gives limitless options on what they can create, and empowers them with the ability to power multiple-sites and applications.

But is going fully decoupled the only way? What if your enterprise could have the best of both worlds? Say, progressively decoupled? How is it different? And what is the right choice for your business?

Here’s taking a look at both these approaches, suggesting what is best, and when.

From Coupled to Fully Decoupled

Traditionally, in its coupled architecture form, Drupal functions as a monolithic system with complete control over its technological stack. It owns the back end (data layers) as well as the front end (presentation layer) of your system. This makes it largely suitable for standalone sites and applications with mostly static content. Especially if the project requirements reflect purely editorial needs like:
  • Manipulating page content and layout without a developer
  • Requirement of in-context tools like in-place editing, contextual links, toolbar
  • Previewing unpublished content without custom development
  • Having content accessible by default like in Drupal’s HTML
On the other hand, decoupled Drupal is the full separation of concerns between the presentation layer, and the back end of your website. The CMS functions as a data provider, and front end uses APIs to cater to the needs of other experiences. As a result of this separation, each half of the website can do what it does best:
  • the backend focusing on business logic and retrieval of data, and
  • the frontend focusing on presentation of content
Decoupled Drupal is largely suitable for websites that need a flexible architecture, and enables front end developers to fully control an application or site's rendered markup and user experience. It is an excellent choice if the project requirements reflect purely developer needs like:
  • Control over visual presentation instead of editors
  • Server-side rendering or Node.js build features
  • JSON from APIs and to write JavaScript for the front end
  • Data security driven by a publicly inaccessible CMS
But deploying it would lead to the loss of inbuilt critical functionalities provided for free by the coupled CMS, such as:
  • layout and display management
  • content previews, user interface localization, form display, accessibility, authentication
  • crucial security features such as XSS and CSRF protection
While some of them may need to be rewritten from scratch, others can’t be implemented at all.

So then what would you do? Give up on these critical functionalities? Or stick with the monolithic architecture? It depends entirely on what your project requirements are. And supposing your requirements are a mix of both, Drupal has a solution for you too.

Progressively Decoupled Drupal Architecture

progressively decoupled drupal                                                                                                                                               Source

The best of both worlds, progressively decoupled simply blurs the line between the back end and front end, rather than fully decoupling the two. Doing so allows you to leverage Drupal’s rendering system, along with the simultaneous use of JavaScript frameworks like React and Angular, for providing interactive user experiences.

It strikes a balance between the editorial and developer needs, by

  • Allowing editors and site assemblers for contextualized interfaces, content workflow, site preview and other features to remain integrated with Drupal
  • Dedicating a portion of the page to a javascript framework, thus enabling front end developers to pursue their own velocity while keeping site assemblers blocked

Thus one can maintain client-side interactivity as well as create a potentially richer user experience with the use of this architecture.

Explaining this further with the help of an example,
Let’s say you have a music website for delivering music reviews, choosing either of the coupled or fully decoupled architectures will not get you the kind of UX and features you desire.

progressively decoupled drupal-1

But using progressive decoupled will. It will provide you the best features of both of these, rendering your website pages progressively. So that the skeleton of the page loads first, followed by expensive UX prone components like “currently playing” or “songs I listened to most in the last week”.

What Should You Choose

Now that you are familiar with both the decoupled approaches, which one should you go with?
It does not make sense to go with fully decoupled if your project also reflects editorial needs. Similarly, if your project requirements are purely of a developers’, progressively decoupled is not required.

Here’s a face-off between the two approaches to give a better clarity on which is the best choice for your business.

progressively decoupled drupal-2

No matter what your needs are, Drupal has a solution for you. At Srijan, we have expert Drupal teams to help enterprises assess their current architecture, and identify which decoupled approach is the way to go. Post assessment, we work to set up a complete decoupled Drupal architecture, based on your exact business requirements.

Get ready to deliver immersive online experiences across customer touchpoints. Let’s get the discussion started on implementing decoupled Drupal for your enterprise.

May 15 2019
May 15


We live in an age of Drupal complexity. In the early days of Drupal, many developers would have a single Drupal instance/environment (aka copy) that was their production site, where they would test out new modules and develop new functionality. Developing on the live website however sometimes met with disastrous consequences when things went wrong! Over time, technology on the web grew, and nowadays it's fairly standard to have a Drupal project running on multiple environments to allow site development to be run in parallel to a live website without causing disruptions. New functionality is developed first in isolated private copies of the website, put into a testing environment where it is approved by clients, and eventually merged into the live production site.

While multiple environments allow for site development without causing disruptions on the live production website, it introduces a new problem; how to ensure consistency between site copies so that they are all working with the correct code.

This series of articles will explore the Configuration API, how it enables functionality to be migrated between multiple environments (sites), and ways of using the Configuration API with contributed modules to effectively manage the configuration of a project. This series will consist of the following posts:

Part 1 gives the background of the Configuration API, as well as discusses some terminology used within this article, and Part 2 describes how the API works, and Part 3 explains how to use functionality provided by core, so they are worth a read before beginning this article. 

Read-only configuration

In some situations, site builders may want to prevent any configuration changes from being made on the production environment, preventing changes that may cause unexpected issues. For example, clients with admin access could log into the production server, and make what they think is an innocent configuration change, that results in unexpected and drastic consequences. Some site builders consider it to be a best practice to prevent configuration changes on the production server altogether, under the idea that only content should be editable on the production server, and configuration changes should only be made in development and/or staging environments before being tested and pushed to production.

The Config Readonly module, allows for configuration changes through the UI to be disabled on a given environment. It does this by disabling the submit buttons on configuration pages. The module also disables configuration changes using Drush and Drupal console.

A configuration form that has been disabled with the Configuration Readonly module

Note: some configuration forms may still be enabled when using this  module. Module developers must build their forms by extending ConfigFormBase for the Configuration Readonly module to do its magic. If the developer has built the form using other means, the form will not be disabled, and the configuration for that form can be changed through the admin UI.

To set up an environment as read-only, add the following line to settings.php, then enable the module:

$settings['config_readonly'] = TRUE;

After an environment is set as read-only, changes to configuration can only be made on other environments, then migrated and imported into the active configuration on the read-only environment.

Complete split (blacklist) configuration

Sometimes configuration needs to exist on some environments, but not exist in other environments. For example, development modules, like the Devel module, or UI modules like Views UI (Drupal core) and Menu UI (Drupal core) should not be enabled on production environments, as they add overhead to the server while being unnecessary since the production server should not be used for development.

A problem arises when configuration is exported from one environment, and imported into the production environment. All the configuration from the source environment is now the active configuration on the production environment. So any development modules that were enabled on the source environment are now enabled on the production environment. In the case of development modules like Devel, this may only add some overhead to the server, but imagine a module like the Shield module, which sets up environments to require a username and password before even accessing the site. If this module is accidentally enabled upon import on production, it will block the site from public access - a disaster!

The solution to this situation is to blacklist configuration. Blacklisted configuration is blacklisted (removed) from configuration upon export. This functionality is provided by the Configuration Split module. This module allows for black-listing configuration either by module, by individual configuration key(s), and/or by wildcard.

Note that more detailed directions for creating blacklists can be found on the documentation page. The following is meant to give an overview of how black lists work.

Blacklists are created as part of a configuration profile. Configuration profiles allow for 'splitting' (a divergence in) configuration between environments. Profiles may be created for environment types such development, staging and production allowing for configuration specific to those types of environments. Or profiles could be set up for public non-production environments, that would have the Shield module enabled and configured. While a development profile may apply to all development environments, not all development environments are on publicly accessible URLs, and therefore may not need the Shield module enabled.

When setting up a configuration profile, note that the folder name must be the same as the machine_name of the profile.

Configuration split profile settings

Note that you must manually create the folder specified above, and that folder can and should be tracked using Git, so it can be use on any environment that enables the profile.

Configuration can then be set up to be blacklisted either by module, by configuration key, or by wildcard:

Complete split (blacklist) can be set by module, configuration key, or by wildcard

Finally, environments need to be set up to use a given profile. This is handled by adding the following line to settings.php on the environment:

$config['config_split.config_split.PROFILEMACHINENAME']['status'] = TRUE;

Where PROFILEMACHINENAME is the machine_name from the profile you created.

Although blacklisted configuration does not become part of the exported archive, it is not ignored altogether. When an environment has the profile enabled, upon export, blacklisted configuration is extracted, then written to the folder specified in the profile. The remaining configuration is written to the default configuration directory. When importing configuration, environments with the profile enabled will first retrieve the configuration from the default configuration directory, then apply any configuration from the folder specified in the profile. Environments not set up to use the profile ignore the configuration in the blacklisted directory altogether on both import and export.

This means that a developer can enable the Devel module on their local environment, blacklist it, then export their configuration. The blacklisted configuration never becomes part of the default configuration, and therefore the module will not accidentally be installed on environments with the configuration profile enabled.

Conditional split (grey list) configuration

Grey lists, also provided by the Configuration Split module, allow for configuration to differ by environment. With a blacklist (previous section), the configuration only exists in the active database configuration for environments that are set up to use the configuration profile containing the blacklisted configuration. With a grey list, the configuration exists in the active configuration in all environments, but the configuration profiles can be set up to allow environments to use differing values for the configuration.

Imagine an integration with a remote API requiring a username, password, and endpoint URL. The production server needs integrate with the remote API's production instance, while other environments will integrate with the remote API's sandbox instance. As such, the values to be used will differ by environment:

Production Environment:

remoteapi.username: ProductionUsername
remoteapi.password: ProductionPassword

Other Environments:

remoteapi.username: SandboxUsername
remoteapi.password: SandboxPassword

A grey list allows for the setup of these values by configuration profile.

You may be remembering that Part 3 of this series of articles discussed overriding configuration in settings.php, and thinking that a grey list sounds like the same thing. After all, the default values for the sandbox instance of the API could be set up as the configuration values, and the production values could be overridden in settings.php on the production environment, with the same end-result.

The difference is that with a grey list, the remote API values are saved to the configuration profile folder, which is tracked by Git, and therefore can be tracked and migrated between environments. When grey listed configuration is exported, the grey listed configuration is written to the configuration profile folder, in the same manner as blacklisted configuration. When configuration is imported, the default values are retrieved, and the grey list values are used to override the default values, after which the configuration is imported into active configuration.

With the configuration override method using settings.php, site builders need to store the various configuration values somewhere outside the project, communicating environment-specific configuration values to each other through some means, to be manually entered on the relevant environment(s). With a grey list, the configuration values are managed with Git, meaning site builders do not need to record them outside the project, nor communicate them to each other through some other means. Site builders simply need to enable the relevant configuration profile in settings.php, and the environment-specific values can then be imported into active configuration from the configuration profile directory. This means that the sandbox API values can be set up as the values used by default on all environments, and a production configuration profile can be enabled on the production environment using the values to connect to the production instance of the remote API.

Conditional split items can be selected either from a list, or by manually entering them into the configuration profile:

Conditional split (grey list) settings can be selected or manually entered

Finally, note that grey lists can actually be used in conjunction with configuration overrides in settings.php. Grey lists are applied during import and export of configuration from the database. Values in settings.php are used at runtime, overriding any active configuration. So a developer could choose to set up their local instance of the system to connect to an entirely different instance of the remote API altogether by overriding the values in settings.php.

Ignoring configuration (overwrite protection)

Sometimes developers will want to protect certain configuration items in the database from ever being overwritten. For example imagine a site named Awesome Site, with a module that supplies the core of the site, named awesome_core. Since this module provides the core functionality of the site, it should never be disabled under any circumstances, as that would disable the core functionality of the site. In this case, the configuration for this module can be set to be 'ignored'. Any attempts to import ignored configuration from the file system to the active configuration in database will be skipped, and not imported.

Configuration can be ignored using the Config Ignore module. The functionality this module provides is similar to the functionality provided by the Config Readonly module discussed earlier, however the Config Readonly module covers the entire configuration of an environment, while the Config Ignore module allows for choosing configuration that should be protected. This configuration is protected by ignoring it altogether on import.

Configuration can be ignored as follows:

  1. Enable Config Ignore module on all environments.
  2. Navigate to the config ignore UI page, and set the configuration item to be ignored. In the case of preventing the awesome_core module from being disabled, the following would be added:
    Configuration to be ignore is entered one item per line. Wildcards can be used.

This setting will ensure that any attempts to change or remove core.extension:module.awesome_core upon configuration import will be ignored. So if the module is enabled on production, and a developer pushes configuration changes that would uninstall this module, those changes will be ignored, and the module will still be set as enabled after import.


In this article, we looked at various modules that extend the Configuration API, use cases behind these modules, and how the modules worked. We looked at the Config Readonly module, the Configuration Split module, and the Config Ignore module, and how to use these modules to manage configuration differences between environments. In the next, final part of this series, we will look at configuration management for module developers, and how developers can define the schema for the configuration their module provides.

May 14 2019
May 14
May 14 2019
May 14


We are in our 13th magical year, can you believe it? We'll be returning to Berkeley October 2nd - 5th, 2019!

We are stoked to be moving the venue to The Hotel Shattuck for 4 glorious days of the sessions, training classes, summits, sponsors, and parties you all know and love!

The 2019 website is currently under construction, but we couldn't wait to share our dates with the community. We'll keep you posted as the magic unfolds...


Berkeley hotels often fill up early for BADCamp week due to other events in the area. Book early to confirm your hotel!

We have rooms reserved at The Hotel Shattuck.

The Hotel Shattuck is in the heart of Berkeley only a few blocks from the UC Berkeley campus. The Hotel Shattuck Plaza building is one of the oldest hotels in Berkeley and was totally renovated just a few years ago. It's only a block from the Downtown Berkeley BART Station and provides easy access to the San Francisco and Oakland airports, as well as downtown SF. There are hundreds of fantastic restaurants and bars within a short walk.

Book online or call the Group Reservations team on their direct line
(510) 225-6013 during their business hours of with the group code 1910BADCAMP19.

Business Hours
Monday - Friday
8:30am - 5:30 pm

May 14 2019
May 14

When every business has a website, how do you stand out? Because customers expect so much more from digital brands, utilizing a marketing platform is essential. Marketing automation software enables businesses to deliver personalized engagement, strengthening customer bonds and driving new business.

acquia acquires mautic open marketing platform

Until recently, businesses have, by-and-large, had to rely on proprietary solutions like Marketo and Salesforce Marketing Cloud to handle their needs. Now, Acquia is looking to disrupt the marketplace. The Drupal SaaS giant has just acquired Mautic, an open-source marketing automation and campaign management platform. Now, Drupal users will have an open alternative to manage their customer experience needs.

This is the latest step Acquia has taken toward their vision for an Open Digital Experience Platform. The company has been working in the content management space for years and is now turning toward a data-driven, experience management approach. With their “API-first” philosophy, Acquia hopes to offer Drupal users maximum flexibility and the ability to meet any organizational needs that may arise. This level of freedom gives marketers the chance to customize every step of the customer cycle across channels.

While still a relatively young company, Mautic is a perfect fit for Acquia’s portfolio. While Acquia specializes in content management, personalization and commerce, Mautic will complement their offerings with their specialties in multichannel delivery, campaign management and journey orchestration. And with both Drupal and Mautic built on Symfony and PHP, collaboration and integration will be made easier. With 200,000 installations already, Mautic has already won over many marketers and, with Acquia’s expanded reach, will likely reach many more. Because of Mautic’s API-friendly build, our team at Duo can easily integrate the platform with a site.

Open Marketing (YouTube)

On a more philosophical level, Mautic echoes Acquia’s (and the Drupal community’s) open-source ethos. Currently, Mautic is the only open source alternative to the aforementioned legacy marketing cloud ecosystems. This openness makes it easier for the development community to create marketing platforms built for a company’s specific needs. This ease of use extends to the marketing side, too. Where many proprietary marketing automation software have steep learning curves and are bundled with countless other products in their respective clouds, Mautic’s platform benefits from its ease-of-use and its modern, streamlined design - allowing anyone on a team to get their organization’s message out faster than ever. To take a look at the platform in action, watch the demo embedded below.

[embedded content]

In addition to Mautic’s open offerings, the company also offers several commercial solutions. The first, Mautic Cloud is a fully managed SaaS version of the platform that includes some premium features not openly available. For enterprise clients, Mautic has Maestro. This product allows multinational organizations the ability to segment their marketing efforts by territory, while still allowing for sharing between regions. Campaigns can also be copied and repeated in different territories. These features will remain separate from Acquia Lift, though Duo can handle integrations with either service if needed.

So what does all of this mean for businesses using Drupal? This being an open-source community, it means more freedom! Rather than being locked into whatever is offered by legacy martech vendors, Drupal allows you to leverage best-of-breed services and solutions. At Duo, we’re always striving for more openness. Your solution should match your exact needs and the Drupal environment provides a vast range of solutions to make it your new site a reality. Now, Mautic joins those ranks, and can be used in conjunction with whatever other modules you opt to use. The open source ecosystem that makes Drupal so robust also gives Mautic more flexibility than other marketing automation platforms, and for a cheaper price tag, as well. Finally,

By 2023, spending on global marketing automation is expected to reach $25 billion. This software isn’t going anywhere, so why would you pay for a stale and outdated marketing suite that you may not be able to use to its full potential? With the acquisition of Mautic, Acquia has given marketers a whole new option when it comes to managing customer engagement. Duo can help you navigate the various marketing paths available while ensuring that whatever choice you make will exceed your expectations.

Explore Duo

May 14 2019
May 14

Long awaited and much needed in the pipeline, the Layout Builder was finally launched in May 2019. With an ambition to create a content tool that can provide more power and flexibility than comparable systems, the Drupal community had been working on a super progressive visual tool for more than a year. Earlier, the digital marketers had restricted templates to work with and were not satisfied with clunky design experiences. However, in the recent launch of Drupal 8.7.0, Dries Buytaert stated that the new layout builder will be able to manipulate different types of content and unleash unique and trend setting features. The feature of layouts for templated and customised content is crucial for websites with large amounts of content. 

For websites with heavy content, the Layout Builder has enhanced Drupal’s ability to handle “structured content” now. 

A man climbing a ladder in the sky

Originally introduced as an experimental module in Drupal 8.5, the primary focus of the layout builder was to develop a drag and drop WYSIWYG tool. Relying on a third-party software was getting painstaking for many and Drupal became one of the first CMS to take this risk. This layout builder offers full compatibility with revisions, workflows, and in-context previews. It is a single, powerful and visual design tool that creates layout templates that can speed up the development process for the site builders. The accessible, mobile-friendly page building tool allows content authors to easily customise individual pages with unique layouts too.

With 123 individuals and 68 organisations contributing, the Drupal 8.7 comes with this promising layout builder.

Advantages of Layout Builder

The shifting focus in the website development has lead to Layout Builder emerging as the most exciting CMS visual design tool. Let’s explore its reasons: 

  • You can create layout templates for a specific content type, such as blog posts, products pages, landing pages, etc. 
  • Layout builder empowers to customise the template layouts and override them on a case-by-case basis. 
  • It enables you to create custom landing pages that are not tied to a content type or structured content. 
  • The tool passes Drupal’s accessibility gate(Level AA conformance with WCAG and ATAG) with a stable state for production. 
  • The updated version in Drupal 8.7 allows streamlining mass-production while supporting unique creation.
  • The drag-and-drop management of your content blocks is now possible with the new layout builder 
  • Additionally, it supports keyboard controls and toggling the content preview on and off to give the content editor complete control of their experience while building their layouts.

With 123 individuals and 68 organisations contributing, the Drupal 8.7 comes with this promising layout builder. Moreover, 40 above individual contributors volunteered for the success of this release. 

Improved Layout Builder in Drupal 8.7

Translation Support

As the layout builder has improved features for translation, there are two approaches that can be taken here:

  • Synchronised approach translation: For multilingual sites that have the same layout, all the content and fields are automated. In other words, any text entered with layout builder is translated automatically for you. 
  • Independent approach translation: On the other hand, if you want different layouts for two different languages or take a localisation approach to the site, you can have independent and individual translations for them too.


From Drupal 8.6 to Drupal 8.7, the usability has drastically improved:

  • You can now narrow down the list of block available and add several tweaks to it. 
  • Contextual links are used to add shortcuts. The Drupal community is re-evaluating the usage as it is essential from the UI point of view. 
  • Except for minor alterations, the layout builder now gives real-time updates based on changes made in sidebar.


The usability is always inter-connected with accessibility. If it isn’t accessible, it is not usable for obvious reasons. The revamped version has features like:  

  • Improved usage of Drupal announce and ARIA attributes.
  • Now you can easily access the keyboard to action commands like save, discard, or revert from anywhere on the page. 
  • The tabledrag can get confusing for many. You can create a tabledrag-based UI to make all changes at once in the layout builder with Drupal 8.7. 

New Media Library

A new, stylish and with a handy user interface, Drupal 8.7 introduces us with numerous improvements in the Media Library:

  • The highlighted design and accessibility of the user interface makes way for inline media creation in the library itself. 
  • The process of searching the media items in the library, from bulk uploading them to the selection of media items and embedding them into the content is also a smooth run with the new version.
  • The Media module also allows reuse of images, documents, efficiently managed drag-and-drop function and provides a more flexible grid and table views. 
  • The media module in sync and stable with this media library and will further improve with the upcoming Drupal 8.8 release.
Screenshot of how to add new media in Layout Builder

Revisions in Custom menu links & Taxonomy

The following revisions in the 8.7.0 release aim to enhance the overall performance of the Layout Builder:

  • It allows the Custom menu links and taxonomy terms to fully participate in the editorial workflows. 
  • They have been revised for improved integration and core support for the Workspaces module with a new Update API for help in conversion of further entity types. 
  • The schema of any content entity type can now be converted between non-revisionable or non-translatable and revisionable or translatable. 

Automatic Entity 

Among many additions, there has been few subtractions as well: 

  • The support for automatic entity updates was removed due to data integrity issues and its conflicts. 
  • The drush entity:updates (drush entup) command stands nullified and the entity changes will now be performed using standard update procedures.

Internet Explorer 9 and 10

The workaround that still existed in D8.5 and D8.6 also gets removed as the *.7.0 release says goodbye to Internet Explorer 9 and 10. The workaround used to allow the inclusion of 32+ stylesheets. 

Check out Buytaert’s demo video showing the Layout Builder in action with Drupal 8.7.0.  

[embedded content]

On the way to Drupal 9

The major release of Drupal 9 planned for June 2020 will open new doors for the layout builder. It will update dependencies primarily on Symfony as the optional support for Symfony 4 is expected to complete by 8.8 version. Further, a better feedback on the compatibility can be obtained as we testing Drupal with updated third-party dependencies in this version. Drupal 8.7.0 also includes an optional support for Twig 2 (for sites that can patch their Composer configuration). 


New improvements in terms of keyboard navigation accessibility, precise permissions, layout overrides, and column width selection has given a stable outlook to the Layout Builder and it is ready to work on live sites. The process of constructing pages “brick by brick” with a combination of elements, configuration of blocks, and drag-and-dropping feature is an easy and enjoyable one. 

Check out the new Drupal 8.7.0 version and share your views with us in the comments! We’d also like to hear from you at [email protected].


May 14 2019
May 14

Here's a short video of it in action.

Ok, that looks pretty cool. Show me the code.

WTF? That code is crap. You have hard-coded what you want the site do to. That's not going to work for all sites, only for your specific use case.

Yep, that's true at the moment. Like I say, it's just a proof-of-concept. We'd need to create a settings page for users to decide if they want it to be available or not. And we'd have to create a better parsing system that listens for "voice admin" and then starts recording. Then we'd need to make sure that it patches together the fragments of speech after this to construct the action that you want to perform. Following that, it would be really cool if on the settings page users could type in commands and responses that SpeechRecognition will listen for and then perform.

I think all this is very possible, and probably not too much work. It would be great to see more progress on this.

If you'd like to create a pull request, the code is available on GitHub.

May 14 2019
May 14

Please enable cookies

This website is using a security service to protect itself from online attacks. The service requires full cookie support in order to view the website.

Please enable cookies on your browser and try again.

Reference ID: 4b112b72a690ea41f60c3bc142d5366f

This website is using a security service to protect itself from online attacks.

This process is automatic, you will be redirected to the requested URL once the validation process is complete.

May 13 2019
May 13

Drupal 7 was officially released in 2011, making it quite old in web years, though it still powers hundreds of thousands of websites worldwide.

Drupal 8 was released in 2015, but the path to upgrading has never been an easy one for Drupal websites (prior to 8). So our recommendation for most Drupal 7 site owners has been to wait– wait until you have the time, budget and other resources needed to do a full redesign and migration to Drupal 8.

But Drupal 7 isn’t going to last forever.

It’s official end of life has already been decided–November, 2021. A full ten years after its original release, Drupal 7 will no longer be officially supported. What this means is no more security patches or bug fixes.

It won’t just stop working, but without official support, Drupal 7 sites will become vulnerable to crashes, hacks and other vulnerabilities. There are private companies who will continue to support Drupal 7 sites after 2021 in exchange for a support contract. But officially, it will be unsupported and after 10 years of service, most sites could benefit greatly from a more modern CMS.

But when is the best time to upgrade? What will it take? What are potential problems, or gains? And why should you continue using Drupal in the future? Let’s break down these questions one by one.

When is the best time to upgrade?

In our opinion, the best time to upgrade is the next time you fully redesign your website. While smaller, ongoing updates and improvement are critical to maintaining a vital and effective website, at some point site owners should look at conducting a full redesign.

The general recommendation is for organizations to conduct a full redesign every 2-5 years, depending on your resources, audience, content, and budget. While there’s no one-size-fits-all, anyone still running the same website after 5 years is risking their ability to stay relevant.

So much may have changed since you last redesigned–user expectations, the way people access the web, how you reach your audience. It is worth revisiting your overall strategy. Certainly the way a site is produced in Drupal 8 is also different than Drupal 7. Only focusing on a version upgrade may be a lost opportunity to take advantage of all the new features Drupal 8 has to offer.

What if I just redesigned, or don’t have the budget for a full redesign?

If you aren’t interested in a full redesign, or unable to consider that option, you have a few options. The first, as stated earlier, is to wait. Start budgeting for a redesign and version upgrade today, knowing you still have at least 2 years before you have to make your move.

The second option is to keep your current site as close to the same as possible, but upgrade to Drupal 8. I would love to tell you exactly what this will take. But like many things in life, it just depends.

The lowest cost scenario for an upgrade is a very simple Drupal 7 website, one that relies on minimal content types with few fields, very few contributed (non-core) modules, and nothing in the way of custom modules or templates. It our experience, however, this isn’t a very common scenario for all but the most basic of websites. The more complex sites depend on an array of custom and contributed modules and custom templates which make upgrading a more… nuanced experience.

Drupal 8 does have a great suite of Migrate modules in core that an experienced developer can use for when updating a site from Drupal 7 to 8 (or migrating from other content management systems). There are, unfortunately, quite a few areas where a versions upgrade runs into trouble, however.

Why can’t I just easily upgrade from Drupal 7 to 8?

As great as Drupal is, its Achilles heel has been version upgrades. They've been historically difficult and time consuming. The good news is, from Drupal 8 to 9 and beyond, this has been addressed and fixed! But if you’re in Drupal 7,  the upgrade path is still a hard one.

There is a good reason for this, of course. With Drupal 8, the entire system was rearchitected. Unlike an upgrade from WordPress 4 to 5, for example, where the overall system remained the same, Drupal 8 changed everything. It introduced the use of Symphony, Composer, Twig templating and a greater reliance on object-oriented programming (OOP).

Extremely popular modules like Views became part of Core, which is great moving forward, but (as of now) requires users to completely rebuild any Views used on their Drupal 7 sites for Drupal 8. Themes in Drupal 7 relied on PHP Template Engine but now use the more modern Twig language for templating.

Popular methods of staging sites via the Features module were replaced by new techniques such as Configuration Management. Photos and videos are now "entities" managed by the Media module, which itself is part of the core install. These were all extremely valuable improvements, but at the cost of making version upgrades difficult.

So what does it cost?

If you’re able to follow our original recommendation, and upgrade to Drupal 8 as part of an overall redesign, the cost is wide-open and not really dependent on the software upgrade. While some or all of your content might be migrated, and modules replaced with the latest versions, often times it’s faster and easier to recreate the entire site from scratch.

This approach, however, means budgeting a lot more than you might have planned for a ‘simple software update.’ Instead you budget for a full redesign and all the work that entails.

Whether you are pursuing a full redesign, or “simply” a version upgrade, the first step in estimating the cost is to conduct a site audit. Using spreadsheets or documents, start collecting data on all of your site content, asking questions such as:

  • How many content types do you have? What fields are in use?
  • How many users and user roles do you have?
  • How many Views are in use? These will need to be recreated by hand
  • How are you going to map existing URLs to content on Drupal 8? What redirects are in place?
  • How many site menus do you use? Menus will need to be recreated
  • What theme are you using? Whether it’s custom or not, it will have to be rebuilt
  • How many blocks do you have, and where are they used?
  • Are you using Field Collections? These will need to be replaced
  • How much Media do you use (images, video, etc.)? These will need to be mapped to entities
  • What contributed modules do you use? Is there a corresponding Drupal 8 version, and if so, does it offer an upgrade path?

Planning for a version upgrade requires a close look at everything your site does, all the users and content, and identifying all the series of steps required to not lose functionality, content, or search engine placement.

TLDR; the cost depends on the size and complexity of your existing site. Plan on 70-100 hours of work at the low end, to well over 200 hours for more elaborate sites.

Why should I bother with Drupal 8?

Considering all the complications and expense with upgrading to Drupal 8, a natural reaction might be to not bother at all. Why not move your site to WordPress, for example? There are, however, more than a few important reasons to consider staying with Drupal.

Drupal 8 is so much better

We’ve talked about how the rearchitected Drupal 8 made version upgrades difficult. But you can’t do that without also talking about much was gained in Drupal 8.

  • More in Core – Views, Media, WYSIWYG, Layout Builder and more
  • Improved Editorial Experience – CKEditor, drag and drop, inline editing
  • Improved Media Management – including new Media library tools
  • Accessibility improvements
  • HTML 5
  • Mobile first and responsive
  • Data integrations – API-first platform with RESTful services and JSON:API in core
  • Configuration Management – easier and faster for developers
  • Improved multilingual support for over 100 languages
  • Security and performance improvements

Future updates are so much easier

Even though the Drupal 7 to 8 process can be long and cumbersome, the future is bright! Drupal 8 was designed for ease of version upgrades. It relies on a new release cycle and semantic versioning for more predictable update schedule. Minor releases come out every 6 months (e.g. 8.6 to 8.7) allowing every site owner to keep their site up to date.

Even better, each minor release contains new and sought-after features, meaning you don't have to wait years between release cycles. Patches and bug fixes get released as needed, until the next stable release of Drupal comes out. Updating to Drupal 9.0 won’t be any different than updating from 8.6 to 8.7!

Even now, every Drupal 8 module is being tested for compatibility with Drupal 9, and the great news is that many of them are already there. As long as you’re keeping your Drupal 8 site up to date, the next full version upgrade should be a piece of cake.

Drupal is ready for the future

Thanks to Drupal’s API first initiative, Drupal 8 (and beyond) is positioned as a powerful platform that makes it easy to integrate with other systems. This includes the increasingly common need for tight integration with existing applications and tools, plus the ability to use and display your content any where you like.

Drupal can now be easily used to power mobile applications, digital signage, voice controlled skills, the Internet of Things (IoT) or as an API that other applications can communicate with directly. The world is quickly moving in this direction, and Drupal 8 is ready for it now.

Familiar with the software

In addition to gaining all the features mentioned prior, it’s worth putting in a plug for the advantage of familiarity. As much as things have changed, there is still a core experience that you will find the same. Content types still power how your content gets entered, Views still drive your database queries, Users can still be managed through powerful Roles and Permissions. Blocks are still a key element of building out your pages.

If you’ve built up years of experience and know-how working with Drupal 7, why throw that all away? Get to know the new features which will improve your site experience, while taking advantage of all that historical knowledge.

And most importantly, the community that makes Drupal so great is still here. That means all the help and knowledge sharing you found on, the online tutorials and articles throughout the web, the agencies and developers who worked with you before, and conferences and meet-ups dedicated to Drupal–we’re all here to help you move to Drupal 8!

Worried about the future of your Drupal 7 site? Thinking about an upgrade? We can help you audit your current build and identify what’s possible. Contact us for a conversation about your upgrade.

May 13 2019
May 13

Digital experience platforms (DXPs) had a big moment this past week.

With Wednesday’s simultaneous announcements, Acquia acquired the open source marketing automation platform Mautic and rival Sitecore acquired the digital consultancy Hedgehog .

Phase2 squarely operates in the business of implementing and integrating DXPs—so naturally I have thoughts on these announcements.

While there is a huge ecosystem of products and providers in this space, there are really three standard platforms that the majority of large-to-medium sized enterprises are centered on: Adobe, Sitecore, and Drupal/Acquia. And while we may be accustomed to the non-organic “growth of the Adobe platform via acquisition”, we haven’t seen many major acquisitions among contender platforms.

So what is driving this consolidation?

What does that signal for the market?

And what does it mean for our clients and our company?

Acquia Acquires Mautic

Over the last few years, Acquia has begun an aggressive strategy to compete with the DXP product offerings of Adobe and Sitecore because digital experiences are not built on Content Management Systems (CMSs) alone. Sophisticated clients, that are in touch with customer needs, also have an overwhelming need for marketing technology that can drive results beyond building, hosting, and powering websites and content. That includes key components like commerce, CRM, and “martech” including: personalization, journey orchestration, marketing automation, and customer data platforms (CDPs).

Phase2 and Acquia share a perspective that the best way to serve those clients (and their wide range of design, technology, and brand needs) is through digital experiences based on open technology viz. open source, and an open API architecture that allows for greater integration, portability, and customization.

In addition to a cloud-based hosting platform and support for Drupal, Acquia offers a variety of products focused on completing the DXP including a personalization engine, a customer journey orchestration tool, and a digital asset manager. But this leaves several components of a complete DXP unaddressed; and traditionally, Acquia customers filled those gaps with alternative, best-of-breed solutions. Most notably absent was marketing automation. Enter Mautic.

Mautic was a necessary acquisition target for Acquia because:

  • Building a stronger connection between Mautic, Drupal, and the Acquia platform should provide superior integration of customer data over using Marketo, Eloqua, Pardot, or Hubspot.

  • Today, Mautic is the only viable open source product that could fill this gap and should appeal to customers who prefer open alternatives to proprietary software.

  • It’s a (not-so-subtle) counter to Adobe’s acquisition of Marketo which could be an entry point into the Adobe Marketing Cloud for shared customers.

Since it’s open source, it’s particularly appealing to many Acquia customers already on Drupal. But also, there’s a natural fit from the perspective of Dries Buytaert, Acquia CTO and Chairman (and the creator and leader of the Drupal project), who envisions the Acquia platform as an “open” alternative to both Sitecore and Adobe—an important option in the market which secures the credible statement that they are building the “First-Ever Open Marketing Cloud”.  

This acquisition also continues the trend I highlighted in an October post, when IBM acquired RedHat—where I argued that open source’s time in the enterprise has come-of-age and consolidation and adoption of open source software was the “new normal”.

Sitecore Acquires Hedgehog

Meanwhile, the move by Sitecore to acquire one of their leading services partners is unusual. And it could indicate that along with expanding revenue, control over the implementation of their software is an objective.

Ultimately, I suspect this move is going to enable them to control more successful implementations, but potentially at the cost of the loyalty and health of their partner ecosystem. It could be a step into the slippery-sloped-world of “channel conflict”.

Look no further than giants like Oracle and IBM that have long struggled with this balance. They believe they need a services component to ensure successful adoption and guide tricky and leading implementations, but they inevitably face backlash from both partners and customers who want a healthy and flourishing ecosystem of implementation partners to choose from.

In my opinion, Acquia’s pursuit of product over services is a healthier direction for all players in the ecosystem. While they have more components still to develop or acquire in their pursuit of a complete DXP offering, the open nature of the platform and the driving direction from its open source roots allows customers to componentize a heterogeneous DXP that has already become the standard.

Upon taking the CEO position at Acquia in December 2017, Mike Sullivan made a very important statement to the Acquia partner community, the Drupal community, and Acquia’s investors when they redirected the professional services (PS) team at Acquia to staff-up the product engineering team. The company has pledged to limit the growth of their PS team to a defined percentage of revenue to ensure ample opportunity for partners and focus their PS efforts on enablement, unique challenges, and high priority adoption projects.

In fairness, Acquia did have a larger PS group than Sitecore. But, using some very back-of-the-napkin calculations on both companies, I would conclude that this move likely puts Sitecore’s total PS size above that of Acquia’s. It will matter, of course, how and where they deploy this team—in terms of implementations vs. training/enablement.

What’s Next?

It was just over a month ago, that in similar fashion, Salesforce and Adobe announced (also in the same week) that they were acquiring competing Customer Data Platform (CDP) products. So this is all still far from over; we are going to see more acquisitions and consolidation.

We may also see the DXP solution components themselves like CMS, CRM, DAM, commerce, personalization, marketing automation, CDP, MDM and campaign management merging into more consolidated categories of software. This is increasingly likely in light of the fact that key industry players like Adobe will want to blend these distinctions to create platform stickiness. It is easier to sell a “Marketing Cloud” than independent types of software.

Personally, I believe that while consolidation of the DXP market will help with customer confusion, there will be (and should be) a place for heterogeneous, de-coupled DXPs that use an API-first architecture to combine different components. These will give customers greater choice, “best-of-breed” functionality, lower (or more controllable) costs, and more opportunity to cater to the uniqueness of each digital experience.

And finally, despite the power of software as the building blocks for digital experiences, the real key to success is how the true experiences are brought to life—beyond underlying platforms. In other words, success of complex digital implementations remains dependent on the services necessary to plan, execute, integrate, design, and polish the user experience of the product. And services companies—like ours—will continue to play a key role in guiding the success of implementations and experiences themselves.   

May 13 2019
May 13

Since last month a lot of Drupalists were busy preparing for and traveling to DrupalCon, we wanted to give everyone a chance to catch up with important news and goings-on in the Drupalverse. To this end, here’s a recap of our favorite Drupal-related posts from last month. A new site of Drupal videos tutorials

The first post from April we want to highlight is Karim Boudjema’s introduction of, a new resource for the Drupal community to easily find videos from various Drupal events. The idea for the website was born out of Karim’s desire to give something back to the community who is doing so much, but often has no lasting value to show for it. is essentially a curated collection of videos found on YouTube that aim at either promoting or educating people on Drupal. To be as helpful as possible both to beginners as well as more seasoned Drupal developers, the site is divided into two sections: one that focuses on the basics of Drupal theming and site building, and one that’s dedicated to more specific topics. 

Read more

A Series Of Unfortunate Images: Drupal 1-click To Rce Exploit Chain Detailed

This next post, written by Zero Day Initiative’s Vincent Lee, relates the discovery of a set of bugs in the recent critical patches for supported versions of Drupal 7.x and 8.x. These two bugs enable remote code execution through uploading three malicious files to the target server and then persuading the admin to click on a crafted link. 

While the exploit is not exactly smooth and involves the attacker(s) having to set up a profile on the site (which means that any site which doesn’t allow visitors to create accounts is automatically safe), it is still interesting and useful to be aware that the possibility of such an attack exists.

(By the way, the song in the video of the two bugs in action is really great - if anyone knows what it is, please let us know!)

Read more

The privilege of free time in Open Source

In the third post on this month’s list, Dries touches upon the problematic of open source contribution of underrepresented and less privileged groups. Because of their social and/or economic status, e.g. women must dedicate a lot of time to childcare and housework, these groups don’t have as much time to do unpaid work on open source. 

In contrast, privileged groups have much more time to contribute, which results in a lack of diversity in tech and open source in particular. But time constraints are not the only issue here; people from underrepresented groups are often subject to hostility and discrimination, which makes them that much more reluctant to continue contributing to open source. 

So, as individuals, we need to be more welcoming and not succumb to our biases. As for organizations, sponsoring your employees’ work on open source so that they don’t have to do it in their limited free time can really go a long way. 

Read more

State of Drupal presentation (April 2019)

Next up, we have another post written by Dries, this one essentially a recap of his annual State of Drupal presentation which he gave at DrupalCon Seattle. The post actually opens with the topic of the previous post mentioned here, that is, fostering diversity and inclusion in open source by giving underrepresented groups better opportunities to contribute. At this year’s ‘Con, nearly 50% of the speakers were from such groups, which shows that we’re on the right track. 

The rest of Dries’ keynote was dedicated to Drupal’s (at the time) upcoming release, the preparation for Drupal 9 and Drupal 7’s end of life. Drupal 8.7, released on May 1st, brought important updates such as a stable Layout Builder and JSON:API in core. With Drupal 9 just a little over a year away, it’s wise to start preparing for the upgrade now - one of the first things you can do, if you haven’t yet, is to upgrade from Drupal 7 to 8.

Read more

A Proposed Drupal privacy initiative and the Cross CMS privacy group.

With privacy becoming a key concern in software development, it’s important for Drupal as well as other CMS to focus on privacy. For this purpose, members of the Drupal, WordPress, Joomla! and Umbraco communities have formed a Cross-CMS privacy group whose goal is to establish a common set of principles that all these technologies can rely on.

In this blog post, Jamie Abrahams of Freely Give discusses the work of the Cross-CMS privacy group, listing a number of the group’s achievements since its formation last year, as well as some points on privacy not just as a legal, but an ethical obligation. Finally, he enumerates the goals of a proposed Drupal privacy initiative and concludes the post with next steps for the Cross-CMS privacy group to take.

Read more

Enabling headless Drupal Commerce while improving its core

In the next post on our list, Matt Glaman of Centarro (formerly Commerce Guys) writes about decoupling Drupal Commerce and how this can actually improve Drupal’s core. The basis for this post is the recent trend of decoupling, or “going headless”, which has been particularly talked about in the Drupal community.

As Matt points out, the work on the API-first initiative and decoupled Drupal is very beneficial to the modules in question and Drupal in general. He gives a few examples, such as a smooth coupon redemption via the Cart API module

This post, then, shows how a decoupled architecture and ecommerce can work perfectly well together. It finishes with some examples of successful uses of decoupled commerce, such as 1xINTERNET’s React-based solution which they presented at DrupalCon Seattle.

Read more

Learn to Theme with Hands-On Exercises

Since part of our mission at Agiledrop is spreading Drupal awareness and training new generations of Drupalists (we just held our second free Drupal course of the year this weekend), we also make it a point to promote other endeavors of educating people on Drupal. 

In this respect, we wanted to highlight this post by Amber Matz introducing Drupalize.Me’s new hands-on workshop for learning Drupal 8 theming. This is a 7-week course perfect for Drupal beginners who want to get practical experience with theming. At the end of each week, participants test their newly acquired skills through hands-on exercises accompanied by helpful videos. 

Another important novelty is’s partnership with Stack Starter, which enables web-based development environments and consequently allows participants to focus on learning rather than having to set up their own local environment. 

Read more

Drupal Association appoints Executive Director

We conclude April’s list with some important news for Drupal and its community. At the very end of April, Interim Executive Director Tim Lehnen announced in a blog post that the Board of Directors of the Drupal Association have appointed Heather Rocker the new Executive Director of the Association. 

As a former executive director of the Women in Technology foundation and CEO of Girls Incorporated of Greater Atlanta, as well as due to her experience in robotics and other fields, Heather is the ideal choice for leading the organization that aims to increase Drupal adoption and unite a diverse community of Drupalists. 

We’d like to give a warm welcome to Heather and join Dries and the entire community in the excitement of beginning the next chapter of Drupal under her guidance!

Read more

We hope you enjoyed our selection and were able to either revisit some of last month’s blog posts or learn something you may have missed. Tune in next month for an overview of the top Drupal posts from May!

May 13 2019
May 13

I’ve been working on a Drupal 7 to 8 migration of content and I encountered in the source body fields a bunch of tables which had a class that styled them in a certain way. One of the requirements was clearly to port the style but improve it using the Bootstrap tables styles and responsiveness. What to do, what to do.

In the source file I was encountering something like this:

<table class="some-class">...</table>

Which you can argue is not that bad, it only has one class on it and an external style does the job. But obviously it would be better if the stored data didn’t even have that class. So then in the migration I could just kill all the table classes from the body field and apply those stylings externally (all the tables inside the body field). This is a first good step. But what about Bootstrap?

I needed something like this instead to pick up Bootstrap styles:

<table class="table table-sm table-striped table-hover">...</table>

So to make the tables show up with Bootstrap styles I’d have to step on my earlier point of not storing the table classes in the body field storage. Even if I could somehow alter the CKEditor plugin to apply the classes from the widget. And not to mention that if I wanted responsive tables, I’d have to wrap the table element with a <div class="table-responsive">...</div>. So even more crap to store. No.

Then it dawned on me: why not just store the clean table elements and then, upon rendering, apply the Bootstrap classes, as well as wrap them into the necessary div? After replying Hold my beer to my self-challenging alter ego, I went and I did. So I came up with this little number (will explain after):


namespace Drupal\my_module\Plugin\Filter;

use Drupal\Component\Utility\Html;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;

 * Makes the tables in the content show up using Bootstrap styling.
 * @Filter(
 *   id = "table_style_filter",
 *   title = @Translation("Table styles"),
 *   description = @Translation("Adds the necessary markup to tables to render
 *   them via Bootstrap styling."),
 *   type = \Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
 * )
class TableStyleFilter extends FilterBase {

   * {@inheritdoc}
  public function process($text, $langcode) {
    $dom = Html::load($text);

    $elements = $dom->getElementsByTagName('table');
    if ($elements->length === 0) {
      return new FilterProcessResult(Html::serialize($dom));

    /** @var \DOMElement $element */
    foreach ($elements as $element) {
      $classes = explode(' ', $element->getAttribute('class'));
      $bootstrap_classes = [

      foreach ($bootstrap_classes as $class) {
        $classes[] = $class;

      $new_element = clone $element;
      $new_element->setAttribute('class', join(' ', array_unique($classes)));

      $wrapper = $dom->createElement('div');
      $wrapper->setAttribute('class', 'table-responsive');
      $element->parentNode->replaceChild($wrapper, $element);

    return new FilterProcessResult(Html::serialize($dom));


So what do we have here? Well, it’s a Filter plugin that you can add to your text format and which processes the text before it’s rendered. And obviously gets cached after.

In the plugin annotation I used the type \Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE because this doesn’t seem to be skipped by core anywhere and its purpose is to generate HTML. Then I implement the process() method to achieve my goal. And I do this quite easily with the following steps:

  1. Find all the table DOM elements and return early if none are found
  2. Loop through all the table DOM elements, clone them and apply the classes to the clone
  3. Create a wrapper div DOM element with the Bootstrap responsive class and append the table element clone to it
  4. Replace the initial table DOM element with the new wrapper
  5. Profit

The return of the method needs to be a FilterProcessResult object that contains the HTML in the same format as the method receives it in. So I serialize the DOM object back into an HTML string and use that.

And that’s it. After clearing the cache you can add this to a text format and all the tables found in the content rendered using that format will be Bootstrap ready. And tables are just an example. Imagine all the possibilities you have to turn simple HTML tags into the markup required by your corner frontend framework. All the while keeping your data clean and not pissing off the developer that will have to migrate that content somewhere else or render it in some other place differently.

May 13 2019
May 13

Having a process to follow when it comes to website planning and development is essential. The following considerations factor into successful development. 


Choosing a Method

Choosing the one method that fits your project can be a daunting task. If you have your own development team, you have control how the process proceeds. If you are hiring a vendor, you need to ensure that you still have a say in the process.

With insight into the planning and development processes, you can help ensure your interests are protected.


Planning and Development Goals

Some goals reflect perfect-world scenarios. It’s important, however, to be prepared with a flexible and acceptable plan when the project falls short of perfection.

Perfect World

In a perfect world, you know every detail about the website you want built and can convey those requirements clearly and completely. In a perfect world, all those requirement details are correctly understood by the developers on your project and they quickly create a solution without any issues.

Reality Check

Unveiling every detail regarding the requirements before development starts, however, isn’t necessary to initiate the process. Document all you can. Sketch what you are envisioning: pencil and paper are fine. Be sure to convey requirements that are critical for you to accept the end product.

When you hand your list to your development lead, understand that the development team will already have strategies in mind as they listen to what you say. This can mean 

  • a speedy and efficient development process or
  • it can mean they are hearing what they want to hear and missing details that can suggest their past experiences might need to be adjusted.

Open and frequent communication between you, the site owner, and the development team is a key success factor.

Choosing a Methodology

Often, a proposal from a development vendor will communicate the process they will follow to deliver your site. Given the recent trends, you will likely see the word Agile in their text. Or, maybe your own people are eager to jump on this new way of executing the development process.

If the developers are well trained in one of the many Agile methodologies, this might be fine. However, that is often not the case. One of the most common misunderstandings about Agile methodologies is that detailed planning is not needed.

What are your options? Become informed. Recognize that 

  • development methodologies can be influenced;
  • methodologies can be tweaked to fit your needs; and
  • you are not limited to just one methodology.

Influencing Development Methodologies 

Over the last several decades, some developers focused on the best steps to programming a solution, while others focused on creating programming languages that would make development easier and faster. Together, these two paths have created opportunities in the software development world. Among them:

  • Rapid application development using object-oriented languages and reusable functions that no longer rely on a developer to write and rewrite the code for frequently used website functionality. 
  • Creation of frameworks that, with specific coding functions, allow for the development of common and unique website applications.
  • Development of prepackaged systems designed to meet common website requirements out-of-the-box, requiring less experience and less time to stand up a site.

Each scenario is open to the use of Agile development processes that can flex, depending on the language, system, and/or requirements.

Will your project be developed from scratch or will your team use an out-of-the-box solution? Ask what the chosen strategy means for your process.

Tweaking Methodologies

Let’s take a brief look at what this means. Agile refers to a manifest of software development principles. There are several Agile methodologies that have been designed based on these principles, but they are not all the same or all-inclusive.

If any methodology does not fit your needs, you can make adjustments: add in tasks of another methodology, rearrange steps. Look at the development process being proposed and simply change it fit your resources, your requirements, and/or the way your team works.

Mixing Things Up

Sometimes tweaking isn’t enough.

Have you ever built a house? If not, you can probably imagine a few of the details such as the need for an approved architectural plan. In other words, a blueprint. The blueprint goes beyond requirements. It conveys how the requirements will be met.

There are reasons why the process used to construct of a house works.

  • Pre-approved plan
  • The ability to identify resources and estimate cost
  • A means to create a construction schedule

These three reasons help prevent scope creep and cost overruns. However, the delay of implementation of the requirements this can cause can has been troublesome for many. For instance, it can cause outdated technology to be used when coding finally starts--hence, the need for a development methodology that can start sooner and flex with changing technology.

Mixing it up means, taking the best aspect from the process used by the construction industry, which is a Waterfall approach and combining it with an agile development strategy.

Waterfall the What

Given the options in software today -- reusable functions, frameworks, pre-packaged systems -- it’s easier to identify a coding strategy for a website before the requirement details are identified. Returning to the house construction example, it’s like planning your new house based on pre-defined and pre-built modules that can be put together to create the house of your dreams.

A website is no longer a totally unique product from other websites. Starting with a blank page as if it has never been done before can be a waste of time. This means, using a waterfall approach to collect detailed requirements and design is a viable option.

Create a blueprint of exactly what you need. Participate in decisions regarding the various modules available to implement the features you need. Don’t rely on blind faith that the development team is going to choose an implementation or coding strategy that works best for you.

Agile the How

Next, implement the blueprint. An agile development methodology is still an appropriate choice, given our Waterfall beginnings. Let’s explore this switch in methodology.

The Agile-based Scrum methodology is used frequently. It utilizes Sprints where portions of the website are developed and then reviewed before proceeding to the next Sprint. With this approach to implementing the blueprint, three things are made possible:

  • The development team can plan how to implement the blueprint.
  • They have an increased chance of creating the correct solution.
  • If a review reveals an issue or something was missed during the creation of the blueprint, there is still time to make an adjustment in the development process to accommodate.

With this mixed approach, you don’t have to wait until all requirement details are in place. Assuming the use of a pre-packaged system such as a content management system, the development team can get started with some of the primary functionality identified early in the requirements and design steps such as:

  • E-commerce
  • Multilingual
  • Multi-site (e.g., more than one site using the same code-base)
  • Third-party system integration
  • Multiple levels of content access.

Given the nature of today’s coding options, take the time to plan the details of your website to help reduces surprises and restarts later. Then, be flexible. There is always a chance that a review of the development process can reveal required changes.


All methodologies have their strengths and weaknesses, especially when, for instance, trying to apply a methodology designed for hand-coded project versus a methodology designed to take advantage of pre-existing code bundles, such as content management systems.

Promet Source offers a depth and breadth of expertise in collaboratively determining the best methodology, based upon your distinct goals and circumstances. Our workshops are an excellent opportunity to understand the impact of process of design and to ensure that your project is positioned for success. 

Contact us to learn more about Promet’s distinct approach to ensuring successful implementations or to schedule a workshop.

May 13 2019
May 13


We live in an age of Drupal complexity. In the early days of Drupal, many developers would have a single Drupal instance/environment (aka copy) that was their production site, where they would test out new modules and develop new functionality. Developing on the live website however sometimes met with disastrous consequences when things went wrong! Over time, technology on the web grew, and nowadays it's fairly standard to have a Drupal project running on multiple environments to allow site development to be run in parallel to a live website without causing disruptions. New functionality is developed first in isolated private copies of the website, put into a testing environment where it is approved by clients, and eventually merged into the live production site.

While multiple environments allow for site development without causing disruptions on the live production website, it introduces a new problem; how to ensure consistency between site copies so that they are all working with the correct code.

This series of articles will explore the Configuration API, how it enables functionality to be migrated between multiple environments (sites), and ways of using the Configuration API with contributed modules to effectively manage the configuration of a project. This series will consist of the following posts:

Part 1 gives the background of the Configuration API, as well as discusses some terminology used within this article, so it's worth a read before beginning this article.

Active configuration is in the database

In Drupal 8, configuration used at runtime is stored in the database. The values in the database are known as active configuration. In Drupal 7, configuration was known as settings, and stored in the {variable} table. In Drupal 8, configuration is stored in the {config} table. The active configuration is used at runtime by Drupal when preparing responses.

Configuration is backed up to files

The Configuration API enables the ability to export the active database configuration into a series of YML files. These files can also be imported into the database. This means that a developer can create a new Field API field on their local development environment, export the configuration for the new field to files, push those files to to the production environment, then import the configuration into the production environment's active configuration in the database.

The configuration values in the database are the live/active values, used by Drupal when responding to requests. The YMLfiles that represent configuration are not required, and are not used at run-time. In fact, in a new system the configuration files don't even exist until/unless someone exports the active configuration from the database. The configuration files are a means to be able to back up and/or migrate configuration between environments. Configuration files are never used in runtime on a site.

Configuration architecture

Let's look at the Configuration API on a more technical level, using a real-world example. The Restrict IP module allows users to set a list of rules that whitelist or blacklist users based on their IP address. Upon visiting the module settings page, users are presented with a checkbox that allows them to enable/disable the module functionality.

From a data standpoint, checkboxes are booleans; they represent either a true or false value. When exporting the configuration of a site with the Restrict IP module enabled, the relevant configuration key will be saved with a value of either true or false to a .yml file. Modules are required to define the schema for any configuration the module creates. Developers can look at the configuration schema declarations to understand what file(s) will be created, and what values are accepted.

Modules declare the schema for their configuration in the [MODULE ROOT]/config/schema directory. In the case of the Restrict IP module, the schema file is restrict_ip/config/schema/restrict_ip.schema.yml. This file contains the following declaration:

  type: config_object
  label: 'Restrict IP settings'
      type: boolean
      label: 'Enable module'

Schema declarations tell the system what the configuration looks like. In this case, the base configuration object is restrict_ip.settings, from the first line. When this configuration is exported to file, the file name will be restrict_ip.settings.yml. In that file will be a declaration of either:

enable: true


enable: false

When the file restrict_ip.settings.yml is imported into the active configuration in another environment's database, the value for the enable key will be imported as defined in the file.

On top of this, enabled modules are listed in core.extension.yml, which is the configuration that tracks which modules are enabled in a given environment. When the Restrict IP module is enabled in one environment, and configuration files exported from that environment are imported into a different Drupal environment, the Restrict IP module will be enabled due to its existence in core.extension.yml, and the setting enable will have a value of either true or false, depending on what the value was exported from the original environment.

Note that if you were to try to import the configuration without having the Restrict IP module in the codebase, an error will be thrown and the configuration import will fail with an error about the Restrict IP module not existing.


In this article, we looked at how the Drupal 8 Configuration API works on a technical level. We looked at how active configuration lives in the database, and can be exported to files which can then be imported back into the database, or migrated and imported to other Drupal environments. In part 3 of the series, Using the API, we will look at how to actually use the Configuration API, as well as some contributed modules that extend the functionality of the Configuration API, allowing for more effective management of Drupal 8 projects.

May 12 2019
May 12

You may have heard of Drupal Check. You may wonder what in the world it is or how it even came to be. I realized this went from an internal research and development task for a product, to open source contribution and then to an essential tool in the march toward Drupal 9. The timeline from January to DrupalCon in April has been pretty crazy, and I realized I have never done a proper blog post about Drupal Check.

In January I wrote a blog post about the PHPStan Drupal extension for writing better Drupal code with static code analysis. That quickly exploded and turned into a way to detect code deprecations on the journey to Drupal 9. Then that also took off. The problem was setting up PHPStan and making it more automated and repeatable.

The result of this dive into PHPStan and Drupal?

  • The blogs and buzz formed the creation of the command line tool Drupal Check. I released Drupal Check as a way to have a no-fuss (spoiler alert: there was still dragons to be found) bundled configuration for running PHPStan against a Drupal site to check deprecations.
  • At MidCamp the contributors scanned 1,692 modules. 1,692. Dwayne McDaniel from Pantheon has summarized it on their blog:
  • There was the development of a new Drupal 8 version of the Upgrade Status module. The new Drupal 8 version uses PHPStan for in-site deprecation detection and reporting as a non-command line solution.
  • At DrupalCon Seattle, Dries even talked about Drupal Check in his State of Drupal presentation's How to Prepare for Drupal 9 section.

That is a lot that happened in just a few months.

How did this all get started?

Well, if you missed the news, Commerce Guys have rebranded as Centarro. At DrupalCon Seattle we unveiled Centarro Toolbox, a collection of SaaS products and support packages that help Drupal Commerce teams build with confidence. One of the products in our Centarro Toolbox is the Quality Monitor.

Quality Monitor performs proactive analysis on your codebase to detect problems in development before you deploy to production. It notifies you of necessary code updates and inappropriate API usage.

Drupal Check is, essentially, an open source version of Quality Monitor without our defined static analysis rules. I think this is awesome. We are an open source company. We are a team of seven. During the Driesnote, I realized four of us are in the Top 50 Contributors list. That's huge.

I love that our company's evolution is having an even more significant impact in open source than we expected.

Want to learn more about Centarro Toolbox? Check it out:

What does Drupal Check do?

Drupal Check is a customized runner for PHPStan. Instead of running PHPStan directly you run Drupal Check. It includes PHPStan, PHPStan's Deprecation Rules, and PHPStan Drupal and configurations for them. 

Here's an example of running it against the Address module and Drupal 8.8.x with just deprecation detection:

Here we go, again, with the default PHPStan static analysis rules:

Why is this useful? Because documenting configuration is hard. It also needs to be taught and takes time at contribution events. The configuration files are available at

However, here's a quick overview of what is setup when running deprecation checks:

    # Don't warn about rules not being executed.
        customRulesetUsed: true
        reportUnmatchedIgnoredErrors: false
        # Ignore things which cause problems.
                - */tests/Drupal/Tests/Listeners/Legacy/*
                - */tests/fixtures/*.php
                - */settings*.php
        # Ignore phpstan-drupal extension's rules.
                - '#\Drupal calls should be avoided in classes, use dependency injection instead#'
                - '#Plugin definitions cannot be altered.#'
                - '#Missing cache backend declaration for performance.#'
                - '#Plugin manager has cache backend specified but does not declare cache tags.#'
    # mglaman/phpstan-junit formatter (pre-checkstyle output)
                class: PHPStan\Command\ErrorFormatter\JUnitErrorFormatter
        - ../vendor/phpstan/phpstan-deprecation-rules/rules.neon

What can't Drupal Check do?

Drupal Check, via PHPStan, can bootstrap Drupal's code and inspect it for errors or deprecations, but it cannot fix code errors. At the end of April, Dezső Biczó wrote an interesting blog: Drupal 9: Automated Deprecated Code Removal - A Proof of Concept. The library announced in the blog post integrates Rector with custom code fixing definitions. It'd be interesting to add this functionality in Drupal Check.

The current features of Drupal Check are dependent on those in PHPStan. PHPStan's deprecation rules do not output the deprecation messages; it only identifies something that is deprecated. Better display of deprecation messages is an open feature request which I have been actively working on. Descriptions for deprecations are now available but do not support multiple line descriptions. If you're interested in following along, development is actively happening in this phpstan/phpdoc-parser pull request:

Dries, at DrupalCon Seattle, proposed the Driesnote. Drupal Check does not support JavaScript and Twig deprecations. Drupal does not even have a deprecation policy for JavaScript. I know there were discussions at DrupalCon Seattle, but I am not sure the status of that discussion. Twig has listed deprecations; however, I don't know if they are detected. There would likely need to be a Twig extension for PHPStan.

What's new since Seattle?

Here are some things which are new since DrupalCon Seattle.

PHPStan Drupal improvements:

Drupal Check improvements:

  • Test coverage! Added multiple CircleCI jobs to perform integration tests
  • Fix various installation problems (Phar, composer global require, cgr) which broke autoloading of Drupal (still to do: composer local install)

What's next?

The next significant feature is to finalize the deprecation description features. Being able to explain why something was deprecated and how to fix it (part of the required deprecation messaging for Drupal core) is vital. Things also get deprecated that cannot be immediately corrected. For instance, things deprecated on Drupal 8.7.x cannot be fixed in contributed modules until Drupal 8.7 is no longer supported, technically.

I would also like to fix some PHPStan issues. There is an "Easy fixes" milestone on the PHPStan project:

May 11 2019
May 11

It seems that I do a roughly annual update for ContribKanban and what I plan on doing with it. This year I evaluated its future and roadmap and how it can be more useful for the community at large.


ContribKanban has been hosted on one of my own DigitalOcean VMs for a while now. The project now has sponsored hosting from on their open source Lagoon platform infrastructure. This allows me to no longer need to worry about a server's maintenance and gives development environments for better testing and review.

I have also started to work on a command line tool for interacting with Lagoon:

Issue Collection Boards

Last year I built a way to create a board based on a collection of issues. It was inspired by Shawn McCabe 'smccabe' at AcroMedia who had a running spreadsheet of contrib tasks employees could work on. Issue Collection boards allow you to take issue IDs and make a custom board. They can be private, shared, or public. Issue collection boards can only be shared if given a link and are not browseable except from your user account page.

  • A public board allows anyone to edit and add issues.
  • A shared board can be viewed by anyone with the link.
  • A private board is for just you!

The Ofer Shaal 'shaal' of the Out of the Box Initiative has adopted ContribKanban as a sprint planning tool for each Drupal release.

See it over at

To create an issue collection board, you need an account on ContribKanban. My next goal is to improve the user experience for creating and managing these boards. It is very basic. 

Some of the things I would like to do:

Browser Extension

Stemming from the issue collection boards, I would like to make a browser extension that allows adding an issue while browsing to a board. I am imagining something like Pinterest or Noun Project. Click "Add to board" and select the board it should be added to or create an existing one.

I would also like the widget to display if an issue has already been added to a board.

OpenCollective and CodeFund

ContribKanban has always been a side project. It originated as a way to learn AngularJS. Then Drupal with VanillaJS. Then React with a Drupal backend. I have added ethical advertising by CodeFund to ContribKanban. CodeFund is an open source and ethical ad platform that funds contributors to the open source ecosystem.

I have also created a ContribKanban collective on Open Collective. This makes it easier to accept contributions and comes from recommendations from several community members.

To be honest, I work on ContribKanban very sporadically - partly because it works, and partly because I work on things which make an impact on my revenue. For instance, I worked on ContribKanban in April 2019, then the last activity was January 2019. Before that? October 2018. I would like to stabilize this and the funding options (funded or not) make me feel morally obligated to keep an active touch on the project.


One thing I would like to do is get a logo for the project: I have no idea. But it would be more useful since there is an Open Collective collective. 


Thanks for reading. Thank you to everyone who has used it and provided feedback. I'd love to hear how you're using ContribKanban.

May 10 2019
May 10

On several occasions clients have come to us asking for a form with a gated resource. They want the  resource (.pdf, .doc, .xls etc.) to be available to download after the user fills a form. In exchange for the visitor's valuable information, we provide them a file.

This is easily achievable in Drupal 8 with the Webform and Token modules.  At the time of creation of this blog post, I used Drupal version 8.7.0.

gated resource webform gif demo

Install modules:

Install the modules as usual. If you need more information on this topic, you can find it here.

Enable modules:

Enable Webform UI, Webform Node (which comes with webform) and the Token module.

  • Webform UI is not really required if you are creating your form via the yml editor, but provides a nice UI to generate and configure our form elements.
  • Webform Node provides a bridge between webform submissions and nodes. The description of the module reads: "Provides a Webform content type which allows webforms to be integrated into a website as nodes."
    For this example I will not be using the new Webform content type that the Webform Node module provides,I am using it because it allow me to bridge our webform submission with the node field tokens.
  • Token is going to get the gated file URL and name.

Configuring the content type:

For this tutorial I will use the Article content type, add a file field that we will name Gated file.

gated form add file field

I hide the field from the default display or any display you might use.

disable the field from the node display

By default the file will be disabled/not shown, therefore not accessible to site visitors.

Creating a webform:

I am going to create a basic webform with only two form elements: one for name and another one for email with standard validation.

* Important to add the form via: /admin/structure/webform, as a webform entity not as the new webform content type, so you can reference the form from different nodes.

Here is a screenshot of my simple form:

gated resource gated form screenshot

Referenced webform:

In this example I will be using an entity reference field to reference the webform we have just created, via the new field called Gated form (field_gated_form):

create a new entity reference to a webform

Then I create a node of type Article. 

You can see the gated file field and the gated form field highlighted in the following screenshot, also you can notice that I am referencing our previously created webform in the Gated form select

creating a node of type article with the gated resource and the form referenced

Creating a confirmation modal with the file exposure:

Because the file is not visible to the user, we will use the webform confirmation modal to expose a link to the file.

image displaying the settings for the webform

if you browse the available tokens at the bottom of the Confirmation message you'll see the following tokens:

If you need a deeper nesting look at /admin/help/token page, where you'll see all of the token values available per field.

example of token values available per field inside node

For the confirmation message I added the following HTML:

Here is your file:
 <a href="[webform_submission:node:field_gated_file:entity:url]" target="_blank">

We are using tokens to get the name and the URL of the field_gated_field, which is the machine name of our file field. Then we form a simple link (HTML a tag) that allow the user to download the file.

Webform in Drupal 8 is super flexible, easy to use and powerful. This is just a simple example of what can be achieved with a little bit of site building and a bunch of clicks.

This is not a secure way to protect files, anyone with the original link to the document will be able to see it and download it, but for some use cases is good enough.

May 10 2019
May 10

my site front page

[embedded content]

Many years ago I made my personal page on Drupal 7, as soon as Drupal 8 was released I have upgraded to this version. My personal site is just a page with my contacts and my blog. 

In truth, I do not always have enough time to write posts to my blog, as well as keep the core and modules up to date. Some times between the huge projects I have a frame to share my experience and to make some support tasks and improvements. 

So more than 99% of its life my personal site works as a simple static HTML site.

Does it make sense to use Drupal as a backend? 

Let's imagine the site is static at any time except the time when I want to edit it...

And it's possible with Tome. It's Drupal 8 module. You can get more information on the official site

Let me show you my personal site It's a static HTML site. I don't have the permanent version of this site either hosted somewhere or locally. But I have a private repository of my Drupal site with configurations and content in flat files. 

Tome module allows exporting configurations in .yml files and content in .json files as well as install Drupal with those files without operating with the DataBase dump.

I have decided to put some changes on the site. I need to get the site locally, log in Drupal admin, make changes and generate a new version of my static site. That's it.  

Cloning the site:

$ git clone [email protected]:vasilyyaremchuk/personal.git

It's my private repository, that I have forked from

Coming to the folder:

$ cd personal

If you've taken a look at you could find that there is no core folder there. You have to run 

$ composer install 

to get all necessary dependencies. 

Install the site with drush:

$ drush tome:install

Run a local server with drush:

$ drush runserver

Make some changes in the admin area. A new password to login in admin provided after the previous action.

If all changes were done, we can stop the server and generate a static site:

$ drush tome:static --uri=

Attention! Don't forget to set the basic URL of your production site, otherwise, you can get incorrect links that point to your local environment in some places of the static site.

Now you have a new static version of the site and you can deploy it on your hosting.

Don't forget to update the repository with those changes:

$ git status

You can see that one file with content is changed. Let me commit those changes:

$ git add .

$ git commit -m "content changes"

$ git push

Finally, you can delete the local Drupal 8 site:

$ cd ..

$ rm -R --force personal

May 10 2019
May 10

There is an ideal blend of usability and attractiveness — this is Media Library in Drupal 8.7 core. That’s what comes to mind when we see Drupal Media Library’s updated UI. Managing media on websites will now be easier and more enjoyable than before!

Drupal Media Library allows you to:

  • save photos, audios, tweets, local videos, remote videos from YouTube or Vimeo etc.
  • manage all items in the Library
  • easily add them to content at any time you wish

So welcome to take a closer look at how the new Media Library interface looks and works in Drupal 8.7.

Media Library’s new UI impresses the world

As soon as the demo video of the new Media Library UI was posted by Webchick yet in March, Drupal core contributor, it gathered many compliments from the Drupal community. “Brilliant,” “wonderful,” “amazing,” “totally huge” are just some of the feedback. It’s interesting to know what you will say, so welcome to leave comments!

A closer look at new Drupal Media Library interface in release 8.7

The Media Library works in pair with the Media module. To start using it, we enable both the Media and Media Library modules.

Drupal shows a warning about the experimental status of Media Library. The module is expected to be stable in Drupal 8.8 after a few fixes and adding WYSIWYG support.

Enabling Media and Media Library modules in Drupal 8.7

With these modules enabled, we can see that the site’s structure now has media types. There are five default and preconfigured ones (and it is also possible to add custom media types):

  • Audio
  • File
  • Image
  • Remote video
  • Video

5 media types in Drupal 8

It’s time to add some media of the available types. All media items will be stored in Media Library for further convenient use. You can add it in two ways:

  • from the admin dashboard “Content — Add content — Media.”
  • directly from the “Media” tab in “Content” where you will see the entire Media Library with all media that you have added.

Media Library new UI in Drupal 8.7

The new Media Library interface can display your media in the Grid view and in the Table view:

Media Library Drupal 8.7 table view

It is easy to filter and sort the media by various criteria, as well as select particular items to do actions with them (delete, publish, save, unpublish).

Media Library Drupal 8 selecting items

Adding media from Media Library to content

Here comes the most interesting part of managing media with the Media Library story — embedding media into content. In fact, it is not only content, but all fieldable entities (for example, user profiles or media itself).

To get this working, the basic necessary thing is to add a “Media” field to the desired entity type. Let’s add it to user account settings and call it “My pet's photos.”

Adding Media field to Drupal contentAllowed number of values will define how many items can be embedded.

Number of values in Media field Drupal 8

You need to select the media type for the field. According to the official documentation, it is completely legal to have multiple media types in the same field.

Selecting Media type for Media field in Drupal 8

Now, every time a new user account is created, it has the “Add media” button that brings in the Media Library interface. Media can be added in two ways (and even at the same time!):

  • You can select Media in the Library:

Selecting uploaded media from Media Library in Drupal 8.7

  • And you can bulk upload media from PC:

Bulk uploading media to Media Library Drupal 8

You can choose “Save and insert”, or “Save and select” to insert them later.

Selecting media from Media Library Drupal 8.7

Once inserted, the media items are displayed on the user account as the user’s favorite pet’s photos. And you can do the same with all kinds of media in all kinds of content.

Media added to user account Drupal 8.7

Enjoy the new interface for Media Library in Drupal 8.7

Well, the new Drupal Media Library interface in release 8.7 is really user-friendly, stylish, and classy. Managing media with it will be fun for content editors.

Our Drupal team is ready to help in configuring the Media fields for your website’s content, creating a custom media type to fit your business needs, and, of course, updating you to Drupal 8.7. Enjoy the newest Drupal features!

May 10 2019
May 10

Things seen here are configured there.

An elaboration on underlying considerations that make simple suggestions as this one not so simple after all.

An important consideration when deciding whether to “add something to core” is that generally speaking, core doesn’t do one-offs. The underlying principle is not “make it do X” but “make it possible to make it do X (and X2, X3,…)

Linking from a create context to a configuration context

In this particular case we have a proposal to link to the screen where you can add new content types from the page that lists available content types to create content with. Or, in url speak: on /node/add, put a link to /admin/structure/types. Or once more: on the screen that lists existing content types that you can create content with, add a link to the screen that lets you define new content types.

Notice the distinction between “create content of type X” and “define a new type of content Y”. The first is a content creation task, the second is a content definition task (in Drupal jargon usually captured under “site building”). This distinction then should clarify why a link to define a new content type should not use the “blue + button” pattern on a screen that is in service of a content creation task.

Back to the “no one-offs” principle. Where and how can we add a link of this kind? To answer that question we should look for possible patterns. Is there a more generalised definition for the type of problem that this single link to elsewhere wants to solve?

The example is: put a link to the content type definition area on the screen that lists already available types to create content with. Restated more generally: link to that area of the Drupal admin where the things on this screen are configured.

Connecting the dots is important

You know those links at the bottom of product pages in an online store: “people who bought this item also bought X, Y and Z”. In our case it’s more like “Things seen here are configured there.

I noticed a sort of similar pattern in the Android OS settings pages, where the screen ends with suggestions of related topics to the ones already shown. It’s a way to provide meaningful next places to go if the current page didn’t offer what you were looking for (and is of course a symptom of how many settings there are in the first place).

“Things seen here are defined there.

If we can find more examples of where this would be meaningful and helpful then we might have a good case for introducing a new user interface pattern. See image for some initial examples.

May 10 2019
May 10


We live in an age of Drupal complexity. In the early days of Drupal, many developers would have a single Drupal instance/environment (aka copy) that was their production site, where they would test out new modules and develop new functionality. Developing on the live website however sometimes met with disastrous consequences when things went wrong! Over time, technology on the web grew, and nowadays it's fairly standard to have a Drupal project running on multiple environments to allow site development to be run in parallel to a live website without causing disruptions. New functionality is developed first in isolated private copies of the website, put into a testing environment where it is approved by clients, and eventually merged into the live production site.

While multiple environments allow for site development without causing disruptions on the live production website, it introduces a new problem; how to ensure consistency between site copies so that they are all working with the correct code.

This series of articles will explore the Configuration API, how it enables functionality to be migrated between multiple environments (sites), and ways of using the Configuration API with contributed modules to effectively manage the configuration of a project. This series will consist of the following posts:

  • Part 1: The Configuration API
  • Part 2: How the API works (coming soon)
  • Part 3: Using the API (coming soon)
  • Part 4: Extending the API with contributed modules (coming soon)
  • Part 5: Module developers and the API (coming soon)


Before we get started, let's review some terminology. A Drupal project is the overall combination of the core codebase and all of the environments that are used for development of the project. An environment is a copy/clone of the website that is accessible at a unique domain name (URL). When most users on the web think of a website, they think of the environment accessed at a single URL, like or These URLs are the entry to the live production environments for these websites. However, in addition to the production environment, large projects will have additional environments, where code is developed and tested before being deployed to the production environment. The combination of these environments make up the project. Drupal 8 is built to enable developers to migrate functionality for a project between environments, using the Configuration API.

Components of a Drupal environment

What makes up an environment of a Drupal project? In other words, when making a 'copy' of a Drupal site, what are the elements that need to be migrated/copied to create that copy? A Drupal environment consists of the following elements:

  1. Codebase: At the core of any Drupal system is codebase that makes up the 'engine' that runs Drupal. The codebase of any Drupal site consists of Drupal core, modules (both contributed and custom), and themes (again, both contributed and custom). The codebase is a series of files, and these files provide the functionality of a Drupal site.
  2. Configuration: Configuration is the collection of settings that define how the project will implement the functionality provided by the codebase. The codebase provides the abstract functionality to create things like content types, fields and taxonomies. Developers configure a Drupal site through the admin interface, to create the actual content types, fields, and taxonomies used in the project, that will allow end-users to do things like create pages or make comments. As developers build out the functionality of the project through the admin interface, the settings they choose are saved as the configuration for that environment. Configuration is environment-specific, and the Configuration API provides a means of migrating configuration between environments.
  3. Content: Content is the data on a site that is specific to the given environment. Content may be created by end-users, or by content admins. While content, like configuration, sometimes needs to be migrated between environments, content should be considered environment-specific. The Migrate API provides a means of migrating content between environments.
  4. Uploaded files: Most Drupal projects will have files uploaded as content. These are not part of the codebase that provides the functionality of the system, rather they are files that are to be provided to end users. Examples are images, audio/video files and PDFs.
  5. Third party technologies: Drupal 8 is a hub framework, built to integrate with 3rd party libraries, APIs, softwares, and other technologies. For example, a project may use a 3rd party CSS/JS framework, or swap out the default database caching backend to a Redis caching backend, which provides significant performance improvements. While these third party technologies are not part of Drupal, often the technologies will be required in each environment for the project to run.

The above five elements together make up a Drupal environment. The environment is a fully-functioning Drupal copy (instance), with its own configuration and content. Each environment will have its own domain (URL) at which the environment can be accessed.

Types of environments

Typical projects these days will have a minimum of three environments:

  1. Production environment: The main live environment that end users will use.
  2. Staging environments: One or more environments on which site owners can test new functionality or bug fixes before they are deployed to the production environment.
  3. Development environments, where new functionality can be developed in isolation. Development environments may be publicly accessible, or may only exist on a developers computer, not accessible to the outside internet.

Content and configuration - both stored in the database

A major issue that existed with all versions of Drupal core up to and including Drupal 7, was that content and configuration were both stored in the database, and there was no way to separate them. This made it difficult to manage configuration changes, such as adding a field to a content type, between multiple environments. There was no way to export the configuration for that single field, so to ensure consistency full databases were migrated. The problem is that database migrations are an all-or-nothing venture; when migrating from one environment to another, the entire database of the source environment overwrote the entire database on the target environment, meaning all content and configuration was overridden on the target environment.

This opens up a problem though. Imagine this scenario:

  1. A developer copies the production database to their local computer.
  2. Someone creates new content on the production environment, that becomes part of the database.
  3. The developer adds a new field on their local environment.
  4. The developer migrates their local database to the production environment, overwriting all configuration and content on the production environment.

With the above scenario, the new field created on the developer's local environment is now on the production environment, however the content created in step 2 is overwritten and lost. As such, the above process is untenable. Databases cannot be migrated 'up' (to production) after a site has gone live. They can only be migrated 'down' (from production).

To overcome this problem, a common way to make changes to configuration before Drupal 8 was to make configuration changes on the production environment, then copy the production environment's database down to the other environments. For example, if a developer was writing code that depended on a new field, rather than create the field on their local development environment, they would create the field on the production environment, then copy the production environment database down to their local development environment. Now the field exists on both the production environment as well as their development environment. This solution works, but is akin to killing a mosquito with a sledgehammer - it's overkill. The developer did not need the whole database, only the configuration for that single field. And any changes they had already made in their own environment, such as content for testing, is now wiped out with data from the production environment.

While this process worked (and still does continue to work for many projects), it was not ideal. It led to issues where database migrations had to be coordinated with clients and other developers to ensure that it was safe to wipe out content or configuration someone else may still be working with.

The Configuration API

The Drupal 8 Configuration API was created to overcome the above issue, so that developers could migrate configuration - such as Field API fields, content types, and taxonomies - between environments, without having to overwrite the entire database. It decoupled configuration from content. To understand how it makes things better, let's again review the components of a Drupal site, and the storage mechanisms behind them:

  • Codebase (files)
  • Configuration (database)
  • Content (database)
  • Uploaded files (files)

With the Configuration API, configuration can be exported into files, and these files can be migrated between environments and imported into the new environment. This means that we can now migrate individual items of configuration without having to overwrite the entire database. The Configuration API decouples configuration from content. In the next parts of this series, we will explore how the API work

Note 1: the Drupal 7 Features module essentially does the same thing, and though the methodology is different, many of the concepts in the following articles will be relevant to that module as well.

Note 2: the Drupal 8 Migrate API was developed in parallel to the Configuration API, allowing for content also to be migrated, again without overwriting the entire database.


In this article, we looked at an overview of the Configuration API to understand what it is, and why it was created. After reading this article, you should have an understanding of what a Drupal environment is, and what it consists of. You should understand that in Drupal 8, configuration is stored in the database, but can be exported to files, which can then be used to migrate content between environments. In Part 2 - How the API works, we will take a closer, more technical look at how the API works, and in Part 3 - Using the API, we will discuss how to use the API, and some contributed modules that extend its functionality.


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