Upgrade Your Drupal Skills

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

See Advanced Courses NAH, I know Enough
Sep 21 2020
Sep 21

There are two kinds of instances that we never forget in our lives; one is when we hysterically cry, and the other is when we hysterically laugh. The other moments in our lives are bound to lose their place in our memories, but not these. Have you ever forgotten a time when you laughed like crazy or cried like a baby? You know I am right. 

These moments are not necessarily associated with your personal lives, these can be related to the professional and commercial experiences you witness at any point. Now, I would not be talking about the upsetting consumer encounters you might have had, since I do not want to dampen your day. Instead, I will be talking about the kind of experiences that make you go all smiles.

We smile because we are happy or smile because someone has cracked a funny joke. Jokes do not have to be limited to social gatherings and Whatsapp messages; they can transcend to the world of web design. Yes, you read it right. Today, jokes, or shall I say humour has become an integral part of web design. Humour has the potential of taking an ordinary website and making it extraordinary. 

If you don’t believe me, continue reading, and by the time you will finish, I am sure your opinion would have changed.

The Importance of Humour 

Humour is an element of our lives that makes it brighter and livelier. People look forward to reading jokes, making jokes and laughing at their hilarity. You know you like those PJs as well, they might not make any sense, but they can be funny. Stepping a little up from the PJs, and moving on to web design. Humour has become extremely important in the world of web designers. It can make or break their designs, it is that powerful. Let us understand why.

If someone is funny and quirky, you will instantly like him or may even be drawn to his or her funniness. Am I right? The same is true for web designs. A user experience that is instilled with enlightening as well as humorous elements is going to be a hit. Humour has the potential of contributing to sales by highlighting a product or service’s attractiveness and making you drawn to them. It does so by giving them a genuine personality. Don Norman believes the same and has vocalised his beliefs in his book, Emotional Design - Why We Love (or Hate) Everyday Things.

After a customer is lured in, you have to keep in mind his needs in order to gain his loyalty. These needs start with the functionality of a product, then move onto its reliability, after becoming satiated with the usability of the same, these needs are finally placated with the pleasure factor. If a product is pleasurable to the user, only then can it be deemed as a success. And you must know that pleasure and humour are the best of friends.

The image shows a pyramid with four segments, pleasure, usable, reliable and functional, describing the hierarchy of needs.Aaron Walter's pyramid of emotional design | Source: Treehouse

Humour is bound to create positive emotional stimuli in all of us. When a user experiences such a response from a web design, there is a high likelihood that he will develop a sense of trust in the same. And that is the reason why humour is important in web designs and should be implemented, but with caution. Read more about the link between decision science and web design to understand how to make design decisions. 

The Subjectivity of Humour 

Humour is a kind of quality that is possessed by everyone, yet everyone has a different notion of it. What may be funny to me, can be offensive for you and nobody can say that our notions about it are wrong. We just have a different perspective.

So, the web designers have to keep this in mind, you have to understand your audience before committing to any humorous elements you want in your designs. 

A web developer has to first comprehend the subjectivity of humour. Yes, every joke is not going to be funny for everyone, but it can be funny for the majority of the people and that should be the ultimate aim. Your jokes need to be understood by most people visiting your site, even if you are using innuendos, they should not be indecipherable. 

The image shows a cartoon with a confused expression, to symbolise the subjectivity of humour in web design.The confused expression is not the reaction that the web developer aims for.

Zeroing in on your target audience will help a great deal in this feat. To help you catch my drift, I will tell you something that you must already know. And that is the fact that the eastern and western cultures are vastly different. So, the kind of jokes these two people find funny are also different. You can joke about celibacy in the west and people would laugh, but if you joke about celibacy in the east, where the Buddhist Monks preach it, you will not get the same reaction.

So, identifying your target audience is crucial, as it would decide whether your humour would hold a punch or not. The subjectivity, the cultural intonation and the contextual meaning of a joke are to be mastered before using it into your designs. 

The image shows a stick figure with a sombre expression, depicting the importance of contextualisation in humour.Source: 9GAG

Here the second phrase, when used in different contexts has very different meanings, and this kind of contextual differences cannot happen in your web design.

The Categories of Humour 

Humour is something that is funny, something that makes us smile, laugh and roll on the floor laughing or ROFL, if you please. I like to believe that I have a great sense of humour, I laugh at things that are not even worth laughing at and a person with that kind of humour must know everything about it, right? But that isn’t the case with me, I did not know that there were seven categories of humour. Did you? For me funniness, satire and irony all fall into the same category, being one and only one. 

So, getting to know the seven varying diversifications of humour in web designs was quite enlightening for me. I hope it is the same way for you.

Comparing with comedy 

Humour by comparison is the most commonly used way of making boring elements on a website become interesting and refreshing. Going through a product’s specifications becomes a chore, if you do not find something funny in the never ending description. Making comparisons that are not only funny, but also serve the purpose of highlighting what the web designer wants is a tactic that could never go wrong.

Personifying with cartoons 

Do you remember the early 2000s? Did you use Microsoft Office then? If you did, you must remember Clippit or Clippy. It was a cartoon paper clip that served as an office assistant. I thought it was cute, funny and somewhat useful; however my belief was not very popular. The point I am trying to make here is that the addition of an animated personification can add character to your web content, giving the customer a break from the monotony of the content. A mascot is a great way to do just that.

The image shows an animated paperclip used in web design as humour.Source: Wikipedia 

Exaggerating with hilarity 

With exaggeration, we take a normal incident, magnify it in our minds, and relay the same with a lot of more severeness than it actually had. It is like saying that you were attacked by a mammoth sized dog, when in actuality a pug barked at you. If you know something is being exaggerated, then it becomes quite hilarious. 

Pun with fun 

Pun is something we are all familiar with, and enjoy a great deal. So, why not use it to make your website all the more interesting. The thing about the usage of pun is that it is quite tricky. It can very easily go into the territory of offensive, if it is not used properly. So, tread lightly when using it in your web design.

Silliness with funniness

Have you ever watched the American TV show Friends? If you have, what do you think of Phoebe? Do you find her funny? I personally do, she is the kind of funny that is silly, yet hilarious. You would never be offended by her character. So, taking inspiration from Phoebe’s hilarity and silliness and implementing it into your website could be a genius stroke. 

Surprise with laughs

Getting pranked is the best kind of surprise, at least to me it is. Being ambushed by a horrifying ghost in a funny video is bound to make you laugh until you cry with your heart racing at 100 km an hour. You must have experienced it sometime. Now, you tell me would an unexpected element of humour not be appreciated in a webpage that could otherwise be boring?

Jesting over the Easter Egg

As finding the easter egg amidst bunnies is no easy task, the same way the humour denoting with the same name is also not easy to find. This one is hidden and that is why it is a gem, when you finally get it. Web developers have been increasingly making use of easter eggs as an element of humour in their web designs and the users have been appreciating the hunt. Have you ever searched the meaning of the word askew on Google? Before you get on to the meaning, you would find something that would give you a clue as to the literal meaning of the word. Your beloved Google would become skewed itself. Is this not clever?

The image shows Google's skewed search page.The skewed screen on your computer when searching the term askew.

An amalgamation of all of these with subtly can make your website’s experience a memorable one for every user to come.

The Implementation of Humour in Web Design 

The thing to remember about humour is that if you have to force it, it is bound to lose its intensity over the audience and your joke would fall flat. Under no circumstances, do we want that. Humour has to seem spontaneous and natural, only then can we enjoy its full magnitude. 

To help you do the same, I will tell you some of the insider secrets of web developers and the way they make humour work for them.

Introducing yourself with a flair

Every website is going to have an About Us page, this is one area in a website that the content creator can create any way he wants to. So, if you want the customer to remember everything about you, you have to make yourself interesting enough to be remembered and humour helps in that. You can talk about history with light heartedness, you can talk about your struggles with humour rather than seriousness, and you can present your team in a fun and refreshing way. See the following example from Lessfilms website:

The image shows funny pictures of a company's team on their webpage.This one hit the mark with the introduction of its employees. The red guitar stole the show. | Source: Less Films

Making boring, yet crucial information interesting 

Webpages are supposed to have a lot of information and a lot of information can become quite boring to peruse through. Since the information has to be given to the user, what can be the solution here? The answer is simple, humour. Adding humour, in all of its categories can make your website content speak through and serve its intended purpose.

A web design with a green backdrop is shown with an ongoing chat on the side.A customised chatbot message. | Source: Lazy Gardener 

Covering up your mistakes

There are often times when your users face problems while surfing through the website. More times than not these problems are frustrating and annoying to the point that they think about going back and looking for something else entirely. Can this annoyance be overcome with humour? Let us see if it works for two of the most annoying things.

The 404 error 

When you get to know a page you were looking for does not exist anymore, you will become frustrated. Here a joke is bound to alleviate some of that. Look at the picture below, did it not make you smile just a tad bit?

A crying cartoon is depicted in the image with the 404 error often seen on websites.

Slow loading 

Apart from the page not found error, when a web page takes ages to load, that also becomes quite a nuisance for the user. There might be a genuine reason for the slow loading, but the problem would still be there, so what does the web developer do? You would use humour in a very subtle way to make the user wait a little longer and see what he had intended to.

A snail is shown in the picture to represent the slow loading process.

Narrating a story 

Sometimes storytelling becomes a necessary part of the web design. It is important to make your point come across in a simple, yet comprehensive manner at the same time making it relatable to the audience. Now, when you add a dose of funniness in your story, it would accentuate your point even more.

Creating a mascot 

A mascot is any object, human or otherwise that is bound to bring you luck. And web developers need all the luck they can get, like most of us. So, creating a website with a funny mascot that keeps popping up in regular intervals to let the users know whatever they want is a great way to make your website’s experience a little more eccentric than dull.

An animated boy is shown eating a burger as an innovative and funny web design..The cute kid with that appetising burger is enough to start a craving.

Baiting with humour 

You must be familiar with the term bait, it basically means to lure people in by enticing them with what you have. Have you ever read something like, “If your dog does this, here is what it means.” You might not even have a dog, but you will be inclined to know what the dog actually does. This is what bait means and it can increase the traffic on many websites.

An instruction is written in white on a blue background, often seen in webpages..If it were me hovering over the click button, I would certainly press it and find out what is inside.

The Avoidance of Humour 

Just knowing where and when to use humour is not sufficient, you should also know when to avoid it. Humour can only work its charm when it is used appropriately, incongruous use of humour can lead to devastating effects. You can’t be cracking jokes at a funeral, right? Right!

Here are three ways to avoid humour taking a toll on your website’s traffic.

Unnecessary implementation

You have to assess the right place and time of using comical aspects in your web design. Using comedy in a serious situation can have serious repercussions, one of which is a brutally harsh feedback from a customer and we do not want that. 

A lady can be seen covering a mouth in an oops reaction.

Seeing something like this on a retail website when your transaction failed and money got deducted from your account is bound to make the customer livid. So, to all web designers, do not go this route.


This one is as insulting as it is inappropriate, if you want your website to be user friendly, I would advise to stay away from confirmshaming. This is a form of humour that uses guilt to make the customer do its bidding and that is just wrong. Telling someone that they are fat and should join your 15-day detox program is not the right approach from any perspective. 

There is a white background with information and instructions for a task to be down by the user.This image is a prime example of insulting and goading a customer in clicking, since nobody would want to be unhealthy.

Making it a distraction 

Using humour in a way that it distracts the customer from what you and your website is all about is probably not the aim. So, when you use comedic elements in your design, try to ensure that it is clearly understood by all the audiences or at least your target audience and it aligns with your website’s purpose. You do not want to leave any room for misinterpretation. This is because if a product is misinterpreted and the consumer does not get what he thought he would, he is definitely going to regard you as a liar.

The Backlash of Humour 

After telling you the ways to avoid humour getting in the way of your success, I want to tell you a story about the negative repercussions of the wrong kind of humour.

Pepsi is a world renowned beverage company, second most successful in the world in its arena. Pepsi is also famous for creating inspiring and unique ad campaigns. They are usually a hit, but their 2019 campaign missed its mark by a long shot. The only reason was the fact that they had taken a serious situation and made light of it. 

[embedded content]

As you can see in the video, a bottle of Pepsi was all it took to restore peace in the world. Do you also see the bizarreness in this idea? On top of this, the stark resemblance to the Black Lives Matter campaign did all the more damage to the company, the tweets are proof that. Pepsi had to retract the ad and issue a public apology. 

Therefore, it is advisable to avoid making humorous content on serious topics than making it and apologise later. Although it was a video commercial, the implication will be the same for website design as well. Nobody will tolerate humour on a subject they are sensitive about. The fine between humour and offensiveness has to be made very clear before implementing humour in your designs. Otherwise the backlash is going to be too brutal to bear. Take a look at how diverse design teams can help make better design decisions.

The Bottom Line 

Using humour to make your website’s experience more enjoyable has indeed become a trend; however, content creators and web developers have to understand that humour can just as easily turn deleterious as easily it can turn meritorious. 

Humour in web design is like a flaming ball of fire, the appropriate usage can make it as powerful as Goku’s dragon balls, and inappropriately used humour can turn your design into ashes; metaphorically speaking of course. You have to have a balance, do not go overboard and do not use it so little so that it becomes non-existent. When you attain that balance, your web design would become one to watch out for, trust me.

Sep 21 2020
Sep 21

Currently, in Drupal’s admin toolbar, the Webform module is listed under ‘Structure’.

Webform module is listed under ‘Structure’

If you have installed the contributed Admin Toolbar module, which adds drop-down menus to Drupal’s admin toolbar, it’s relatively easy to access Webforms from any page on your website.

Someone recently asked me why ‘Webforms’ is listed under ‘Structure’ and not ‘Content.’

There are two immediate explanations as to why I chose to list ‘Webforms’ under ‘Structure.’

First, it’s much easier to add links to Drupal’s ‘Structure’ section because it provides a dedicated overview page. Drupal’s ‘Content’ section, on the other hand, displays a tabbed user interface to manage content, comments, files, and media. This tabbed interface does not easily support multiple levels of administrative pages.

Secondly, webforms are configuration entities that create webform submissions, which are content entities. This pattern aligns with how ‘Taxonomy’ and ‘Content types’ work, and they are listed in Drupal’s ‘Structure’ section. Generally, the ‘Structure’ section includes things that a site builder configures yet does not frequently update. The ‘Content’ section is where content editors continually create and update content. For a more in-depth explanation about Drupal’s admin tool, you can learn more about working with the toolbar.

For small websites with just a few webforms, like a contact or registration form, it makes sense to list ‘Webforms’ under ‘Structure’ because a site builder would configure these types of webforms once and not frequently update them. As organizations have started leveraging the Webform module to build applications and event registration systems, having ‘Webforms’ nested under ‘Structure’ makes less sense. For example, content editors that are only allowed to manage content and webforms would have the ‘Structure’ section visible with only the ‘Webforms’ sub-menu item.

the ‘Structure’ section visible with only the ‘Webforms’ sub-menu item

The above screenshot is awkward and confusing. Yes, one immediate solution is to move the ‘Webforms’ into the ‘Content.’ But the fact that the tabbed user interface in the ‘Content’ section is not able to support the Webform module’s multi-level tabbed interface remains. Let’s also not forget the question, ‘Are Webforms content, configuration, or both?’.

The problem is that some organizations are building more than just a few webforms, and there are instances where webforms are as crucial as content. The solution is to make ‘Webforms’ a top-level menu item with a dedicated icon under the ‘Manage’ section within Drupal’s admin toolbar. To further improve the user experience, I have also added sub-level menu items to ‘Webforms’ section, making it even easier to manage any aspect of the Webform module via the Admin Toolbar module’s drop-down menus. Finally, when ‘Webforms’ is moved out of the ‘Structure’ section, all administrative paths will begin with /admin/webform instead of /admin/structure/webform.

Moving the 'Webforms' menu item out of the 'Structure' section

This is a significant UI/UX change that may be appropriate for an organization’s Drupal site. Like many advanced features in the Webform module, I decided to make this a configurable setting via /admin/structure/webform/config/advanced. By default, the Webform module will still place the ‘Webforms’ menu item under ‘Structure’. For websites that are doing a lot with webforms, they can now easily move the ‘Webforms’ menu item next to ‘Content.’

For advanced Drupal site builders and developers, you can also move the ‘Webforms’ anywhere you want, including under ‘Content’ using Drupal’s menu system. My solution makes it easier for people to check a box and promote ‘Webforms’ in Drupal’s admin toolbar.

I like this new feature because it acknowledges that organizations can use the Webform module to build simple content forms or rich applications. In some cases, the Webform module is a key part of an organization’s Drupal installation, with lots of users collaborating to build webforms and manage submissions. This feature allows organizations to decide where the 'Webforms' section should live within their organization Drupal administrative interface.

In short, this feature represents the power and flexibility of the Webform module - small or large Drupal sites can create simple or complex webforms, and they can decide precisely how they want to integrate the Webform module into their websites.

Lately, there has been a lot of cool things. happening with the Webform module and you can learn more by following my blog at jrockowitz.com and watch videos on my YouTube channel.

Almost done…

We just sent you an email. Please click the link in the email to confirm your subscription!


Sep 21 2020
Sep 21

In his Drupal4Gov webinar Using tools and Git workflow best practices to simplify your local development, Greg Lund-Chaix, Senior Infrastructure Engineer at Tag1, talks about some of the ways that teams struggle when they become successful and need to learn to scale. He recommends using some basic tools to make your workflow easier. The right tools in your environment can prevent big problems down the line with merge conflicts, code committed to the wrong branch, or other mistakes.

Git is one of the most common version control systems in use today. With a few tools, and a few best practices, you and your team can make your local environments easier and safer to use.

[embedded content]


Learn to rebase. When you’re working on a feature it might take you a few hours, to several days or weeks. The longer you take working on a branch, the more chances your branch is out of sync with the rest of the code base. The cleanest way to prevent problems is to rebase. Rebasing checks where your branch diverged from main, pulls in all the changes, and replays your changes on top of them. Rebasing prevents cluttering up your commit history, too.

Here’s an example of how Greg works:

[laptop] ~ $ git checkout feature123-amazing-stuff
[laptop] ~ $ git pull --rebase origin main
[laptop] ~ $ git add my_amazing_module.module
[laptop] ~ $ git commit
[laptop] ~ $ git pull --rebase origin main
[laptop] ~ $ git push -u origin feature_branch

Greg starts his day by checking out his feature branch. Greg always works in feature branches, as one of his core four rules. He can’t be sure if anyone has committed code since he last checked this branch, so he rebases his branch against the main branch on his codebase’s origin. Everyone else’s changes are pulled in, and Greg’s changes are added back on top of them. Now, if someone has made changes to the same files Greg has, he’s able to see the conflicts before they go into the main branch. A pull --rebase does not add a merge commit, and keeps your commit history cleaner.

Now, Greg knows his changes are clean. During the day, he adds and commits more changes. Just before the end of the day, he rebases again, ensuring his code is as clean and safe as possible before he finally pushes it at the end of the session.

Git prompts for sanity

Anyone who has ever worked on a command line has felt the pain of doing something in the wrong directory, deleting the wrong file, or moving something to the wrong place. Your command line prompt can be a helpful indicator for where you are, what you’re doing, and the status of your local repository.

Git includes a script for showing your repository status in your command prompt. Download the git-prompt.sh file or look for it in your git source, and customize it to your needs. This prompt file does several helpful things:

  • Tells you what branch you’re on
  • Adds a red percent (%) sign when there are untracked files in the repository
  • Adds a red asterisk (*) when there's a changed file in the repository
  • Adds a green plus sign (+) when a file has been added using git add

These indicators flag that there is some change that has not been committed. This may be expected, but it may also be a sign that something has gone wrong - for example, if your indicators show up when you’re on the main branch.

Greg made a secondary script available for prompts, which indicates where you’re making the changes: locally, or on a server. If this might help you, download the servertype-prompt.sh script for yourself. This script depends on git-prompt.sh. Whether or not that prompt displays is an indicator for where you’re working.

Sniff your code

Unlike the more traditional network sniffer, which analyzes your packet traffic on the wire, a code sniffer reviews your code and checks it against a predefined standard. PHP_CodeSniffer “tokenizes PHP files and detects violations of a defined set of coding standards.”

Drupal developers are often familiar with the Coder module, written by Tag1 Senior Architect Doug Green, checks your Drupal code against coding standards and other best practices.

To include these in your codebase, add the following lines to your composer.json file.

composer require --dev drupal/coder
composer require --dev dealerdirect/phpcodesniffer-composer-installer

For a full tutorial on installing Coder and PHP Codesniffer, see Installing Coder Sniffer on drupal.org.

Coder module is designed to work with PHP CodeSniffer, making it easy to integrate with your continuous integration platform. Setting your team up with this kind of integration enables automated coding standard reviews on every pull request.

Other useful tools

Pre-commit hooks can run checks for you before you make a commit locally. You can set up a hook to run codesniffer before you commit - if your codesniffer fails, your commit fails, too! This can prevent some of the more obvious mistakes from even making into your local code. See an example Drupal pre-commit hook by Marco Marctino (mecmartini), or full documentation at pre-commit.

Tig is a visual command line tool that lets you see commit and log information for your repository. It has an interface that enables you to walk the list of commits, and see the details more easily.

Users who are less comfortable or familiar with the command line may find a graphical interface to be friendlier. Many GUIs are available for Git. If you’re struggling with the command line, check out a GUI and make your life easier.

About Drupal 4 Gov

Drupal 4 gov is an open source community for developers and IT professionals with an interest in making the government more open to open source.

It encompasses many open source projects but we have our beginnings in the Drupal project.

Drupal4gov offers:

Photo by Grant Ritchie on Unsplash

Sep 21 2020
Sep 21

This week brought a new, stable release for Smart Date 3.0.0. You're welcome to dig through the various Smart Date release notes to read up on all the changes from the previous, 8.x-2.x branch but I thought I would use this space to talk about some of the key themes.

Support for Drupal core Date Range fields

One piece of feedback I've heard a number of times is that people wanted the Admin Experience (AX) improvements of Smart Date and its more natural formatting for date and time ranges, but were hesitant to depend on a contrib module for custom storage of their date values. Knowing that this was a barrier to adoption, I started to think about how Smart Date was started as effectively a fork of the core Date Range field. Given this common ancestry, it wouldn't be too hard to make at least some of Smart Date's functionality available to Date Range fields.

This is now possible in Smart Date 3. You can use the Smart Date widget, meant to draw best practices from popular calendar software from Google, Apple, and others, and leverage Smart Date Formats for formatting output. In fact, the latter is also available for core date and time fields, to make it easier to keep the output consistent across your site.

This means you can hedge your bets by continuing to use core fields for storage, but Smart Date to enhance your forms and output. It also makes Smart Date easier to drop into an existing site.

Unfortunately, there are some limitations to this mixed approach. For one, the setup for allowed duration values is moved to the widget configuration for core date range fields, which means they can't be enforced for content created programmatically, as an example. Also, you lose the performance benefits of storing your time values as timestamps. There are a variety of other minor concessions, but perhaps the most significant functionality you forego in this approach are the biggest features introduced in the 8.x-2.x branch: the ability to manually set time zones per event and Smart Date's practical and easy-to-use integration for recurring dates.

An easier Admin Experience out of the box

The primary goal for Smart Date when it was first created was to make life better for content authors. The new release continues to build on that effort, though in more subtle ways.

When using a Smart Date field that allows unlimited values (recommended in case you want to enable recurring events at any point), Smart Date now allows you to suppress the additional, empty field set Drupal creates in addition to the one for the default values. An author can still add more field sets as needed, but it's another change meant to make Drupal work a little more like the calendar software authors are using every day.

For sites where the timezone widget is used, the default set of timezones can be daunting to choose from. The Chosen module can help, but in a recent talk about Smart Date, an attendee asked if it was possible to choose which time zones would be shown in the dropdown. It was a great idea and not difficult to implement. If you need to have time zones associated with your events but don't need support for the long, global set of timezones, using this new configuration for Smart Date's timezone widget can make life significantly easier.

When formatting dates and times with time zones, Smart Date formats now do a better job of determining when there’s value in also showing the time in the site’s default time zone. You now also have the option to force your format to never append the site time.

Support for Drupal’s next-generation themes

There’s significant work underway to get Drupal’s gorgeous new Olivero theme into Drupal 9.1 as experimental and to move Claro towards being stable -- and eventually Drupal’s default admin theme. Meanwhile, during DrupalCon Global we kept hearing the buzz about Gin, the customizable, contrib cousin to Claro. We’ve grown to love Gin and have made it our default for new sites, especially as we transition to building sites in Drupal 9.

It only makes sense, then, for Smart Date to look great and function as expected in Olivero, Claro, and Gin. SmartDate 3.0 has made a variety of changes to make sure that whichever one of these your site uses, Smart Date will be a seamless addition.

Feedback is always welcome

There have been a number of other, smaller changes: better support for formatting German-language dates, improved Fullcalendar View integration, additional views options for recurring dates, and many more. 

As always, the best way to learn about the power and potential of Smart Date is to test it out yourself. I encourage you to try out the Smart Date module and I’d love to hear your feedback. After all, much of what makes Smart Date as feature-rich as it is today came from the Drupal community, either directly as patches, or as feature requests. 

Please feel free to open issues for ways you think the module could be even better, or reach to @mandclu on Twitter, or in the #datetime channel in Drupal’s slack.

Sep 20 2020
Sep 20

I am no longer a Drupal Association board member nor was I involved in or privy to the discussions around the changes that the Drupal Association Board made to voting eligibility made this spring.  I’ve been reflecting on what I’ve heard from all sides and find that I may have some context that might prove helpful in understanding how we got here and some ideas on moving forward. Ultimately, the vestigial linguistic mapping that we used to ease the transition from Drupal VZW to DrupalCon, Inc. may instead be creating tension and misaligned expectations. The more the DA can clarify and create aligned expectations between itself and its contributors the stronger the Drupal’s future can be.

Drupal VZW - The Original Drupal Association

The Drupal Association has actually been two separate legal entities during its short lifespan. The current US-based 501(c)3 organization, DrupalCon, Inc. (DCI) that does business as (DBA) the Drupal Association is the successor organization to Drupal VZW, a Belgian organization originally founded in 2006. 

Drupal VZW was structured as an “association with non-profit purpose” (Vereniging zonder winstoogmerk in Dutch, abbreviated VZW or in French, Association sans but lucratif, or ABSL). A VZW has a defined structure which may be unfamiliar to non-Europeans: an association has a General Assembly (GA) of permanent “members” who nominate new people to become members of the GA at their discretion and then select the board of directors from among that GA membership; the membership rights and obligations are also quite defined and standardized. The original Drupal Association began as a GA of members selected by Dries with other members added annually by nomination of existing members based on their contributions to Drupal. 

While establishing the DA as a VZW initially was the most expedient option, by 2009 when I joined the GA and the board, the structure was under strain. At its peak, Drupal VZW was an international organization with a General Assembly of about four dozen and a board of ~8 people, most of whom did the work of unpaid staff. 

There were many reasons why we decided to deprecate the Belgian organization in 2010 and transfer the primary governance and assets to a US-based 501(c)3. The top three from my perspective were fiscal and tax considerations from the increasingly successful US-based educational conferences (North American DrupalCon), governance challenges with the GA/board structure (quorum was incredibly difficult to obtain to even consider structural changes) and difficulties operating the organization internationally especially during a period of Belgian political instability. Things may have been different had it been structured as an internationale vereniging zonder winstoogmerk (IVZW) from the start, but that is neither here nor there at this point.

The Transition to DrupalCon, Inc.

This context of VZW is important to understand how the bylaws for DrupalCon Inc., the US-based 501(c)3 were drafted. Largely, they are standard non-profit bylaws, but there were some key questions that we considered that informed the ways in which they were different (at least initially):

  1. What might the role be for former General Assembly permanent members?

    In VZW, the GA served as the accountability check for the board, which in turn functioned as staff. For example, the VZW board brought the budget to the General Assembly for review and approval once per year in the annual meeting. However, in the US, boards typically have a mix of those involved with the organization as well as outside perspectives that serve as the directors who are legally accountable for the actions of organizations.  

    As a transition, we created opportunities for interested former GA members to retain involvement and oversight. Initially, the bylaws created an Advisory Board committee for former GA members to serve on, but within the first few years, it was defunct through neglect. The board itself was advisory only and didn’t need another advisory board to advise it. In addition, GA members were invited to serve on the permanent committees of the board such as the Nominating Committee. Over time, that too has fallen off. Now the board committees are entirely composed of board members, which is typical of US-based non-profits.

    Many former GA members have moved on from the project; some remain involved in leadership roles: George DeMet is the chair of the Community Working Group. Neill Drumm is a Senior Technologist at the Drupal Association, and  Angie Byron is a Drupal Product Manager. Others remain contributors at various levels. None, aside from Dries, is currently serving on the Board.

  2. As we professionalized the board (e.g., became a strategic board that supported staff rather than a board of hands-on doers or managers or staff), how might we ensure a continued voice for hands-on contributors in the community?

    The strength of the Drupal community has always been in and derived from its contributor base. There was a lot of anxiety and care in our bylaw drafting process given to how we could preserve that connection and culture on the board even as we knew we would need to adapt the composition of the board to suit the needs of a strategic board. This is where the concept of the At-Large Director came in.

    The idea was that having two At-Large Directors would guarantee that at a minimum there would always be at least two representatives of the contributor community on the board to give voice, connection and insight to Drupal’s core strength. That, combined with Dries’s permanent seat as founder, created the three-person backbone of the organization that offsets the three rotating classes of self-selected Director slates, more typical of professional not-for-profit boards.

    The shorter term length was to keep this voice fresh and increase the accountability to the contributor community through frequent opportunity for the community to weigh in. After a few years it became clear that the one-year term was too short. It truly does take a year to get your bearings on any board. To enable an At-Large Director to make a meaningful contribution to the board, a two-year term was necessary and the director openings were staggered to keep elections annual.

  3. How to map the European structures and concepts to a US-based 501(c)3?

    Despite all the hours spent redesigning the organization, its structure, and its bylaws, there was never any consideration given to changing the name “The Drupal Association.” The US-based entity DrupalCon, Inc. (DCI) that had been created for DrupalCon DC as a Co-op was converted into the 501(c)3 and all of the assets from Drupal VZW were transferred to it. “The Drupal Association” was overlaid as a DBA (doing business as) due to the equity in the name and to minimize confusion. 

    For the US organization, the General Assembly (GA)’s oversight responsibilities (budget oversight, statutes, legal status, adding/removing members, etc.) moved to the Board of Directors with operational responsibilities transitioned to staff. We recognized that the elimination of the GA and the shift to a strategic board with a professional staff represented a necessary maturation of the organization and also had the potential to impact our culture unless deliberately preserved. Looking for opportunities for broader and more inclusive participation and to ensure that the voices of contributors remained strong, we created the At-Large Directors “elected by the community and ratified by the rest of the Board.”

The Challenge and Impact of Not Defining “Community”

The bylaws are silent on the definition of “community” even though it bestows a pretty important right to it. That lack of clarity has been the root cause of frustrations for both the community and the DA staff over the years and, it seems to me, underlies these current concerns. Without a clear alignment, it has been difficult to establish mutual expectations, to know what to expect and what might be expected in return.

This ambiguity becomes especially confusing in an organization that refers to itself an “Association.” The name itself implies there would be (or should be) members. In an association, the most common right bestowed upon a member of the association is voting eligibility.

Because “community” is not defined it falls to the Board to define. For expediency prior to those first At-Large elections, the DA used logging into Drupal.org in the year prior to the opening of the election to define the “community” as it was easy to quantify and provided some safeguards against fraud. While I recall discussing it as a board, the discussion was about technical feasibility rather than strategic value or engagement. I recall it as a case of measuring what was easy/feasible. We knew it was ridiculously overbroad, but it had worked well enough and better to be more inclusive than less. I don’t recall discussing or validating a definition of “community” with respect to election eligibility again during my tenure, which ended in December 2017.

The problem with this definition is that it sets the bar too low. It is not unreasonable that an organization ask that those who vote in its election be restricted to those who engage with and contribute to the organization. Failure to revisit this definition earlier has ossified an expedient definition into an expectant right. To change a privilege that had been in place that long (albeit one that was very underused) needed more communication with those impacted than was provided.

I fully support the Board in revisiting this neglected portion of its governance process. However, restricting voting eligibility to those with purchased memberships (while again expedient/easy) seems a flawed approach as it both perpetuates the “association” confusion and is overly restrictive. The DA bylaws explicitly state: “DrupalCon, Inc. (the "Corporation") is a Washington, D.C., nonprofit, public benefit corporation, and it has no members.” The fact that the DA offers individual “memberships” and is now extending voting rights only to those with membership is confusing. To be clear, these individual recurring donations are an essential form of support for the organization (as with any non-profit), but they do not constitute memberships of the non-profit corporation in a traditional association sense. Further, financial donations are not the only support upon which the DA relies. To bestow voting rights in exchange for primarily financial considerations (absent individual appeals) feels restrictive and like an alarming usurpation especially for an open source community.

What now?

Over the last ten years, the DA has gradually evolved and matured. The unique characteristics designed to ease the transition from VZW to DCI have increasingly been deprecated or brought into alignment with standard practice for a US-based 501(c)3. The changes have been gradual; to those actively involved in the DA, they might feel like a steady natural progression or for those who are newer to the organization, might feel completely non-controversial. It’s important to keep in mind that the 2019-2020 Drupal Association Board marked the first time when no former member of the Drupal VZW General Assembly (aside from Dries) served on the DA (DCI) Board. 

It seems to me that it is time to further evolve and here are my unsolicited recommendations:

  1. Clarify what the DA is: drop the legacy language inherited from our VZW days that is confusing and distracting. 
    • The organization is not an “Association”. It is a Foundation. Consider renaming it.
    • There are no “members”. There never have been. There are and always have been “contributors”. Discontinue calling financial supporters “members”. Orient services and benefits provided for contributors, both individual and organizational, comprehensively recognizing all forms of contribution.
    • Update the wording around the At-Large Director: “elected by the Contributors to the DA and ratified by the Board of Directors.”
  2. Clarify what the DA does: it is the clearinghouse for resources that support Drupal and its contributors. While the DA (and Drupal project itself) may provide benefit to those who are not contributors, the sustainability of the organization depends on optimizing benefit for those who are contributors.

    Adopting this lens provides the opportunity to clarify the ambiguous “community” in the bylaws with a much more objective definition of “contributors” particularly following implementation of the forthcoming recommendations from the Contribution Committee that recognizes all types of contribution (individual and organizational). 

  3. Consider expanding the number of At-Large Directors. As I left the Board, I advocated that the number of At-Large board positions be increased to 4, two elected each year. The switch to two-year terms for each At-Large Director was important. However, an unintended consequence of that change has been that those elected have been less globally representative than the representatives with two people elected at once. In fact, to date, all have been North American, with the exception of the remarkable Shyamala Rajaram from India in 2016 (the year of DrupalCon Asia, which saw increased eligibility and turnout).

    At-Large Directors bring tremendous value and perspective to the board. Ranked voting from a single pool for two positions gives candidates from smaller emergent contributor communities greater statistical odds of success. I encourage the board to consider expanding the number of At-Large Directors for that reason.

My hope is that by addressing some of these legacy semantic issues, the Drupal Association will be able to provide greater clarity, move forward into its next decade and build the kind of strong relationships that allow us all to focus on our shared goals.

Sep 19 2020
Sep 19

In the evolving world of web design and development, component-based design systems represent a revolutionary leap -- a previously missing link that replaces an environment of siloed functions and time-consuming complexities with high velocity capabilities that fuel flexibility, consistency, and collaboration.

Component-based design systems produce inherent efficiencies for designers and developers, and solve the challenges associated with duplication and inconsistency in applying themes, while driving the development of better quality, reusable components.  Clients gain the benefit of better brand management resulting from a simplified content editor experience that allows for bending as necessary, without breaking brand guidelines or page structures. 

As a thought leader on how humans interact with technology, Promet Source has enthusiastically pursued component-based design systems from the standpoint of both: 

  • innovative design patterns that optimize UX and spark engagement, and 
  • streamlined and simplified content editor experiences that allow for a wide range of page possibilities.

Powerful Partnership

As dedicated open source advocates, Promet has adopted Emulsify® as a tool to help us better organize, share, and reuse our custom design systems. Promet serves as both a user and contributor to its support and success. 

Emulsify is an open-source tool for creating design systems as a series of components that can be duplicated and easily manipulated within a set of clear guidelines for designers and developers. Promet is currently leveraging Emulsify on complex web development projects for government, healthcare, and higher education clients.

Advantages of Emulsify for Web Design Systems:

  • Integration with a starter library of Drupal-ready components with Storybook,
  • Portability across other CMS platforms and applications,
  • Open source, and
  • Compatibility with both WordPress and Drupal.

As Aaron Couch, director of technology solutions for Promet Source, recently pointed out: 

Emulsify has provided Promet with an optimal starting point to incorporate a component-driven approach into both Drupal and WordPress development. It has changed the way we deliver front-end experiences making our work higher quality, more efficient to deliver, and more accessible, while creating a better user experience for our clients.

Join Promet’s Aaron Couch along with Emulsify contributors Brian Lewis and Evan Willhite on Fri., Sept. 25, 2020, at 3:30 p.m. EDT, during this year’s virtual Drupal GovCon, for “Component-Driven Theming with Storybook.” 

During this session, presenters from Promet and Emulsify will explain how a component-based approach offers greater consistency, flexibility, re-usability, and velocity for front-end development. 

AKA "Atomic Design" 

While metaphors for helping to explain component-based design systems abound, “Atomic Design” (and a book with the same title) authored by Brad Frost) is the one that has gained the most traction and has entered into the lexicon of component-based web design. 

Atomic design looks at a website’s user interface as the collection of five factors that roll up into each other:

  • Atoms,
  • Molecules,
  • Organisms,
  • Templates, and 
  • Pages.

Exponential Impact

Component-based design makes front-end web development up to four times faster. This translates into happier clients and the freeing up of resources to focus on fine tuning and providing greater functionality. 

For the content creator and editor, component-based web design provides the ability to edit and revise pages to fit evolving needs and new priorities. 

The new world of “drag and drop” content management is soon to set a new standard in which previous limitations will quickly come to be viewed as  unacceptable. Low code/no code web design is the future.

The four key advantages of Promet’s adoption of the open based tool for creating web design systems powered by Emulsify®:

  • Design systems that can flex, bend, and scale within and among complex web designs,
  • Powerful new possibilities resulting from enhanced consistency, flexibility, re-usability and velocity for front-end development,
  • Elimination of painstaking QA processes in favor of proven patterns and high-quality built-ins that get designers, developers on the same page, and
  • Assurance that non-technical content editors can make multiple changes to a web page without breaking layouts or straying from brand guidelines. 

Need help creating a Drupal design system for your complex website? Contact us today.

Sep 18 2020
Sep 18

Read our roadmap to understand how this work falls into priorities set by the Drupal Association with direction and collaboration from the Board and community. You can also review the Drupal project roadmap.

Drupal.org UpdatesGit Merge Request

GitLab Merge Request beta

Back in July we kicked off the GitLab merge request beta, and over the course of August more and more project maintainers opted-in. The merge request workflow is available on more than 150 projects, and in several core issues. This is a *dramatic* improvement in the contribution workflow, especially for newer contributors or contributors making 'drive-by' contribution - and makes the lives of our existing long-term contributors much easier.

We're getting ever closer to enabling this workflow on every project across Drupal.org - but we still need your help! You can try out the contribution workflow on any of the projects that have opted in, opt-in your own projects, or check out the workflow in the core issues trying the beta.

Check out these issues to opt-in your project or core issue.  We anticipate general availability across all projects within just a few more weeks as we gather the final feedback from our beta contributors.

Auto Updates contribution week(s)!

During the week of August 3rd, 2020, representatives from three of the most successful open source content management systems came together to collaborate on a mechanism for securing software updates. Each of these open source projects is based on PHP, with similar use-cases, users, and update delivery architecture. By teaming up across these three projects, and any others who choose to join, we hope to standardize on a secure update delivery and validation mechanism. With this mechanism in place, each project can then build on top of it for additional features for our respective communities, such as providing secure automatic updates in Drupal.

Drupal    Typo 3   Joomla

Drupal, Typo3, and Joomla spent the week evaluating The Update Framework (aka TUF), an initiative of the Cloud Native Computing Foundation to provide a standardized framework or managing secure updates, minimize the impact of any potential compromises, and to be flexible enough to be used across different software systems.

Over the course of the week we made significant progress by replicating the reference implementation and its test fixtures in php, hosting the work in a shared repository: https://github.com/php-tuf/php-tuf. As we left the contribution we agreed to regroup in September for an additional collaboration. (That second contribution week has now happened, so look for an update in our September blog post!)

How can you get involved?

If you're interested in contributing to the PHP-TUF effort, you can take a look at the GitHub repository for the project: https://github.com/php-tuf/php-tuf

If you're connected to the Drupal community and are interested in PHP-TUF, or the larger initiative to work towards automatic updates, you can join us in Drupal Slack in the #autoupdates channel.

Per-project issue summary templates

Contributing to Drupal can be intimidating for a newcomer. One of the first barriers is just knowing 'how do I file a bug or feature request?'

Drupal core has a project issue summary template that is predefined to ask the right questions to help build a useful, actionable issue report.

And now, thanks to community contributors, each project hosted on Drupal.org can now define its own issue summary template - extending this great contributor onboarding feature to all projects in the Drupal ecosystem.

Launched the Lazy Load initiative

An increasing goal of the Drupal Association is to foster and onboard more major contributors to the Drupal project. One of the organizations we've been talking to recently is Google. Google has a vested interest in the performance of the open web, and over the course of the past several years has begun hosting a CMS leadership summit, to bring representatives from many CMS projects together.

As part of this growing collaboration, the Drupal Association has helped to coordinate the Lazy-Load initiative, which seeks to load all images lazily in Drupal core by default. Google has generously sponsored this work, and we hope to see it included in Drupal 9.1.

DrupalCon Europe

Supporting DrupalCon Europe - now virtual!

DrupalCon Europe has gone virtual! Early in the year, many of us hoped that we might be able to come together in person in Barcelona this fall. Unfortunately, this was not to be. But the European community is not letting that stop them from having a great event - online!

The Drupal Association spent some time in August working with the DrupalCon Europe team to integrate their chosen virtual event platform with the events.drupal.org schedule!

Registration is open now: https://events.drupal.org/europe2020 

And you can browse the program here: https://events.drupal.org/europe2020/schedule/2020-12-08


As always, we’d like to say thanks to all the volunteers who work with us, and to the Drupal Association Supporters, who make it possible for us to work on these projects. In particular, we want to thank:

If you would like to support our work as an individual or an organization, consider becoming a member of the Drupal Association.

Follow us on Twitter for regular updates: @drupal_org, @drupal_infra

Sep 18 2020
Sep 18

Accessibility isn’t just a concern for web developers. With content being dynamically created, there are a few points content editors can keep in mind to make sure their content is accessible to everyone. Following accessibility standards helps non-visual users, but can also help all users find and understand the information they’re looking for.

Creating Emphasis

One of the most common times accessibility issues pop up is when content editors are trying to emphasize sections of text. It is important to keep in mind that screen readers do not recognize details like different colors or bolded text, but will intonate exclamation points. If it is vital to the understanding of the content that a certain sentence be highlighted, consider using an exclamation point. If it is not vital but may help visual users to better understand the message, your best bet is making use of bold. 

From a usability standpoint, be wary of using color for emphasis. Colors can have unintended implications, such as causing the user to think the text is a warning, or even a link. Text also has to pass a certain color contrast ratio with its background to maintain accessibility, so unless a designer or developer with a knowledge of accessibility has picked out new colors for you, it’s best not to introduce more.

Another common mistake when emphasizing content is using all uppercase letters. A screen reader will read this out like an acronym, which could be particularly painful for a full sentence. Aside from screen readers, it is also shown to be less readable for all users when there are more than one or two words in a row in all-caps. Sometimes you’ll see all-caps used on buttons or labels, but the crucial difference is that these are (or should be) made into all-caps with code. A screen reader will usually ignore the css and see the text as it is originally written.

Is bold not enough variation for your content? Talk to your designer or developer about coming up with additional text styles for you to use. You may think to yourself, “I already have a dropdown with five different text styles I can use!” What you’re probably referring to is the heading selector.

Heading selector in a WYSIWYG field in Drupal.

Headings should never be used for emphasis or a stylistic choice. They are a tool to add structure to a page.

Heading Structure

Headings are pieces of HTML that are used to give structure to a page. They make it possible for non-visual users to navigate and understand a page without needing to see visual indicators. There is a specific way headings need to be arranged on a page. 

Headings are nested, just like you would see in an outline of a paper where subsections are indented and have a different bullet point or character. Heading 1 is the topmost level, functioning as the title of the page. There should only ever be one H1 on a page, and if you’re using Drupal or any other content management system, the H1 is probably already generated for you as the page title. If you’re working in a body field, for example, you’ll most likely start with H2 to title a section of content. Anything else at this same section level will also be an H2. If you need to label sections within this section, you can start to use H3’s. If you need to go any deeper than this, you can start to use H4’s, H5’s, and H6’s, but if you are going this deep into the structure, it may become difficult to follow for your average user. Here’s an example of heading structure:

(H1) The Most Amazing Chocolate Cake

          (H2) My Grandmother’s History

          (H2) Ingredients

                    (H3) Types of flour you can use

                    (H3)  Alternative ingredients

                              (H4) Vegan alternatives

                              (H4) Gluten free alternatives

          (H2) Instructions

                    (H3) The cake

                    (H3) The frosting

An important thing to watch out for is that heading levels don’t skip. You don’t want to go from an H2 right to an H4. That makes it more difficult for non-visual users to understand the structure of the page, and creates inconsistencies for all users. If you keep finding yourself tempted to do this for visual reasons, think about why it feels like the heading style available doesn’t fit, and work with your designer to figure out how best to fix it.

As mentioned before, don’t use headings simply to emphasize text. If you’re making a whole sentence into a heading, it’s probably not the right use. Headings are also not designed to be used for long sections of text. Bigger and bolder does not always mean easier to read. Sometimes a pull quote or a custom text style is an option that will accomplish what you’re looking for, without creating accessibility and usability issues, as well as design inconsistencies between different content editors.

Foreign Languages

Sometimes on your site you’ll need to add text in a different language. Visual users can identify when they won’t be able to read something, but screen readers need a hint that a sentence is in a different language. There’s a simple way to add this hint to your text: the language button. When you add content to a text field, usually you will have a toolbar at the top that allows you to make things bold, add a link, etc. One button that you may see if you’re using Drupal looks like this:

Language button on a WYSIWYG field in Drupal.

If you see this button, you can highlight your text and select from the dropdown. If you don’t see this button, or any buttons, ask your developer to make it available for that field.

Another thing to note with foreign languages is that users can use external tools to translate the content into a language they understand. For this reason, it is best to stay away from made up words that would only make sense in the language you’re writing, but not others (i.e. “hangry”).

Special Characters

One more content writing trend to avoid is replacing letters with characters, for example “$ave ₵ash” or “see u l8r.” This causes predictable issues for translation and screen readers, but it also can show up incorrectly for anyone. If you have an article titled “$ave ₵ash” it will show up in the url as something like this: yoursite.com/news/ave-ash, which could lead to some confusion when sharing links. The “u” in “see u l8r” would most likely be understood by a non-visual user, but would be impossible to translate.

Writing Accessible Links

Writing good link titles is important, and once you understand how non-visual users navigate a page, it’s easier to accomplish. These links could be inline links, such as a word in a sentence, or could stand alone, such as a button. Regardless, what you want is for link titles to be able to stand on their own. This is because one navigational tool that assistive technology provides users with is a list of links that appear on the page. Imagine a list of links that says “click here,” “learn more,” and “download.” These links don’t give the user any context or information about where the links will go. Instead, create links with text that gives users an understanding of what exactly that link will be doing. No user wants to waste time clicking on a link gives them an unexpected result.

W3.org gives these as examples of successful links (URI refers to the link destination):

A link contains text that gives a description of the information at that URI

A page contains the sentence "There was much bloodshed during the Medieval period of history." Where "Medieval period of history" is a link.

A link is preceded by a text description of the information at that URI

A page contains the sentence "Learn more about the Government of Ireland's Commission on Electronic Voting at Go Vote!" where "Go Vote!" is a link.

Meaningful link text also helps users tabbing through a page from link to link. Users can more easily navigate and determine where to go next without spending more time than wanted on an intermediary page.

Learn more about link accessibility at w3.org.

Writing Good Alternative (Alt) Text

Images that you add to your page need good alt text. When using a content management system, you’ll see a field show up when you add an image, asking for alt text. Alt text allows non-visual users to get the same basic information that the image is giving to a visual user. It is what shows if an image doesn’t load, whether because of a broken image link(?) or a user’s limited internet access. It also provides information to search engines.

Writing good alt text can feel a bit tricky at first. What you want is for your alt text to communicate the content and function of the image. Think of alt text as what you would want to appear in the place of the image if you couldn’t use it. You’ll want to be succinct in describing the image, and avoid any redundancy with the text around it. Screen readers will know that it’s an image, so don’t add text like “image of…” Think about what information is and isn’t helpful, and why you’re adding an image in the first place. Is it just to take up space next to text, or is there something important being conveyed through that image? An image of students on a quad conveys information about student life at the university, whereas a cartoon image of a backpack likely doesn’t add any information.

Example of an alt text field in Drupal8.

Sometimes the alt attribute of an image should be empty. The alt attribute is the piece of HTML that is holding the alt text you enter when you first add an image. You may instead have a label below your image that is visible to all and acts as alt text. You wouldn’t want a screen reader to read out what would ultimately be the same text twice, so you’ll want an empty alt attribute on the image. The only instance where you want no alt text at all is when an image is only decorative, such as a swirling line between text sections or a generic image added only to break up the text (like the previous backpack example). Alternative text may be a required field when you add an image, in which case adding empty alt text by typing a single space in the field might work for you. If this doesn’t work, you may want to talk to a developer about making alt text optional. Consider how many content editors your site has, and if they all have accessibility training. If it is possible that a lot of images that need alt text could end up without it, it may be best to keep it required and minimize using images that don’t add meaning to a page. If the image has alt text in a caption already and you need to add something into the alt text field to be able to save it, try to add context that isn’t already clear from the caption. In most cases you will want alt text anyway, but ask yourself if the alt text you’re adding will be a help or an unnecessary hindrance to a non-visual user.

Wikipedia shows the alt text below the image and the alt attribute stays empty.

When an image is linked, and is the only thing in the link, the alt text needs to describe the function of the link. This is because the link doesn’t have any other text in it, so any clue as to where the link is going to go is taken from the alt text. In this case, you can write alt text as if you were writing link text.

For some great examples of how to write alt text, take a look at the list provided by webaim.org.


Once you understand how different users are experiencing your content, writing with accessibility in mind starts to get easier. It’s not always the most exciting and creative part of writing content, but it can be a rewarding experience to continually remind yourself to think about users that often can be overlooked. Putting yourself in someone else’s shoes can help build empathy and make the web, and particularly your piece of it, a more positive space for all.

Sep 18 2020
Sep 18

BADCamp is understanding that there are many different ways that folks can contribute back to Drupal. Not a coder!? Not a problem! We have plenty of opportunities for people to earn contribution credits while working on their professional development. 

  • Already planning on attending sessions? Volunteer to be a Session monitor.
  • Love Drupal Trivia? Submit trivia questions unique to BADCamp.
  • Love to meet with new folks? Chatt with attendees at the BADCamp booth.

Fill out this volunteer survey to discover the many ways you can give back to the Bay Area Drupal Community.

We are 100% volunteer driven and invite the wider community to help make our camp the most rad camp it can possibly be.

BADCamp is dedicated to providing a safe, inclusive, welcoming, professional, and harassment-free conference experience for everyone regardless of gender, gender identity and expression, sexual orientation, disability, physical appearance, body size, race, age, religion and any other status protected by laws in which the conference or program is being held.


Sep 18 2020
Sep 18

Often, the most effective means of managing complexity is a laser-sharp focus on simplification -- breaking down a project into its smallest component parts and visualizing incremental  steps toward completion beginning with the smallest building blocks. 
That’s exactly what Brad Frost has achieved in coining the concept of Atomic Design, and authoring a book by the same name.  In clarifying the new capabilities of component-based web design systems, the vocabulary of Atomic Design has gained traction, and entered into the working lexicon of web designers and developers.  
As Frost explains:

Atomic design is not a linear process, but rather a mental model to help us think of our user interfaces as both a cohesive whole and a collection of parts at the same time. 

From Atoms to Pages

Atomic design considers a website’s user interface as the collection of five factors that roll up into each other:

  • Atoms,
  • Molecules,
  • Organisms,
  • Templates, and 
  • Pages.

1. Atoms

The basic building blocks such as HTML tags, form labels, and buttons, as well as color palettes and fonts -- essentially all of the factors that designers typically define as a reference point for developers when creating a website’s style guide. 

2. Molecules

Chemically speaking, molecules consist of atoms bonded together. Within Atomic Design a molecule make up distinct building blocks and refer to design specifications for functional, reusable combinations of atoms, such as a keyword search bar with a search button. 

3. Organisms

Combinations of molecular building blocks form organisms that form distinct sections of a user interface. This is where the design begins to take shape with the creation of reusable components such as a footer consisting of a logo, social media icons, a call to action link, and other branding elements.

4.  Templates

Groups of organisms arranged together form a template. The game-changing factor within component-based design is the inherent flexibility of the templated layout, allowing for a wide range of options such as switching out an image for a text block, and previewing responsive layouts for various devices. 

5. Pages

Pages refer to specific representations of templates that take shape beyond a theoretical example and come to life as a real-world view of what the user will see and experience on the site. It is at the page stage where texting and review concerning the totality of the design system tends to occur and adjustments are made.

To learn more about the powerful potential of component-based web design systems, join Promet’s Aaron Couch along with Emulsify’s Brian Lewis and Evan Willhitel on Fri., Sept. 25, 2020, at 3:30 p.m. EDT, during the virtual Drupal GovCon, for “Component-Driven Theming with Storybook.” 

Stay tuned for further announcements concerning Promet and Emulsify® and in the meantime, Contact Us for help or consultation concerning the creation of a complex Drupal website. 

Sep 18 2020
Sep 18

Often, the most effective means of managing complexity is a laser-sharp focus on simplification -- breaking down a project into its smallest component parts and visualizing incremental  steps toward completion beginning with the smallest building blocks. 
That’s exactly what Brad Frost has achieved in coining the concept of Atomic Design, and authoring a book by the same name.  In clarifying the new capabilities of component-based web design systems, the vocabulary of Atomic Design has gained traction, and entered into the working lexicon of web designers and developers.  
As Frost explains:

Atomic design is not a linear process, but rather a mental model to help us think of our user interfaces as both a cohesive whole and a collection of parts at the same time. 

From Atoms to Pages

Atomic design considers a website’s user interface as the collection of five factors that roll up into each other:

  • Atoms,
  • Molecules,
  • Organisms,
  • Templates, and 
  • Pages.

1. Atoms

The basic building blocks such as HTML tags, form labels, and buttons, as well as color palettes and fonts -- essentially all of the factors that designers typically define as a reference point for developers when creating a website’s style guide. 

2. Molecules

Chemically speaking, molecules consist of atoms bonded together. Within Atomic Design a molecule make up distinct building blocks and refer to design specifications for functional, reusable combinations of atoms, such as a keyword search bar with a search button. 

3. Organisms

Combinations of molecular building blocks form organisms that form distinct sections of a user interface. This is where the design begins to take shape with the creation of reusable components such as a footer consisting of a logo, social media icons, a call to action link, and other branding elements.

4.  Templates

Groups of organisms arranged together form a template. The game-changing factor within component-based design is the inherent flexibility of the templated layout, allowing for a wide range of options such as switching out an image for a text block, and previewing responsive layouts for various devices. 

5. Pages

Pages refer to specific representations of templates that take shape beyond a theoretical example and come to life as a real-world view of what the user will see and experience on the site. It is at the page stage where texting and review concerning the totality of the design system tends to occur and adjustments are made.

Need help creating an Atomic Design system for your organization’s website that allows for greater flexibility that maintains brand consistency? Get in touch!

Sep 16 2020
Sep 16

Gatsby Image, along with gatsby-transformer-sharp and gatsby-plugin-sharp, is a common way to handle images in a Gatsby project.  It gives us the power to process source images at build time to create a 'srcSet' for  '<img>' or '<picture>' tags, or create versions in grayscale, duotone, cropped, rotated, etc.

When Gatsby builds from a Drupal source, it downloads the source images and processes them to create these image variations which are stored in the public directory. The ability to optimize and art-direct images at build time is great, but build performance suffers while these assets are generated. As a site grows in images, the time it takes to build grows as well. Image processing can take hours, while the rest of the build takes mere minutes.

Drupal has the built in ability to generate its own derivative images on demand and cache them, so why not just build our Gatsby components in a way that leverages Drupal Image Styles and dramatically speed up the Gatsby build process? Gatsby can just query for the image urls and let Drupal serve them directly.

For this experiment, I didn’t use Gatsby Image at all, though you could format your image data in a way that the Gatsby Image component expects, and still pass that in. My goal was to explore my options for getting image variants from Drupal via JSON:API and GraphQL, and to pass that to a custom React component, so that’s what I’ll demonstrate in this post.

I’ll show examples using both the core JSON:API module, as well as the GraphQL contrib module, which gives us a different developer experience.

Drupal Modules Used

 - jsonapi
 - rest

 - graphql - An alternative to jsonapi with a developer experience that, so far, I prefer.
 - jsonapi_image_styles - required to access image styles with jsonapi, not required with graphql module.

Gatsby Configuration

  resolve: "gatsby-source-graphql", 
  options: { 
    typeName: "Drupal", 
    fieldName: "drupal", 
    url: `http://backend.lndo.site/graphql/` 
  resolve: `gatsby-source-drupal`, 
  options: { 
    baseUrl: `http://backend.lndo.site/`, 
    apiBase: `jsonapi`, // optional, defaults to `jsonapi` 
    skipFileDownloads: true, 

Here I’m configuring both the graphql and the drupal (jsonapi) sources. As this is only a local experiment, I’m not concerned with authentication and I’m using Lando/Docker for local development. In a real project, I’d extract the relevant parts to environment variables so they can be changed for the production server. I’d also only use one or the other, and not both.

In the graphql config, you’ll notice 'fieldName:' is set to 'drupal', which is what we’ll use to access the GraphQL API, as opposed to the JSON API.

In the 'gatsby-source-drupal' config I’ve set 'skipFileDownloads:' to 'true' because we will not need them for local processing or delivery. This skips all file downloads, but there are ways to be more specific using filters. https://www.gatsbyjs.com/plugins/gatsby-source-drupal/#filters

Option 1: GraphQL

Query Against the GraphQL API

query($id: String!) {
  drupal {
    nodeById(id: $id) {
      ... on Drupal_NodeArticle {
        title: entityLabel
        author: entityOwner {
          authorName: entityLabel
        body {
        fieldImage {
          xxl: derivative (style: XXL) {
          xl: derivative (style: XL) {
          large: derivative (style: LARGE) {
          medium: derivative (style: MEDIUM) {
          small: derivative (style: SMALL) {

This query is for a specific article node in Drupal that contains a field named 'field_image'.  With the GraphQL module in Drupal, we have access to the 'derivative' function that allows us to query for the values of a specific image style.

In this case we’ve set up 5 image styles in Drupal which scale an image to different widths:

  • Small: 300
  • Medium: 600
  • Large: 1200
  • XL: 1800
  • XXL: 2400

The sizes are meant to cover a “full width” image at various breakpoints or screen resolutions.  Of course, you can set up Image Styles more suited to your needs.

We can alias each derivative by prefixing it with the style name and a colon, allowing us to have multiple derivatives in the same query, setting the style argument to the appropriate style name.

The result of the query includes all the values we need for our Image component.

        "fieldImage": {
          "alt": "Arduino",
          "xxl": {
            "width": 2400,
            "url": "http://backend.lndo.site/sites/default/files/styles/xxl/public/2020-09/arduino-harrison-broadbent_0.jpg?itok=EyvwD2ta"
          "xl": {
            "width": 1800,
            "url": "http://backend.lndo.site/sites/default/files/styles/xl/public/2020-09/arduino-harrison-broadbent_0.jpg?itok=0gub18uQ"
          "large": {
            "width": 1200,
            "url": "http://backend.lndo.site/sites/default/files/styles/large/public/2020-09/arduino-harrison-broadbent_0.jpg?itok=eNUhJHb6"
          "medium": {
            "width": 600,
            "url": "http://backend.lndo.site/sites/default/files/styles/medium/public/2020-09/arduino-harrison-broadbent_0.jpg?itok=Rvsmw0an"
          "small": {
            "width": 300,
            "url": "http://backend.lndo.site/sites/default/files/styles/small/public/2020-09/arduino-harrison-broadbent_0.jpg?itok=sNDME4Ju"

We can see that the url for each style is specific to the path Drupal will use to serve that version of the image. We’re letting Drupal do the work.

Next: An Article Component

Here we put it all together to render a node.

import React from 'react';
import { Link, graphql } from 'gatsby';
import Layout from '../components/layout';
import Image from '../components/image';

export const query = graphql`
query($id: String!) {
  drupal {
    nodeById(id: $id) {
      ... on Drupal_NodeArticle {
        title: entityLabel
        author: entityOwner {
          authorName: entityLabel
        body {
        fieldImage {
          xxl: derivative (style: XXL) {
          xl: derivative (style: XL) {
          large: derivative (style: LARGE) {
          medium: derivative (style: MEDIUM) {
          small: derivative (style: SMALL) {

const ArticleTemplate = ({ data: { drupal: { nodeById: article } }}) => {

  return (
      <div className="article">
        <p className="author">Posted by {article.author.authorName}</p>
        <div dangerouslySetInnerHTML={{ __html: article.body.processed}}></div>
        <Link to='/'>&larr; Back  to all articles</Link>

export default ArticleTemplate;

This 'fieldImage' object is passed to the Image component as the first prop named 'image'. Our second prop is named 'sizes' and this is set manually where we call our Image component. It gives us some control over which version of the image is rendered given what we know about how wide it will be in the layout at certain breakpoints.

Next: An Image Component

I want to create a responsive image with a 'srcSet' similar to what we would get with gatsby-image.

import React from 'react';

const Image = ({image, sizes}) => {

  const derivatives = [];

  for (const derivative in image) {
    if (image[derivative].url) {
      derivatives.push(`${image[derivative].url} ${image[derivative].width}w`);

  const srcSet = derivatives.join();

  return (

export default Image;

The '<img>' tag will need 'srcSet', 'sizes', 'src' and 'alt' values. The query to the GraphQL API in Drupal collects all this information, returning it in the 'fieldImage' object that we passed to the 'image' prop. The 'for' loop iterates over the derivatives and concatenates each image URL with its width, pushing each to an array to create a set. The array is later joined to create the full value of the 'srcSet' image attribute. 
The 'src' attribute can have a value of any of the derivative urls. In this case 'image.small.url'.

Finally, the 'alt' attribute comes as part of the query, at 'image.alt'.

Option 2: JSON:API Version 

If you’re more comfortable with, or more invested in using the JSON:API rather than the GraphQL module in Drupal, you can achieve the same results with the addition of the 'jsonapi_image_styles' module, which exposes the image styles to the JSON:API.

In this case the query would look more like this:

  query($id: String!) {
    nodePage(id: { eq: $id }) {
      field_image {
      relationships {
        uid {
        field_image {
          image_style_uri {
      body {

However, the results are a bit unexpected.

        "field_image": {
          "image_style_uri": [
              "small": null,
              "medium": null,
              "large": "http://backend.lndo.site/sites/default/files/styles/large/public/2020-09/engin-akyurt-girl-blond-hair-unsplash.jpg?itok=MrcdTwGV",
              "xl": null,
              "xxl": null
              "small": null,
              "medium": "http://backend.lndo.site/sites/default/files/styles/medium/public/2020-09/engin-akyurt-girl-blond-hair-unsplash.jpg?itok=vQx__izk",
              "large": null,
              "xl": null,
              "xxl": null
              "small": "http://backend.lndo.site/sites/default/files/styles/small/public/2020-09/engin-akyurt-girl-blond-hair-unsplash.jpg?itok=hKO4dR34",
              "medium": null,
              "large": null,
              "xl": null,
              "xxl": null
              "small": null,
              "medium": null,
              "large": null,
              "xl": "http://backend.lndo.site/sites/default/files/styles/xl/public/2020-09/engin-akyurt-girl-blond-hair-unsplash.jpg?itok=MPph1lH4",
              "xxl": null
              "small": null,
              "medium": null,
              "large": null,
              "xl": null,
              "xxl": "http://backend.lndo.site/sites/default/files/styles/xxl/public/2020-09/engin-akyurt-girl-blond-hair-unsplash.jpg?itok=sz-ymDam"

We get an object for each image style that contains keys for all the image styles queried, with 'null' values, except for the style corresponding to that part of the query. I’m not sure why this is, but we have to process our results differently to build the 'srcSet'.  Let’s illustrate with a Picture component so we don’t have to change the Image component.

import React from 'react';

const Picture = ({image, alt, sizes}) => {

  const derivatives = [];
  let src = "";

  image.forEach(derivative => {
    if (derivative.small) {
      src = derivative.small
      derivatives.push(`${derivative.small} 300w`)
    if (derivative.medium) {
      derivatives.push(`${derivative.medium} 600w`)
    if (derivative.large) {
      derivatives.push(`${derivative.large} 1200w`)
    if (derivative.xl) {
      derivatives.push(`${derivative.xl} 1800w`)
    if (derivative.xxl) {
      derivatives.push(`${derivative.xxl} 2400w`)

  const srcSet = derivatives.join();

  return (
      <source srcSet={srcSet} sizes={sizes}/>
      <img src={src}

export default Picture;

Notice that we also have an 'alt' prop because the 'alt' data comes from a different part of the query. It can’t be accessed from 'relationships.field_image' like the image styles are. 


Whichever API type you use on the backend, I hope I’ve shown that we can still leverage the power of Drupal to process images as they’re needed instead of having to download and process them during the Gatsby build, bloating the build time and the size of the build artifact. 

Combine this with the 'image_effects' module in Drupal and create image styles to meet many different needs. You can have your fast Gatsby build times and responsive images too!

"Code like nobody is watching... but then refactor. ;)"

Sep 16 2020
Sep 16

Gatsby Image, along with gatsby-transformer-sharp and gatsby-plugin-sharp, is a common way to handle images in a Gatsby project.  It gives us the power to process source images at build time to create a 'srcSet' for  '' or '' tags, or create versions in grayscale, duotone, cropped, rotated, etc.

When Gatsby builds from a Drupal source, it downloads the source images and processes them to create these image variations which are stored in the public directory. The ability to optimize and art-direct images at build time is great, but build performance suffers while these assets are generated. As a site grows in images, the time it takes to build grows as well. Image processing can take hours, while the rest of the build takes mere minutes.

Sep 16 2020
Sep 16

by David Snopek on September 16, 2020 - 1:27pm

As you may know, Drupal 6 has reached End-of-Life (EOL) which means the Drupal Security Team is no longer doing Security Advisories or working on security patches for Drupal 6 core or contrib modules - but the Drupal 6 LTS vendors are and we're one of them!

Today, there is a Moderately Critical security release for Drupal core and CTools to fix a Cross-Site Scripting (XSS) vulnerability. You can learn more in the security advisory:

Drupal core - Moderately critical - Cross-site scripting - SA-CORE-2020-007

Here you can download:

If you have a Drupal 6 site, we recommend you update immediately! We have already deployed the patch for all of our Drupal 6 Long-Term Support clients. :-)

FYI, there were other Drupal core security advisories made today, but those don't affect Drupal 6.

If you'd like all your Drupal 6 modules to receive security updates and have the fixes deployed the same day they're released, please check out our D6LTS plans.

Note: if you use the myDropWizard module (totally free!), you'll be alerted to these and any future security updates, and will be able to use drush to install them (even though they won't necessarily have a release on Drupal.org).

Sep 16 2020
Sep 16

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

Alberto Rojas from Manati will be giving an update about Layout Builder. We will also discuss whatever Drupal related thoughts are on your mind. If you would like to contribute to the conversation, please join us.  

All nonprofit Drupal devs and users, regardless of experience level, are always welcome on this call.

Feel free to share your thoughts and discussion points ahead of time in our collaborative Google doc: https://nten.org/drupal/notes

This free call is sponsored by NTEN.org and open to everyone.

View notes of previous months' calls.

Sep 16 2020
Sep 16
Project: Drupal coreDate: 2020-September-16Security risk: Moderately critical 12∕25 AC:None/A:User/CI:Some/II:None/E:Theoretical/TD:DefaultVulnerability: Information disclosureCVE IDs: CVE-2020-13670Description: 

A vulnerability exists in the File module which allows an attacker to gain access to the file metadata of a permanent private file that they do not have access to by guessing the ID of the file.


Install the latest version:

Versions of Drupal 8 prior to 8.8.x are end-of-life and do not receive security coverage. Sites on 8.7.x or earlier should update to 8.8.10.

Reported By: Fixed By: 
Sep 16 2020
Sep 16
Project: Drupal coreDate: 2020-September-16Security risk: Moderately critical 12∕25 AC:Basic/A:None/CI:Some/II:None/E:Theoretical/TD:DefaultVulnerability: Access bypassCVE IDs: CVE-2020-13667Description: 

The experimental Workspaces module allows you to create multiple workspaces on your site in which draft content can be edited before being published to the live workspace.

The Workspaces module doesn't sufficiently check access permissions when switching workspaces, leading to an access bypass vulnerability. An attacker might be able to see content before the site owner intends people to see the content.

This vulnerability is mitigated by the fact that sites are only vulnerable if they have installed the experimental Workspaces module.


Install the latest version:

Versions of Drupal 8 prior to 8.8.x are end-of-life and do not receive security coverage. Sites on 8.7.x or earlier should update to 8.8.10.

Once a site running Workspaces is upgraded, authenticated users may continue to see unauthorized workspace content that they accessed previously until they are logged out.

If it is important for the unintended access to stop immediately, you may wish to end all active user sessions on your site (for example, by truncating the sessions table). Be aware that this will immediately log all users out and can cause side effects like lost user input.

Reported By: Fixed By: 
Sep 16 2020
Sep 16
Project: Drupal coreDate: 2020-September-16Security risk: Moderately critical 13∕25 AC:Basic/A:User/CI:Some/II:Some/E:Theoretical/TD:DefaultVulnerability: Cross-site scriptingCVE IDs: CVE-2020-13669Description: 

Drupal core's built-in CKEditor image caption functionality is vulnerable to XSS.


Install the latest version:

Versions of Drupal 8 prior to 8.8.x are end-of-life and do not receive security coverage. Sites on 8.7.x or earlier should update to 8.8.10.

Reported By: Fixed By: 
Sep 16 2020
Sep 16
Project: Drupal coreDate: 2020-September-16Security risk: Critical 15∕25 AC:Basic/A:None/CI:Some/II:Some/E:Theoretical/TD:DefaultVulnerability: Cross-site scriptingCVE IDs: CVE-2020-13668Description: 

Drupal 8 and 9 have a reflected cross-site scripting (XSS) vulnerability under certain circumstances.

An attacker could leverage the way that HTML is rendered for affected forms in order to exploit the vulnerability.


Install the latest version:

Versions of Drupal 8 prior to 8.8.x are end-of-life and do not receive security coverage. Sites on 8.7.x or earlier should update to 8.8.10.

In addition to updating Drupal core, sites that override \Drupal\Core\Form\FormBuilder's renderPlaceholderFormAction() and/or buildFormAction() methods in contrib and/or custom code should ensure that appropriate sanitization is applied for URLs.

Reported By: Fixed By: 
Sep 16 2020
Sep 16
Project: Drupal coreDate: 2020-September-16Security risk: Moderately critical 14∕25 AC:Basic/A:User/CI:Some/II:Some/E:Theoretical/TD:AllVulnerability: Cross-site scriptingCVE IDs: CVE-2020-13666Description: 

The Drupal AJAX API does not disable JSONP by default, which can lead to cross-site scripting.


Install the latest version:

Versions of Drupal 8 prior to 8.8.x are end-of-life and do not receive security coverage. Sites on 8.7.x or earlier should update to 8.8.10.

If you were previously relying on Drupal's AJAX API to perform trusted JSONP requests, you'll either need to override the AJAX options to set "jsonp: true", or you'll need to use the jQuery AJAX API directly.

If you are using jQuery's AJAX API for user-provided URLs in a contrib or custom module, you should review your code and set "jsonp: false" where this is appropriate.


Drupal 7 sites should also pass such URLs through the new Drupal.sanitizeAjaxUrl() function.

The update to Drupal 7 is likely to cause a regression in AJAX functionality on sites which use jQuery 1.5 (for example via the jQuery Update module). This issue seems to specifically affect jQuery 1.5; the version included in Drupal 7 core (1.4.4) and versions 1.6 and later do not suffer from the regression.

Reported By: Fixed By: 
Sep 15 2020
Sep 15

voting banner image of a ballot box

Elections for the next At-Large member of the Drupal Association Board have now reached the voting phase. Voting will take place from now, 15 September, until 30 September at 10 am PDT.

Drupal Association Individual members should check their email inboxes over the next couple of days for their voting slip arriving.

In the meantime, voters should read the candidate’s info pages, watch the “Candidate Chat” videos, and consider which of the candidates will help the Drupal Association most effectively fulfil its mission.


As detailed previously, we will be using Helios Voting this year and the voting process looks like this:

  1. Open the voting slip email that was sent to the primary email address defined in your drupal.org profile
    The email will arrive from [email protected] - check your spam folder if you cannot see it, though it will take some hours to send voting slips to each of the 3200+ eligible voters!
  2. Read the instructions there to register your vote
  3. Again, you should receive an email from Helios Voting, confirming the correct registration of your vote
  4. Await the results!

We would like to thank all of our candidates this year for their participation and wish them all the very best of luck!

Have questions? Please contact me: Rachel Lawson.

Sep 15 2020
Sep 15

How awesome would it be to give your users the freedom to customize their interface to as per their preference? While many users prefer a light interface (light background with dark text), some users choose a dark interface (dark background with light text). Darker interfaces are perceived as cool and trendy while some also believe it reduces strain on the eyes especially for developers who spend a lot of time in front of the screen. I believe that providing an option to your users is a tremendous win in terms of accessibility and user experience. There are a couple of ways with which one can accomplish this. In this article, we will discuss on how to toggle between dark/light web design modes and implement this in Drupal 8 or Drupal 9.

Implementing the dark/light toggle

We will be focusing on two methods to implement this -
1.    Using only CSS.
2.    Implementing the CSS & JS toggle switch

Using only CSS

To achieve Dark mode on any website with only CSS, one must keep in mind some of the system requirements.

One such important requirement is the system-wide dark mode. If a user prefers to use dark mode on his PC, then the user is served with a website which shows a dark-colored background with light text on it.

The prefers-color-scheme (media query) is used to identify if the user has requested the system to use a light or dark color theme.

1.    Declare the CSS variables.
2.    Use the variables wherever it is necessary.

The result:

Note: To emulate the result on some unsupported devices, just enter DevTool by pressing F12. Next, press CTRL+SHIFT+P, then search for prefers-color-scheme: dark and press enter.  

Implementing the CSS and JS toggle switch

If we are going with this approach, then we don’t need to bother about the system requirements. Just write couple of lines of CSS and JS and you should be ready.

Once we have initialized the variables, we can reference these variables in our stylesheets.

This will be the HTML structure to toggle between dark and light mode.

HTML Structure                                               HTML Structure

And some lines of CSS should result in this switch.

The switchThe Switch

The final part is to add a bit of JavaScript to tie it all together.
●    Store the user preference for future visits
●    Check for saved user preference, if any, on load of the website

That's it! Check out the full demo below.

Or click here to view the demo.

Implementing the Dark / Light Toggle in Drupal 8 (or Drupal 9)

To start with creating a custom Drupal 8 theme, please refer the awesome article here. Let us now start creating a theme to show how to use dark theme/ light theme in Drupal 8 or Drupal 9.
The file structure will look like this: 

Implementing the dark/light toggle

Now, update the header section inside the page.html.twig with the following code.


  <header aria-label="Site header" id="header" role="banner">
    <div class="container">
      <div class="header">
        {{ page.branding }}
        {{ page.navigation }}
        <div class="switch-wrapper">
          <label class="switch" for="checkbox">
            <input type="checkbox" id="checkbox"/>
            <div class="slider round"></div>

The rest of the HTML structure will be dependent on your design or requirements.

Once you are done with the HTML structure, it is time to make them look nice by styling the elements in CSS.

First, you have to create all the default variables which will be responsible for the colors on Light/ Dark mode.


:root {
  --color-background: #f0f0f0;
  --color-header: rgb(14, 33, 141);
  --color-header-text: #aecafa;
  --color-text: #2c0000;
  --color-card-bg: #fff;
  --color-link: rgb(255, 0, 0);

/* Variable decleration for dark mode */

[data-theme="dark"] {
  --color-background: #1a1a1a;
  --color-header: #aecafa;
  --color-header-text: 0e218d;
  --color-text: #d3d3d3;
  --color-card-bg: #435561;
  --color-link: #24ce24;

Now that you are done defining the variables, it is time to add style to the Header section to get the required result.


.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  border-bottom-right-radius: 10px;
  border-bottom-left-radius: 10px;
  background-color: var(--color-header);

.header a {
  color: var(--color-header-text);
  text-decoration: none;
  font-weight: bold;

.region-navigation {
  display: flex;
  justify-content: center;

ul.menu {
  display: flex;
  justify-content: center;

ul.menu li {
  margin-right: 30px;

.switch-wrapper {
  display: flex;
  align-items: center;

.switch {
  display: inline-block;
  height: 34px;
  position: relative;
  width: 60px;

.switch input {
  display: none;

.slider {
  background-color: white;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  transition: 0.4s;

.slider:before {
  background-color: rgb(255, 196, 0);
  bottom: 4px;
  content: url("../assets/sunny-day.svg");
  height: 26px;
  left: 4px;
  position: absolute;
  transition: 0.4s;
  width: 26px;

input:checked + .slider {
  background-color: rgb(36, 36, 36);

input:checked + .slider:before {
  transform: translateX(26px);
  content: url("../assets/night.svg");
  background-color: rgb(59, 116, 223);

.slider.round {
  border-radius: 34px;

.slider.round:before {
  border-radius: 50%;

Please note that the styling may vary according to your requirements.

After all the styling, it is now time to write some functionality in Jquery code.

The Jquery code will look something like this (script.js in our case)


(($, Drupal) => {
  Drupal.behaviors.mainMenu = {
    attach(context) {
      const toggleSwitch = document.querySelector(
        '.switch input[type="checkbox"]'
      const currentTheme = localStorage.getItem("theme");

      if (currentTheme) {
        document.documentElement.setAttribute("data-theme", currentTheme);

        if (currentTheme === "dark") {
          toggleSwitch.checked = true;

      function switchTheme(e) {
        if (e.target.checked) {
          document.documentElement.setAttribute("data-theme", "dark");
          localStorage.setItem("theme", "dark");
        } else {
          document.documentElement.setAttribute("data-theme", "light");
          localStorage.setItem("theme", "light");

      toggleSwitch.addEventListener("change", switchTheme, false);
})(jQuery, Drupal);

And don’t forget to include your JS and CSS files inside your theme_name.libraries.yml file.

  version: 1.x
      css/style.css: {}
    js/script.js: {}
    - core/jquery
- core/drupal

Now clear the site cache to see the result. Your end result should look like this :

Resulttoggle between Dark and Light Mode in Drupal 8
Sep 14 2020
Sep 14

At Drupalize.Me, we have a long history of leading in-person Drupal training workshops. In fact, our whole website evolved out of public workshops we used to do as part of Lullabot before online video-based training was a thing. (We even made DVDs once!) While workshops are no longer the core of our business, we continue to offer them on occasion at DrupalCon and various local camps -- just because we just love doing them.

I've always really enjoyed facilitating real-time in-person workshops. It's such a different experience than recording screencasts. The energy is different, as is the sense of accomplishment and the rush you get afterwards. And while both are great for learning, I think there are some benefits to in-person learning that are hard to replicate via written tutorials and pre-recorded screencasts.

So this fall, we're trying something new: we're offering real-time remote workshops. It's not quite in-person, but I'm pretty excited to try it out. I'm looking forward to being able to engage with others who are learning Drupal. And I think that there are some interesting things we can explore -- like using VS Code's collaboration features, and tools like Miro -- that'll make the whole experience engaging in a different, yet equally valuable way.

We're still ironing out the details, but we'll certainly be doing a version of our popular Hands-On Theming workshop which has sold out every time we've done it in the last 4 years. I'm also excited that we're putting together a workshop on upgrading from Drupal 7 to Drupal 8 (or 9).

We're going to keep the number of seats limited (probably 10 or fewer), in order to ensure we can create an environment that promotes discussion and collaboration. I think the intimacy of smaller groups can be much more engaging than large webinar-style courses where the participants are mostly anonymous.

Take a look at what we've got in store, and sign up for the waiting list to get early access and discounted prices when we schedule these workshops later this year.

View upcoming workshops →

Sep 14 2020
Sep 14

In his Drupal 4 Gov webinar Using tools and Git workflow best practices to simplify your local development, Tag1 Senior Infrastructure Engineer Greg Lund-Chaix talks about some of the ways that teams struggle when they become successful and need to learn to scale. One of his primary focuses for teams is helping them learn how to improve their development workflow.

Local development environments give developers the tools to quickly prototype and run their code, and make testing and debugging easier. You can use local environments to create code that can be pushed to the repository, and shared with the team easily and cleanly - enabling discussions and peer review early in the development process.

One of Greg’s key tenants is “No editing on the servers.” Working locally keeps mistakes from reaching the primary codebase. Using a local environment is a best practice.

Tag1 developers often use these two tools:

These tools are open source, extensible, and have many available integrations. They make it quicker and easier to create a local environment than using a tool like MAMP, or configuring your own setup with MySQL, Apache, and so on.

Tools like DDEV and Lando also ensure your local environment matches your production environment, preventing long troubleshooting sessions when something works locally, but not on production.

How to get up and running with DDEV

Here’s a quick guide to getting started with DDEV.

[embedded content]

  1. Install DDEV.
  2. From a command line, start with a basic Composer-ized installation of Drupal. Greg created a template repository you can use as a starting point. You can have as little as a directory for custom code, the composer.json file, and a README.txt file.
  3. Enter composer install. Composer will download and complete a basic Drupal installation.
  4. At the prompt, enter ddev config.
  5. The command prompt updates. DDEV checks the directory name, and assumes the project name is based on that directory. Update the name here if that is incorrect, or press the Enter key to accept the default.
  6. DDEV checks the contents of the directory. If you’ve installed Drupal, it recognizes the installation. You may also select a different Project Type from the list DDEV supplies.
  7. DDEV setup is complete. To run DDEV, type ddev start.

DDEV starts the Docker containers. If you have never run DDEV before, this may take a few minutes while it pulls the containers down from the repository. When ready, a message similar to this displays:

DDEV setup is complete when the `Successfully started` message displays.

Click, or copy and paste the link into your browser to load your new Drupal website.

Two commands, one Drupal website!

What next?

When DDEV runs for the first time, it creates the .ddev/config.yaml file in the directory. Git ignores this file by default; consider adding it to your repository. This ensures everyone who checks out the repository has the same configuration.

View the file in your choice of text viewers.

An example of DDEV's `config.yaml` file.

This file is customizable, enabling you, your developers, and your DevOps teams to make changes that ensure your local environment matches your production servers.

From here, Greg suggests using Ansible, Puppet, or another configuration management tool to deploy your code to production.

Now you should be able to run DDEV, and explore its uses!

About Drupal 4 Gov

Drupal 4 gov is an open source community for developers and IT professionals with an interest in making the government more open to open source. This blog was based on Greg’s Drupal 4 Gov presentation.

It encompasses many open source projects but has its beginnings in the Drupal project.

Drupal 4 gov offers:

Photo by Lysander Yuen on Unsplash

Sep 13 2020
Sep 13

The Drupal Association (D.A.) Board decided in May to update the eligibility criteria for voting in the election of At-Large Directors of the D.A. These are the members of the Board whose purpose is to “reflect and represent the Drupal community at large,” and their election is to be “by the community” and dependent on “[ratification] by the rest of the Board.” We changed the voter eligibility criteria for these elections from requiring community members to have logged in to drupal.org in the year prior to nominations opening to requiring them to have an active D.A. Membership prior to the start of voting.

As we wrote in our statement about this resolution, we believe we failed as a Board to consider how to engage the community and communicate the change proactively. I personally endeavored to answer as many questions as I could in various threads on Twitter, but Twitter is a poor place for long answers, nuance, or organized communication. As such, I solicited specific questions I could answer in this post as a member of the Board who approved the resolution.

A word before I dive in: this post contains my personal recollections of fact and statements of opinion, and I’m not speaking herein on behalf of the full Board. We’re fifteen different individuals with unique perspectives on this discussion and virtually every topic we approach. In places where I’m answering questions of fact, I ask the reader to be gracious - just because I’m stating how something occurred (e.g. “neither the discussion nor the final resolution were controversial to the Board”) doesn’t mean I or the Board don’t understand competing opinions or wouldn’t accept other points of view as legitimate alternatives.

I also wish I could have prepared this post faster, but finding a solid 8 hours to give to the task has proven difficult. My family was gracious to give me most of this Saturday for it, and while I'm sure I won't satisfy every critic, I hope the post is received as my honest attempt to plainly, directly answer your questions.

Ok, diving in!

I’m going to follow Sally Young’s list of questions as a general outline and try to address as many questions or concerns as I can that were raised in the various Twitter threads by other community members.

1. What was the impetus for the change being tabled?

I didn’t write the initial proposal and can’t recall which specific conversation would have birthed it. However, I believe the resolution was generally a byproduct of recurring conversations at Board meetings about continuing to evolve the D.A. and its Board in pursuit of its mission. These conversations include comparative analysis, advice and counsel from outside experts, and books and reference material designed to help organizations like ours mature.

You can see the results of these conversations in who we hire to be Executive Director, who we recruit to serve on the Board, how we work to diversify our staff, programs, and revenue, and how we clarify who our stakeholders are and how we serve them. These conversations have included questions about the meaning and purpose of both individual and organizational supporters of the D.A., and as far as I can recall, our discussions on the topic of the resolution were primarily a matter of alignment - that people who desire a say in who should lead the organization, or who desire to serve as its leaders, ought to be individually committed to the organization through a D.A. Membership.

I understand there are people who conscientiously object to D.A. Membership for a variety of reasons, including its structure, its prior decisions or actions, its current programs, or a sense that contribution “ought to be enough.” While I wish they were able to find common cause and become advocates for the D.A. as the primary organization responsible for the Drupal community’s infrastructure, I don’t begrudge them their abstention. I would likely even agree with them on various critiques of the D.A. - nobody believes it's perfect! I just don’t believe people who intentionally refuse D.A. Membership or who believe the D.A. as it is shouldn’t even exist must be given a say in who leads it.

(Note: lest I be accused of saying such people don’t matter, please understand that I am talking about the leadership specifically of the D.A., which is distinct from but exists to serve the Drupal community at large. You can be a contributor to the project and a leader in the community without believing in or respecting the D.A. While I might disagree with your position, it wouldn’t make me respect you or value your contributions any less, nor would I expect the D.A. not to work hard to serve you. By nature it serves the whole community, and in many areas it solicits guidance and feedback from a wide variety of individuals, working groups, committees, etc. to attempt to do so even better.)

To Sally’s follow-up questions on this point regarding specific expectations for engagement or data-driven analysis, all I can say, even if it’s unsatisfying, is this wasn’t a data-driven decision. We saw it as correcting a misalignment and trust the staff of the D.A. to find new ways to activate and empower individuals who maintain a D.A. Membership, including those who perhaps through this very discussion engage the D.A. for the first time.

2. What was the process of this being proposed?

The resolution was presented to the Board for discussion at our meeting in May. From my memory, we had previously discussed this topic at an earlier strategy meeting, so I don’t believe it was a surprise to anyone or that anyone expressed concerns with respect to the text of the resolution itself. We approved it by the unanimous consent of all those present, including myself (who previously served as an At-Large Director) and our two currently serving At-Large Directors.

3. What percentage of people who voted in the previous election were D.A. members?

Unfortunately, I don’t know the answer to this, and I can’t say off the top of my head what it would take to find out (i.e. do we have the data in the right shape and places to run such a query?). I’m sure a significant percentage of voters were not D.A. members, because only a small fraction of all eligible voters under the prior criteria were D.A. Members. (I do expect D.A. Members were overrepresented in the vote; I'd love to see the actual statistics on this, too.)

That said, I do know that we have significantly more Individual Members of the D.A. than we have had participants in any recent election. I gathered the statistics from the last 4 elections from the D.A. blog, and the numbers aren’t particularly encouraging. (I’ll save my reflections on the trend for another post; trying to stay focused here...) We have over 2,900 Individual Members in our directory, but we have averaged only 1,345 voters over the last four elections with an average turnout of only 1.59% of eligible voters.

I’m very curious to see the numbers from the upcoming election.

4. [With respect to the text of the by-laws stating the corporation has no members,] when an individual signs up for a membership, what status are they within the organization?

(Let me state the obvious here: I am not a lawyer or an expert in nonprofit law. While I consulted a lawyer to understand the meaning of our by-laws on these points, the following still just reflects my personal understanding … i.e. I could be stating something incorrectly, apologies in advance.)

The D.A. is a board driven organization with a self-perpetuating board as opposed to a member driven organization where members directly elect the organization’s leaders. As stated in our by-laws, the Board of Directors “exercise or direct the exercise of all corporate powers,” and with respect to our community elections, the Board must ratify the winners before they become part of the Board.

I wasn’t party to the creation of the D.A. to speak to why this specific structure was chosen, but I’ve read various articles on the advantages and disadvantages of each. I believe our structure gives us room to think more strategically / long term, as our nominations process allows us to ensure continuity of purpose year over year, but it also centralizes decision making in a way that may make some stakeholders unhappy. (This particular debate is a case in point.)

The D.A. doesn’t have members who vote for directors; we have a membership of people from all over the world who have an interest in the success of the Association’s mission, somewhat similar to other nonprofits like NPR. (As one example, you can refer to the membership page of the nonprofit supporting public radio in South Carolina.) I personally think we’ll need to rename the “Drupal Association Membership” to clarify this distinction, finding a term that is not semantically overloaded, in much the same way that we have to be careful about words like “Partner” or “Affiliate”.

In short, a person’s “status in the organization” is unchanged when they sign up for a D.A. Membership, but they do receive a variety of benefits for joining.

5. [With respect to the text of the by-laws describing the nature of At-Large Directors and their election process,] will this be changed?

I’m not sure if Sally means the name, “At-Large Directors”, or the text related to the election process. I’ll answer each one in turn just in case, as other folks have echoed these questions in various Twitter threads.

First, will we rename At-Large Directors?

The answer to that is no, they have and will continue to “reflect and represent the Drupal community at large,” and as such will still be referred to as “At-Large Directors.” Speaking from personal experience, when I served as an At-Large Director, my input was regularly, directly solicited on a variety of community impacting topics. I expect this to continue to be the case.

I see two basic objections to this position:

On the one hand, some people believe every member of the Drupal Association Board ought to be directly elected by members of the nonprofit, and as such “At-Large Director” was a misnomer even before we made this change. I understand this critique, but I personally consider our structure to be a foregone conclusion and theorizing about “how it could have been” to be interesting but impractical. (Speaking of “how it could have been,” imagine if the suggestion to use Certified to Rock for qualification had gained traction…)

On the other hand, some people believe that restricting eligible voters in these elections to people who maintain D.A. Memberships means the Directors cannot be described as representatives of “the Drupal community at large.” I think there’s merit to this point but that there’s room for disagreement, especially in light of historical precedent.

Our by-laws are ambiguous about what constitutes the “community” with respect to elections, and even our earliest discussions about elections demonstrate the debate was about what the criteria ought to be beyond simple self-identification as a member of the Drupal community. Notes from that era specifically ask the question, “Who is the Drupal community we're trying to capture in our voting eligibility criteria?”

In other words, from the very beginning, our debate hasn’t been about how to maximally define “community” but about how to define “community” in a way that is clear, concrete, and ensures that everyone who does vote is inarguably part of the community. After those initial discussions, D.A. Memberships and drupal.org user accounts were the two final criteria being considered for the election, and both were described as “not remotely represent[ing] the ENTIRE community.” No one objected then that that meant the directors could not be called “At-Large Directors” as a result. That same post also reflected an understanding “that this definition could shift over time,” including in a hypothetical future where we provided a “sliding scale cost for membership, or free memberships to certain subsets of the community.”

I revisit this history for a couple reasons. It demonstrates that the decision of the Board in May was very much in line with the earliest thinking of the Drupal community on this topic, and it comes at a point after we’ve long provided a sliding scale for the Individual Membership price and in conjunction with a policy that allows anyone to request a free Membership.

Even more poignant, from a process standpoint, it’s clear that from the very beginning the D.A. Board was leading the process. The election committee tasked with defining election policies was constituted by the Board, populated by the Board, reported to the Board, and produced recommendations that required Board approval prior to the first election. If Board leadership wasn’t illegitimate then, it isn’t today. That said, even if our decision was both within our realm of responsibility and in keeping with the spirit and positions of previous discussions, I still very much agree with the Board statement that we should have discussed and defined a communications strategy at the time we made it.

Going back to the second part of question 5, will we revise the by-laws with respect to the election process?

On this point, my current answer is I’m not sure but probably. I don’t believe the changed criteria conflicts with the by-laws any more than the prior criteria did - in either case, we’re restricting who, among all the people in the world who might consider themselves part of the Drupal community, is actually eligible to vote.

I do think we should consider amending the by-laws to point to a definitive policy document that addresses both how we determine voter eligibility and what it means for the Board to ratify an elected candidate.

6. Do the [new rules] create a different kind of barrier and why?

Yes, the new rules create a different kind of barrier, no bones about it. I know others disagree, but I don’t personally find the new criteria particularly more onerous than the old criteria.

Additionally, the new criteria create more room for people to participate under certain conditions, because eligibility is no longer determined based on when you last logged in to drupal.org. I know that’s a “simple” requirement, but it’s also fairly arbitrary. Even if you’d participated in Drupal events or worked at a Drupal agency, if you hadn’t created an account until after nominations opened or logged in to an existing account in the year prior to that date, you were ineligible to vote and without recourse to become eligible. Under the new criteria, you simply must log in or create an account and then become a D.A. Member at any point before the election in order to participate. These may be freely acquired by those who cannot afford the variable price fee or whose organizations do not already provide them an Individual Membership.

That answers the “what has changed” and as to the “why”, as I stated above, I believe the new criteria better align voter eligibility with the purpose of the vote. You are electing a Director of the D.A., which is a distinct entity within the Drupal community, and as such it’s more relevant whether or not you have a D.A. Membership than whether or not you have logged in to drupal.org in the year prior to nominations opening for a new election.

7. What effect will this [barrier] have on under represented groups?

I think its impact will be negligible but likely impossible to quantify. As I pointed out above, even in 2012, election discussions foresaw a shift in eligibility criteria, especially after the means of acquiring a D.A. Membership expanded and / or became more accessible. I understand some consider having to ask for a free Membership to be an impediment unto itself, but I’m not convinced this will be a practical barrier in the context of our community, which includes many such scholarships, grants, sponsorships, etc. and a no-questions, no-shame based approach to the awarding of these.

Furthermore, what Pedro Cambra writes in his self-nomination is not entirely correct, that “You can still vote even if you’re not a member of the Drupal Association.” I understand the intent of this heading, but the D.A. is literally activating a D.A. Membership upon request, with all the benefits that come with it, not just doling out voting rights. It is not a lesser Membership; there is no asterisk beside the badge on grantees’ user profiles. They are members, and upon becoming members, they are eligible to vote.

(Yes, as Sally points out, one person was directed to the normal registration form after requesting a D.A. Membership; this was an unfortunate mistake that was rectified the next day. I asked about it as soon as it was brought to my attention - a supporting staff member had not immediately understood the nature of the request. It was corrected, the process was amended to prevent further mistakes, and ultimately no one who has requested a membership has been denied one.)

I remain confident that anyone who wants to participate in this election will be able to do so, and I appreciate the efforts of the D.A. staff to communicate the changes in a variety of channels and generally improve the process for helping the community get to know their nominees. Might someone still be surprised come election day? There’s always a chance, but I don’t consider it any greater a chance with the new criteria than with the old.

8. Did the Association consider adding a free option to its regular membership sign up form?

I do not know the answer to this question or the follow-ups. I can only say I wasn’t party to any such conversation, nor have I heard of any taking place.

Personally speaking, I would expect such decisions to be left to the Executive Director and the D.A. staff. The Board passes resolutions and works with the Executive Director at a higher level to prepare budgets, organize priorities, plan the organization’s strategy, etc. but leaves the implementation details up to her and the staff. This goes for any number of areas of the Association's operations, not just the specifics of managing these elections, and the staff are always careful, competent, and eager to do right by the community in their work.

In closing...

I've been a part of the community since 2006 and a part of the D.A. Board since 2017. I first met other members of the Drupal community in person at DrupalCon Barcelona 2007, and I met my partners and many of my team members at Commerce Guys and Centarro through subsequent DrupalCons. I grew my career through contributions on drupal.org. The Drupal Association undergirds these things today, and as such, I strongly believe in the D.A. and its mission, want it to succeed, and want as many people as possible to join me in supporting it.

We do have a strong roster of candidates in the current election, and voting for the next At-Large Director begins on Tuesday, September 15th. I encourage you to learn more about the candidates and secure your D.A. Membership by September 14th in order to join me in this upcoming election.

Sep 12 2020
Sep 12

For a long time I was thinking about write or not a review of the Drupal 8 Module Development (the former edition of the current). For me there were two very important keys: on the one hand, it was a very ambitious book in terms of scope and content (so it was an important challenge to make a synthesis on its simple review). On the other hand, Drupal 9 was already on its way and it was possible that it would be deprecated quickly. Luckily, Drupal 9 has already arrived and the transition from 8 to 9 has not only not been at all traumatic (there are still many people trapped in the crack between Drupal 7 and Drupal 8), but it has also been an easy road. There won’t be substantial or profound differences in how to approach the creation of custom modules in Drupal 9 respect to Drupal 8 and with this new edition adapted to Drupal 9, everything is ready to review this ambitious book. There we go!

Picture from Unsplash, user Erol Ahmed, @erol

Table of Contents

1- Introduction
2- The Book
3- Recommendations
4- Book Information
5- Fast Review
6- Ratings
7- :wq!

1- Introduction

Daniel Sipos (or just Danny Sipos, or Upchuk in Drupal.org or @drupalexp in twitter) is a developer related to Drupal for many years. He is also a regular speaker at Drupal events and is also the person behind the website called Web Omelette (https://www.webomelette.com), such a popular website that you should get to know it if you’re a Drupal developer (put the URL in your favorites if you don’t know).
I already knew his website from looking for doubts, consulting references and obtaining examples (almost as a study and training online resource), when I had the opportunity to be a little closer to his work through a project in the context of the European Commission, where I had to use a Drupal distribution and set of tools and resources, called Open Europa to generate new platforms for the European Commission. At that time I left some written lines here in my notebook about this.

As it is easy to contextualize, the author has a lot of experience in the field of knowledge about Drupal, and that shows well. Perhaps that is why he has written successive editions (Drupal 9 would be the third iteration) of what can perhaps be considered the fundamental book for Drupal-based development. In fact, because of its scope and size, this book should be considered the Holy Bible of Drupal. A resource that should be part of any developer’s shelf or ebook/kindle/tablet. But if the metaphor about the bible were accurate, then we could extend it a little further. Because basically, a sacred text requires its own “hermeneutics” in order to be interpreted correctly, that is, its own study of meaning. We hope that this article will be useful to unravel its essence and value. Let’s continue.

2- The Book

Imagine a tutorial that contains all the most important issues of Drupal. A review through its diverse concepts, systems, subsystems, elements&mldr;Well here you have about six hundred pages with all of it. As we said in the previous section by way of introduction, the true Drupal bible. Here you will have access to all the ins and outs of Drupal, even those parts that are not well known even to many senior developers (such as the TypedData API).
The paradox, the real tension of this book is to assume a length and depth that sometimes does not meet the expectations of didactics for people who want to start in Drupal. In my experience, I have tried to share the book with fellow juniors and it has been difficult for them to advance: first those who are not fluent in English, but then those who were. In all the cases observed, the colleagues considered the book too hard, rough, complex&mldr; however, when they commented and shared it with the older profiles, they made a much more agile and profitable use of the book. They did know how to get into the inner workings of the book. This is important and marks my view of the book in some ways.

Based on these observations, I have concluded that if Drupal were a medicine, I would say that this extensive manual is something like a help for healthy people. It is in itself a treatment for people who are already initiated, those who are already able to place themselves within the world of Drupal. It is really curious, since it would be easy to accuse or blame the book of anti - didactic (in the second chapter, right when you create your first Drupal module the content are already talking about services or Form API, this is a very, very fast trip). You could say that everything (or almost everything) is sacrificed to try to make the ambitious goal of explaining Drupal deeply (or to demonstrate the author’s mastery of the subject, but that belongs to another set of interpretations). This book contains the same information as a thousand articles, hundreds of posts, and dozens of online guides. It is the perfect accumulation of Drupal content, and in order not to get lost in the way, it is better to be in the hands of a senior profile that acts as a sherpa.

The book -by the way- is still edition after edition the reference guide on Drupal, as you can see in the books section of the Drupal.org website: https://www.drupal.org/books.

Some APIs that are discussed in this book:

  • Mail API: Send emails programmatically, by code (Chapter 3: Logging and Mailing).
  • Token API: How to manage formatted placeholders (Chapter 3: Logging and Mailing).
  • State API: Simple Storage by key/value pairs (Chapter 6: Data Modeling and Storage).
  • UserData API: Storage of some pieces of data related with users (Chapter 6: Data Modeling and Storage).
  • Configuration API: Related with this important subsystem of Drupal, set of methods (Chapter 6: Data Modeling and Storage).
  • TypedData API: Low level object oriented API for descriptive data processing over PHP (Chapter 6: Data Modeling and Storage).
  • Entity API: The most important API for interactions with Entities (Chapter 6: Data Modeling and Storage).
  • Database API: Describes methods and resources for manage the database, including queries (Chapter 8: The Database API).
  • Schema API: Allows defining database table structures (Chapter 8: The Database API).
  • Cache API: Creating, Reading and Invalidating caching entries (Chapter 11: Caching).
  • AJAX API: Client-Side interactions using PHP and without JavaScript (Chapter 12: JavaScript and the AJAX API).
  • Translation API: Working with entity translations (Chapter 13: Internationalization and Languages).
  • Lock API: Low level resource for processes (Chapter 14: Batches, Queues, and Cron).

3- Recommendations

Mainly, this book is indicated for someone who wants to deepen their knowledge of Drupal.

In principle, there are some requirements to enjoy this book, related with some kind of previous experiencie in the Drupal World, or it runs the risk of becoming a “book - door”, since you will have to go to the Internet to find many concepts and other examples in order to establish the knowledge set out in this great manual.
On the other hand, we will say: Ok, the book it’s a MUST. All teams should have a copy nearby, for consultations, to resolve doubts, to clarify ideas. So if you’ve decided that you want to make Drupal the best way to make a living (and earn your salary). I would recommend you take this tutorial and handle it as what it is: an excellent cartographic compendium, with plenty of maps to go through all the routes of Drupal.

Read it, study it, practice it and repeat all the examples. It’s a master’s degree in Drupal whose execution only depends on you (and with a very good price).

4- Book Information

Field Description Title Drupal 9 Module Development. Author Daniel Sipos. Publisher Packt. Date August, 2020. Pages 626 Overview Comprehensive guide to Drupal 9 development. Keywords Drupal, Backend, API, PHP, Symfony, Testing. Price 30$ // 29.99€ (aprox) Links Packt, Amazon

5- Fast Review

Question // Answer 1- Is this book progressive, Iterative and Incremental? No, the book tries to be lineal using the idea of implementing a custom module, but it’s more complex than this. 2- Does it offer specific solutions to particular problems or concrete issues? Yes, the book is full-filled with a lot of proposals, solutions and ideas. 3- Does it explain well the original problems or needs it aims to solve? Yes, Yes, although it does not have a problem-solution structure it’s rather a topic-exposition. 4- Is this book rich in examples? Yes, it contains many examples and practical demonstrations. 5- Is this book written in plain English, suitable for non-English speakers? No, it contains set phrases, expressions, usages that sometimes take it away from plain English. . 6- Is it up to date? Yes, is a recent issue from August 2019.

6- Ratings

Table of Book Ratings for DDEV

7- :wq!

[embedded content]

Sep 11 2020
Sep 11

Please join us for our first MidCamp 2021 planning meeting!

Why come?

Because we value giving back to the Drupal community and this is one way you can do that.

What should I expect?

That's mostly up to you -- there are a lot of roles and skillsets needed to put on a conference like MidCamp. Regardless of what you do day-to-day, you can find a fit.

What if I don't live in Chicago?

That's OK! The planning of things is done remotely. A good portion of the planning team doesn't live in or near Chicago. People join because they care about Drupal and want to help make MidCamp happen.

How to join?

We'll be using a Waiting Room for the Zoom, so please RSVP if you plan on joining so we're able to let you in.

Sep 10 2020
Sep 10

Let's decouple Drupal - Well, what exactly?

When it comes to decoupling, it turns out there are many options on how to decouple. Not only are there many technology choices in choosing the right frontend framework and APIs involved, the questions become also more foundational: Which system should be in charge of handling different aspects of the application, e.g. routing, placing blocks or authentication?

So before moving on, we need to clarify what exactly we want to achieve:

Clarifying goals: Why to decouple?

For us, the main reasons are:

Independent frontend development

By separating the frontend from the backend, frontend development can happen completely independent of the backend. So frontend developers do not have to know Drupal development, but can focus solely or their part: the frontend. That way, it's much easier to find and onboard frontend developers.

Easier performance optimization

While efficiently lazy-loading CSS or JS assets of a page is quite hard to do with Drupal, modern frontend technologies handle this with breeze and simply lazy-load pre-built asset chunks as needed. Furthermore, the frontend can better optimize the page loading experience (and the assets needed per-page) since the frontend has the knowledge of what exactly is needed by which frontend component.

Re-usable frontend components

Re-usable frontend components - including asset dependency management - are a solved problem in the Javascript world and all the various Javascript frontend frameworks provide that. Additionally, tools like Storybook make it really easy to build up your own component library.

Modern frontend and UX

By building upon modern frontend tooling we can provide a more app-like UX to our users, handle client-side route changes and only reload and repaint what's needed when navigating pages. The web page can become and feel more app-like, or even be turned into a Progressive Web App that does more than providing an offline copy of the site!

Challenges faced

This sounds all good - but there are lots of challenges that must be well-considered:

Re-inventing the wheel

By throwing away Drupal's frontend, you also throw away all the existing integration Drupal provides with its own frontend. Besides the more obvious, like handling forms and logins, features like contextual edit links, previews or the layout builder just do not work out of the box anymore. So one has to develop alternative solutions for all those features - if needed. Depending on the solutions choosen, this can be a lot of work.

Server-Side-Rendering and Hosting

For delivering a decent user experience and being friendly to robots (Google) some sort of pre-rendering is needed on the server. So this needs extra thought and comes with new infrastructure requirements (Node.js) that, come at a cost, and must be considered when choosing where to host.

Cold cache performance

When the Drupal backend is connected via JSON API or GraphQL a first, uncached page load typically needs various kind of data, quickly ending up in multiple API requests to the backend. Since all of those need to be resolved on a cold-cache page hit requests possibly end up really slow and lead to slow first page loads.

Coupling of the frontend to the backend

When the frontend talks to Drupal via its default JSON or GraphQL APIs, the frontend needs to know about Drupal's data structure. Field names, their types and entity relationships are no Drupal interna anymore, but become part of the contract between the backend and the frontend, limiting the possibilities to develop them separately. One could implement custom JSON endpoints or GraphQL Schema to mitigate and fine-tune that.

Our solution: Rendering into Custom Elements markup

We figured that in order to reach the mentioned goals, we can use a soft approach to decoupled Drupal in order to keep more of Drupal's features available. The basic idea is that Drupal keeps rendering pages by providing the main page content as custom elements (markup). Then, this simplified markup can be picked up by client-side frameworks like Vue.js to handle rendering the elements client-side.

An example of custom element would be the following markup for a Twitter paragraph:

<pg-twitter src="https://twitter.com/bmann/status/1283090375742091264">
  <h3 slot="title">#Driesnote suggesting to ship an official component for React and Vue for managing menus</h3>

Note that we use pg as abbreviation for paragraph here. Or a quote paragraph:

  <h1 slot="title">a quote from twitter...</h1>
  <p>#Driesnote suggesting to ship an official component for React and Vue for managing menus<br>Ship it in NPM as those devs expect.</p>
  <span slot="author">Boris Mann</span>

Generating this markup, is exactly what the Custom Elements module does. The module renders the data of all visible fields either as attribute to the custom element tag, or as nested tag with a slot attribute.

As custom elements are part of Web components specification, web components provide a good fit for rendering the content client-side, but other client-side frameworks like Vue.js or React.js can pick up the data and render it as well - so there is plenty of choice for the best-suiting client-side solution.

So what about the page template?

Since the header and footer area is pretty static for most of the time on most of our sites, we figured they are best implemented by mostly static components in the frontend. Any dynamic parts, like meta tags or navigation elements can be complemented with data provided by (long-cached) API calls or even computed client-side (for example, the active menu item). If necessary, it's easy to re-render parts of it and client-side frameworks like Vue.js and React can handle updating only the necessary bits when navigating pages.
While the dynamic per-page content is provided by the backend in a single API response per page, the header and footer can be controlled by the frontend. The frontend application takes the custom element content and renders it, next to taking care of updating essential page metadata like meta tags.

Thus, for rendering individual pages, the frontend needs to fetch the main content - rendered as Custom Elements - as well as any page metadata that it needs for rendering the page from the backend. For that, we've implemented the Lupus Custom Elements Renderer module which turns Drupal into an API backend providing exactly that.

Summing up

By rendering the page shell and custom element content in a frontend framework of our choice, we achieve all of our goals stated. Moreover, the custom elements "format" provides a good way of decoupling the frontend of the backend, since any Drupalisms or backend complexities in the data model can easily by translated into a meaningful collection of custom elements. Those elements comprise a well-defined structure representing your site's content elements and transferring the necessary data to the frontend. In the frontend, the custom elements map nicely to Vue/React/Web/... components.

By keeping Drupal's page routing mechanism, we can keep using Drupal's path handling, including useful features like editor controlled path aliases or redirects. Since page responses are handled as whole by Drupal, we optimize and cache full-page responses and leverage Drupal's existing cache infrastructure and optimized cache tags for caching individual parts of the page.

Finally, the approach taken allows us to keep using some of Drupal's existing solutions like, cookie-based authentication for user-specific page responses, the layout builder or even form processing.

Following up

Since there is so many details more to talk about, I'll be following up with further blog posts in the coming weeks, covering the following topics:

  • Selecting a frontend framework. Server-Side-Rendering and hosting options
  • Architecture variants, Authentication, Custom Elements markup & json formats
  • A developer introduction: Creating components, adding Custom Element processors, the relationship to Drupal's render API, Custom routes and optimizing cache metadata.
  • Handling blocks & layout builder, content previews, forms, caching & performance optimizations.

Finally, I'm going to talk more about this stack at the Drupalcon Europe 2020 in my session "Custom Elements: An alternate Render API for decoupled Drupal" - so mark your calendars!

Sep 10 2020
Sep 10

“Since getting started with Drupal can be a bit intimidating for newbies, this blog is literally a great investment to take a look at”.

Apparently, Drupal offers a wide range of modules, nearly thousands of modules that are available to download anytime and anywhere. Modules play a pivotal role in the overall Drupal experience. The reason being, a module is a compact set of PHP, JavaScript and/or CSS files that provide a framework to strengthen the functionality of the website.

When you are starting a new Drupal project, there are certain modules that you need to consider installing right away irrespective of what sort of industry type that is for or what will be the key functions of that website.

Therefore, in this blog, we have rounded up some of the most common Drupal modules that are really helpful and can be used in almost all cases. So, without any further ado, let’s get right into the article. 

Modules for site-building

Admin Toolbar

The Drupal Admin Toolbar is a very light module and allows faster and easier functioning to all administration pages. The module is highly capable to improve the default Toolbar (the administration menu at the top of your site) by transforming it into a drop-down menu. You can also create simple icons using Admin Toolbar which offers quick shortcut links to make for a more mobile-friendly and receptive experience.


The PathAuto module is a must-have module in every Drupal project. It is one of those tools that has got your back when you experience some not-so-fun work. Not only this, but the module also does it quickly and effectively. The Drupal PathAuto module helps in generating SEO friendly and well-structured URLs. Site admins can also change the pattern system by changing the tokens it uses. Read the ultimate Drupal SEO guide for 2020 to know more about Drupal’s SEO features.


A Token is a fundamental element in any Drupal website. This Drupal module provides additional tokens (which are not supported by core), as well as a UI for browsing tokens. In addition to this, the Token module auto generates metadata about a website that further helps in search engine optimization (SEO). 

Inline Entity Form

Originally created for Drupal 7, the Inline Entity Form is a popular Drupal module that provides a widget for inline management (creation, modification, removal) of referenced entities. The module allows you to create multiple types of content (or other related entities) from a single form and is primarily used to let you manage order items from the order add / edit form.  


The Drupal 8 Paragraphs module is an author-friendly extension that allows content authors and editors to create flexible and structured content at ease. Using drag and drop functionalities, Paragraphs makes it possible to combine several different fields into a custom reusable element. Moreover, you can add various paragraphs field types such as images, text blocks, quotes, slideshows, videos and so much more.

Advanced Aggregation

The Advanced CSS/JS Aggregation module allows you to enhance the frontend performance of your site by minimizing the CSS and Javascript. The module has the capability to reduce the delivery of the number of files as well as their size. This in turn augments the download and display speed of the entire content of a web page. Not to mention, Advanced CSS/JS Aggregation collects and stores each resource category, thereby consuming less amount of data to download the page. Read Drupal’s effect on high-performance websites to understand more about Drupal’s performance optimization capabilities.


The Metatag module plays a significant role as it allows you to automatically provide structured metadata aka "meta tags", about a website. If used in the right manner, Metatags can help you reach your audience in the most natural manner. In addition to this, the module provides support for meta tags (Open Graph Protocol from Facebook, Twitter Cards from Twitter) that have the power to control how content will appear when shared on social networks.


The most important part to build a site right is to involve the Redirect Drupal module. The module allows the creation and management of redirects using a simpler user interface. In order to sustain in the long-term, the website must have the ability to create and maintain redirects. Well, this function can be handled perfectly by the Redirect module which creates manual redirects and maintains a canonical URL for all content, redirecting all other requests to that path.


Inspired by Mac apps Alfred and Spotlight, the Coffee module allows you to navigate the admin area using your keyboard which is always much faster than a mouse. Just type (alt + D) or (alt + shift + D) using a simple keyboard shortcut, depending on your internet browser, and you are all set to search for the page you are looking to visit, and it will source it in the fewest characters possible.

Entity Reference Revision 

The core Entity Reference module forms the basis of the Entity Reference Revision module that allows you to reference a specific revision of an entity. This Drupal module is presented form the team that brought the Paragraphs model in existence. Besides this, it adds an Entity Reference field type that has revision support and can work in favor of modules like Paragraphs and Inline Entity Form.


Webform Drupal module is one of the most powerful modules responsible for making forms and surveys available for your users to submit. Once a customizable email is sent to administrators and/or submitters, results can be immediately taken out into Excel or other spreadsheet applications. Moreover, Webform also provides some basic statistical reviews and has an extensive API in-store to further expand its features.

Simple XML sitemap

Search Engine Optimization (SEO) has always been the topmost priority for the Drupal community and therefore tons of modules are created to improve the SEO ranking. Specifically made for Drupal 8, the Simple XML Sitemap module adheres to google’s latest standard and supports multilingual content which makes it even more futuristic and flexible. It also provides an API that allows you to customize links and configurations.

Field group

Field group as the name suggests group fields together which cleans up content types and reduces the burden which falls directly in the lap of content editors. All fieldable entities have the possibility to add groups to wrap their fields together. The main intent of this particular Drupal module is to allow grouping similar fields into tabs, thereby making it easier for people to visualize and deal with the content on the page. 

Fast 404

Drupal suffers from expensive 404 errors which consume more memory of the server to load a page than it should take. This is where the Fast 404 module comes into the picture. Fast 404 Drupal module reduces expensive page rendering without the urge for an additional module. By enabling this module, you can decrease waste bandwidth and server load on-site. In other words, you can deliver 404 errors using less than 1MB of memory on your server. 

403 to 404

403 to 404 refers to a simple Drupal module that emits a 404 error when a user tries to access a page that they don't have access to view.

Modules for development


Being a web developer who is looking for some tools for debugging, the Devel module can be really powerful that any developer would love to improve efficiency. This module is like a compendium of tools with functions that are handy. For example- the ability to create dummy users, nodes, and taxonomy terms as well as easily view information about APIs, cache effectiveness, Views, database queries, and more.

Devel PHP

The Devel module is used to remove the execute feature from the Drupal module. The Devel PHP module allows you to re-use this feature provided by the Admin toolbar by re-adding the executive tool as an external feature. 

Backup and Migrate

Creating a regular backup is an important step to ensure that you don’t lose your data. Drupal is no different and understands this concern. You will be glad to know that Drupal has a dedicated module to look after backup issues that software might face. This module is popularly called the Backup and Migrate module which allows backing up databases, files, codes, etc. This Drupal module is easy and is highly recommended for beginners. Go through the ultimate guide on Drupal 9 to plan a better migration path.

Twig Tweak

Twig Tweak Drupal module is a small module that is accountable to provide a Twig extension with some useful functions. Along with it, the module allows filters that hold the potential to improve the development experience.


Ctools is an important module in the Drupal framework which basically is a suite of APIs and tools that can make code readily available with a view to improving the developer experience. This suite comprises a module called the Page Manager who is responsible for managing pages. The usage of Ctools varies from people to people and is highly dependent on the person using it. 

Modules included in core and disabled by default


The Media module is held responsible for the management of creation, editing, deletion, settings, and display of the media entities. The media items generally include images, documents, slideshows, YouTube videos, tweets, Instagram photos, etc.

Media Library

Have you ever wondered if a tool can help you manage media at ease? No? Well for your notice, Media Library is a media management tool that can help you find already existing on your site. Not to mention, the tool can help you make additions of new media items to an entity reference field, or embed media into your content via a text editor. This Drupal module is used in sites which is rich in content, where the media assets can be reused.

Layout Builder

Drupal Layout Builder is a unique module that allows content editors and site builders to create a powerful visual design for displaying content, that too with ease. Using this module, developers can easily and conveniently build page layouts using a UI and allows embedding and linking any elements in layouts (fields, views, menus, and forms). Layout Builder in Drupal 8 gives you access to add/remove sections to display the content using different layouts, and customizing your pages based on the requirements. 


JSON: API is intended to minimize the number of requests and the amount of data transferred between clients and servers efficiently. This Drupal module is of pre-determined nature where everything is pre-fixed. In other words, the possibility of making amends in this module is zero. Be it about the location where the resources will reside, or what methods are immediately available on them. Not to mention, JSON: API provides access control to Drupal Core's permissions system. 


The GraphQL is a perfect fit for anyone who wishes to raise a query or update/delete any content or configuration. This can be done with the help of the official GraphQL query language.  The GraphQL module is considered as one of the finest as well as a mightier tool of Drupal which can be used as a foundation for building your own schema through custom code or you can use and extend the generated schema using the plugin architecture and the provided plugin implementations form the sub-module.

RESTful Web Services

Inspired by Drupal 7, the RESTful web services module relies on the Serialization module in Drupal 8 core to allow a customizable and extensible RESTful API of data that is managed by Drupal. Surprisingly, this Drupal module provides you to create an interaction with any content entity (nodes, users, comments) as well as closely monitor the database log entries.

Core Multilingual modules

A multilingual site allows developers to access Drupal in a language that they prefer. For this obvious reason, the multilingual component feature of Drupal has become an ideal choice for both businesses and developers. Presently, Drupal offers 4 different modules for language and content translation which can be enabled as per the need of the website.  

Language Module:

This is the base module that is required for any non-English or multi-lingual site. It provides users access to arrange languages and apply languages to content.

Locale (Interface Translation) module:

This particular Drupal module is responsible for translating the built-in user interface, your added modules, and themes.

Content Translation module:

This module provides the translation of content entities. Further, it lets you translate your site content, including pages, taxonomy terms, blocks, etc., into different languages.

Configuration Translation:

It is responsible to allow translation of the text that is part of the configuration, such as field labels, the text used in views, etc.


The Migrate module is used to provide a flexible framework for migrating content into Drupal from other sources. For example- converting a site from another CMS to Drupal. Besides this, this module can be easily extended for migrating other kinds of content too.  

Migrate UI

Drupal Migrate UI is responsible to provide the browser user interface (UI) for Migrate Drupal. This Drupal module provides a user interface for editing and configuring migrations to Drupal 8.


And now that you have reached the end of the blog, we expect you to have some really solid suggestions on your radar. Most importantly, make sure that whatever you figure out should be the best fit for your website and your workflow. 

Think you are ready to take a plunge into Drupal? Contact us at [email protected] and our experts will help you plan and launch your site with ease.

Sep 10 2020
Sep 10

With the Drupal Book module, it is possible to create collections of related pieces of documents presented in a hierarchy. This format is suitable for handbooks and tutorials, for example.

Notice: This module is not for creating ebooks.

The Book module comes by default (disabled) with Drupal core modules, so there is no need to download or install anything additional on your system.

Keep reading to learn how to use this module!

How to use the Drupal book module

Step #1. - Enable the Module

  • Click Extend.
  • Scroll down and enable the Book module.
  • Click Install.

How to use the Drupal book module

Step #2. - The Book Content Type

  • Click Structure > Content types.

There is a new content type in addition to the 2 Drupal default content types called the Book page Content type.

  • Click Manage fields.

How to use the Drupal book module

Add an image field with the default settings.

How to use the Drupal book module

  • Add a link field.
  • Give it proper title.
  • Click Save and continue.

How to use the Drupal book module

  • Set the allowed number of values to unlimited.
  • Click Save field settings.

How to use the Drupal book module

  • Click Manage display.
  • Hide the image label.
  • Rearrange the fields.
  • Click Save.

How to use the Drupal book module

Step #3. - The Book Outline

  • Click Structure > Books.

How to use the Drupal book module

You will be presented with a list of book outlines. At the moment this list is empty, since we haven’t created any book yet.

  • Click the Settings tab.

You have two settings here:

  1. the content types allowed in book outlines (you can select multiple options here)
  2. the default content type (one value allowed) added when you click the “Add page” link
  • Leave default values
  • Click Save configuration.

How to use the Drupal book module

Step #4. - Create a Book

  • Click Content > Add content > Book page
  • Enter a proper title and body text.
  • Add a proper image.
  • Click Book Outline on the right column.
  • Select Create a new book from the dropdown.
  • Click Save.

How to use the Drupal book module

How to use the Drupal book module

When seeing the published node, you will notice an extra tab on the top called Outline.

How to use the Drupal book module

You can click here at any time and rearrange the outline of this particular node within the book hierarchy. This is also possible through the Books outline interface we saw on the step before.

How to use the Drupal book module

Since we have created only the main page of our book, you will not be able to configure anything here.

  • Click Update Book outline.
  • Scroll down to the bottom of the book page.
  • Click Add child page

How to use the Drupal book module

This will take you directly to the Book page edit screen.

  • Add proper content
  • Click Save.
  • Change the weight to -15 (if you will have more than 16 child pages, you will have a problem to place the last one at the end) as a security measure.

As a matter of fact, this is more a quirk, since you can rearrange book pages through a drag and drop interface within the book outline.

How to use the Drupal book module

  • Click Save.

How to use the Drupal book module

Let’s add some more pages to “modelate” the structure detailed on the image. Use the column on the right of each node you edit.

How to use the Drupal book module

How to use the Drupal book module

When you have finished, take a look at the published nodes.

How to use the Drupal book module

Nodes with child pages, will display a list of links containing them. Furthermore you have on the bottom, three additional links. Two of them point to the previous and next articles according to the sequence on the hierarchy.

The link labeled “Up” takes you to the corresponding parent page, that is, one level up.

To check the finished outline,

  • Click Structure > Books > Edit order and titles.

You can rearrange the structure and order of your book here.

  • Click Save book pages after you are finished editing.

How to use the Drupal book module

The book navigation links can be styled through the css class .book-navigation or through its particular id.

How to use the Drupal book module

I hope you liked this tutorial. Thanks for reading!

About the author

Jorge lived in Ecuador and Germany. Now he is back to his homeland Colombia. He spends his time translating from English and German to Spanish. He enjoys playing with Drupal and other Open Source Content Management Systems and technologies.
Sep 08 2020
Sep 08

The Drupal Association is running an election to one seat for the board of directors from the community. I asked this questions to all candidates.

I believe that engagement with the Drupal Association is not optional if you want to participate in the Drupal project in any way.

  • The Drupal Association manages drupal.org (ticketing + releases + documentation + API docs + outstanding communications + translations + security coverage). This is not optional for any individual.
  • The Drupal Association manages DrupalCon. This is optional for individuals.
  • The Drupal Association oversees the CWG. This is not optional for individuals.

Maybe some day engagement with the Drupal Association will be optional, but my opinion is that it is not optional today. This is why I think that the Drupal Association cannot act only in its own best interest, but it needs to act on the best interest of the people contributing to the project. That is regardless of their affiliation and/or feelings towards the association.

On that vein I asked all candidates this:

Excuse me if I make no sense in my questions. I am no lawyer either, and the U.S. is not my home country. My questions are framed around legal figures, however I only intend to get a sense of what your values are as a potential director.

The Drupal Association (DrupalCon Inc.) currently declares itself as a 501(c)(3) (as per 2018's tax filing). According to the IRS website:

A section 501(c)(3) organization must not be organized or operated for the benefit of private interests, such as the creator or the creator's family, shareholders of the organization, other designated individuals, or persons controlled directly or indirectly by such private interests. No part of the net earnings of a section 501(c)(3) organization may inure to the benefit of any private shareholder or individual. A private shareholder or individual is a person having a personal and private interest in the activities of the organization.

(emphasis of my own)

I sense a lot of effort in promoting business using Drupal in what the Drupal association does (my perception might be wrong). From my limited understanding, this is typical from 501(c)(6) organizations (Business leagues, Chambers of commerce, Boards of trade, ...). For context, the Linux Foundation declares itself as 501(c)(6) (as per 2018's tax filing).

My questions are:

  1. Do you feel the current Drupal Association is living to the 501(c)(3) spirit? (I am not asking about the legality, but the spirit).
  2. Should a voting arise: do you lean towards promoting the project itself and stay as a 501(c)(3)? or do you think that promoting business with Drupal is the best course of action and, therefore, the Drupal Association should become a 501(c)(6)?

My questions are geared towards: how will you position yourself in the balance between promoting the common good vs. fostering healthy business using Drupal? But I would love to get specific answers to the two questions above.

Sep 07 2020
Sep 07

In a typical scenario of staging or production, developers seldom have the option to use the debugger so they turn to the logging functionality to resolve system issues.

One of the most underutilized tools at the developer’s disposal, ideally, logs should be the first thing that developers should look at when trying to resolve a system error or spending time tracking down a gnarly bug.

This blog will walk you through the Drupal module, Monolog, that logs the messages of the site (words, errors, notices, & warnings) in the file to fix issues swiftly without impacting the site performance. Find out how it can be installed and how it works.

The ABC of Monolog Module

In a typical scenario, a module trying to log the debug information in the database table has to connect to the database every time, making the whole process tedious. Additionally, the gradual increase in table size starts hampering the site performance.

Contrary to this, another way of logging the site messages without impacting the site performance is by saving these messages in the file. Whenever the site will be down due to fatal errors, the messages can be checked from the log file.

Monolog is one of the modules in Drupal that saves messages (words, errors, notices, warnings) in the file to save the system from the overhead of buffering logs and network errors.A laptop showcasing Drupal logo and error


 The Monolog module integrates Drupal with the Monolog library to   offer a better logging solution. It can send logs to files, sockets,   inboxes, databases, and various web services. In a nutshell, it allows   you to define a logging pipeline. 

 When it logs something, it dispatches it along that pipeline to       whichever files, services, emails, etc. you have defined.

Benefits of Monolog Module

It offers following benefits

  • Enhanced system performance

Monolog logs system messages as per the defined file system/structure, thereby enhancing the overall performance of the application and system.

  • A multitude of handlers

The multiple handlers defined in monolog can be integrated hassle-free to send log messages into an email, Slack, etc.

  • Easy to install

The Monolog module is easy to install as it does not require any external library and server for configurations

  • Complete watchdog integration

The Monolog module consists of full watchdog integration, making it easier to work with core and contributed modules out of the box.

  • Configurable logging levels

The Monolog module is PSR-3  (PHP Standards Recommendation). As a result of which, it enables interoperability to help you change the logging library for another that implements PSR-3 without too much headache.

Why is Monolog Important?

Drupal core logging offers minimal features to developers for defining a log message type, “attention level,” and then saving all the log messages to a destination, usually Syslog; even when the logging can be redirected to another destination. All the log messages, including those where critical problems are listed, are stored at the same place with trivial logged information.

Whenever the site encounters an unexpected issue, site owners try to find the cause behind it. Though all the information is written to the log system by Drupal, it quickly gets overwritten with newer log messages on an active site. Once it happens, it becomes difficult to recover because they all stay in the same log stream along with PHP errors and warnings and all the other types of system logs.

This is why the Monolog module comes handy. With it, you can send critical logs to email, HipChat, or NewRelic, normal logs to a persistent backend, and debug to a simple pre-defined log file.

The clear separation of information by concerns extensively improves access to the specific log information that is relevant and useful in any given situation. 

In fact, you can use this module to write operational logs related to the content and user actions to a particular stream so the site owner can gain access to that information instantly without going through all the unnecessary or irrelevant log messages.

At the same time, a system administrator can see all system logs on a different stream, and receive critical messages only via email.

How to Install the Monolog Module?

The monolog module can be installed by using the composer.

Black background with commands

The Monolog module does not have any configuration form in the backend, and all the configuration is done in services files. You can follow the below-mentioned steps for the same-

  1. Create a site specific services.yml (monolog.services.yml, for example) in the same folder of your settings.php and then add this line to settings.php itself:

$settings['container_yamls'][] = 'sites/default/monolog.services.yml';


2.   The simplest configuration that allows Monolog to log to a rotating file could be-


default: ['rotating_file']
monolog.processors: ['message_placeholder', 'current_user', 'request_uri', 'ip', 'referer']

class: Monolog\Handler\RotatingFileHandler
arguments: ['private://logs/debug.log', 10, 'monolog.level.debug']

3.  This configuration will log every message with a log level greater (or equal) than debug to a file called debug.log located into the logs folder in your private file system. Since data will be rotated every day, the maximum number of files that you can keep would be 10.

Role of Handlers & Processors in Monolog’s Functionality

Handlers are accountable for saving the message to the file, database, or sending it to a mail. In Drupal Monolog’s default monolog.services.yml, several handlers are defined, for instance, monolog.handler.browser_console, monolog.handler.chrome_php, monolog.handler.fire_php, etc. These are registered as services in the Drupal Service Container. You can define as many handlers as you need. Each handler has a name (that should be under the monolog.handler. namespace), an implementing class, and a list of arguments. 

Mapping among logger channels and Monolog handlers is done by defining parameters. Under the monolog.channel_handlers parameter, it is possible to determine where to send logs from a specific channel. The default mapping should exist as the fallback one. In the previous example, all logs were sent to the monolog.handler.rotating_file handler. 

Note -  Only the handler name is used instead of the full-service name.

The following example will send all PHP specific logs to a separate file:


default: ['rotating_file']
monolog.processors: ['message_placeholder', 'current_user', 'request_uri', 'ip', 'referer']

class: Monolog\Handler\RotatingFileHandler
arguments: ['private://logs/debug.log', 10, 'monolog.level.debug']

It method will write the corresponding message to the private://logs/php.log file.

On the other hand, a processor is a PHP callable used to process the log message-

monolog.processors: ['message_placeholder', 'current_user', 'request_uri', 'ip', 'referrer']

Monolog can alter the messages being written to a logging facility using processors. The module provides a set of already defined processors to add information like the current user, the request URI, the client IP, and so on.

Processors are defined as services under the monolog.processor. namespace. We can also use the Devel module or Drupal Console to find all of them.

'Message_placeholder': text of message

'Current_user' : logged in user

'Request_uri' : requested url

'Ip' : ip address of user

‘'Referer': url from where the user has arrived to the page.

code written in black background

How to log custom messages in a custom module using Monolog? 

To log custom messages, add below-mentioned code in your custom module-

\Drupal::logger('php')->debug('debug message');

It will successfully write the corresponding message to the private://logs/debug.log file.


\Drupal::logger('php')->debug('Data added using cron');

code written in black background


The Monolog module offers complete flexibility to help you capture the right information and leverage it for troubleshooting and monitoring. Once you have configured your applications to log all the useful information, you can send these logs to a platform where it can be used for in-depth analysis and collaborative troubleshooting.

Install the module for speedy development and resolve errors hassle-free.

Sep 04 2020
Sep 04

Oftentimes projects need a way to serve multiple domains from the same installation or from the same codebase. In Drupal we have several ways to accomplish this, and this post will describe some architecture options that make this possible, as well as the relevant factors that can help you decide which option provides the best ‘fit’ for the implementation.

We’ll be looking at four distinct implementation choices: Classic Drupal Multisite, Domain Access or Mega Site, Distribution Profile, and an offshoot of the distribution profile called Custom Upstream.

Classic Drupal Multisite

In a classic Drupal multisite architecture, the individual websites share code (the Drupal core, modules, and themes), but each website has its own database so they do not share content, configuration, or settings. Each website can also have some extra modules / themes under its own subdirectory in the same codebase.

  • Single codebase:
    • Onboarding developers and administrative tasks are easier with a single codebase.
    • Code and library updates only need to be done once.
  • Some degree of customization is possible, because each site has its own configuration, and it can have it’s own custom theme and modules.
  • Shared features can be accomplished by using Feature modules: features modules can be shared across the sites, and then individual sites can import the configuration from it. Another option would be to use the Config Split module to segment what configuration is shared across sites and what should be overridden per site.
  • Less hosting costs: a single hosting plan that supports all of the traffic from all of the sites might be cheaper than hosting per individual site.
  • If a site decides to customize functionality provided by a Features module, then it would lose any further updates to the module, as they have deviated from it. This is one of the greatest risks of a multisite setup, because if sites start diverging in functionality, it makes no sense to keep maintaining a single codebase.
  • All developers working in the team have access to the codebase that affects all of the sites. This implies a high level of trust in the whole team, and does not allow for separation of concerns, meaning that while team members could be assigned to work only in a particular site, the codebase architecture implies it cannot be enforced on a code level.
  • Heavy maintenance:
    • Configuration and updates still need to be run once per site and saved back into code configuration (in each site’s config folder).
    • Deployments in this architecture need to happen “all at once” for all the sites, which can potentially be chaotic (there is no simple “revert” a commit for a single site, for example).
    • Scripts are a frequent solution that comes up to automate maintenance tasks across the sites, which means more devops time.
  • Single point of failure:
    • Since there is a single server hosting all of the sites, a traffic spike can affect all of the other sites. This is mitigated if most of the content is static (for anonymous users), because it can be cached by a CDN which can deliver the (cached) pages even if the server is down.
    • A code error has the potential to affect all of the sites.
  • As a note, this setup is not supported by Pantheon, because they don’t allow multiple databases per hosting plan.

A shared codebase setup would be most beneficial if all of the sites are using similar modules and settings. “Snowflake sites”, i.e. sites that need lots of special customization to code or config, can rapidly increase the risk of technical debt in an architecture that was meant to maintain similar sites.

Mega Site (Domain Access)

This architecture consists of a single codebase and single database/installation. The Domain Access suite of modules provide functionality that allows serving multiple sites (domains) from this setup, and specifying which pieces of content belong to a particular site, or are shared across some or all of the sites.

  • Maintaining a single Drupal installation.
    • Updating a single site is faster and easier to test (vs once per site in a multisite setup).
    • Maintaining configuration and functionality is straightforward (no need for Feature modules).
  • Admin users can effortlessly manage all content from one platform.
  • Content and users can be shared across multiple sites (if needed).
  • Allows sharing the same features and functionality to all affiliate sites.
  • Single point of failure. A single hosting plan for all of the sites. This is mitigated if most of the content is static (for anonymous users), because it can be cached by a CDN which can deliver the (cached) pages even if the server is down.
  • Some contrib modules, and custom or complex functionality might need custom development to make sure they are compatible with the Domain Access module. We call this “glue code”, and a lot might be needed depending on the complexity of the project.
  • If a site needs to be “taken away” into its own hosting plan, it’s not straightforward. (note: here we're referring to scenarios where a site might be spun off to another owner because it needs to pay for its own hosting for funding or other organizational reasons.)
  • Requires strict governance enforcing a policy of no-exceptions (or extremely few). An exception would be a functionality or config on a site that doesn’t follow the rest. Each “exception” adds complexity to the site, and if left unchecked, can quickly become a maintenance nightmare.

A mega-site setup makes sense if sites will share content and/or users, and if all of the sites will have the same functionality, content types/data structures, and will only differ in limited configurations or theme variations, as in a family of affiliated sites.

Distribution Profile

A Drupal distribution can also be created and maintained. A distribution typically contains a declaration of the required modules and libraries, custom theme and custom modules, and configuration that gets imported during install, maybe even default content. Updates to configuration can also be provided via Features modules as described in the multisite section. Under this use case, each site has its own codebase that includes the distribution profile, and is hosted under separate hosting accounts.

Some well-known distributions are Commerce Kickstart, Lightning, Open Social, etc. While these are large projects that aim to provide a generic starting point for projects, a custom distribution profile can also be created to address the needs of a collection of sites with similar functionality, passing the main burden of development to a centralized team of devs in charge of providing updates and new features.

  • Sites are independent: Code errors or traffic spikes on one site don’t affect other sites.
  • Flexibility: They can be customized more easily (as long as they don’t override configuration provided by the base distribution, so they could still receive functionality updates).
  • Again, sites overriding features provided by the distribution means they won’t be able to update to the latest bug fixes or new functionality provided in the profile.
  • This architecture involves maintaining the distribution codebase, plus each of the sites.
  • Maintaining a distribution is also hard work. Even more work and attention need to be dedicated if the distribution will be published on drupal.org, as aspects of dealing with security updates and bug reports are more relevant.

A distribution profile works well if the sites are all starting out the same, but they are expected to grow in different directions. Maintenance work is expected and independent for each of the sites. A typical scenario is a university distribution profile, where each department can have its own independent site.

Custom Upstream

This involves maintaining what is essentially a distribution profile directly from a code repository, instead of making it available in drupal.org. Advantages and disadvantages are similar to the distribution profile as well.


A custom upstream can be useful for companies that maintain a base installation profile, and expect to do bespoke development work on each site in order to accommodate different user requirements, transactions or other scenarios from site to site.

For further reading:

Sep 04 2020
Sep 04

As you’ve probably heard - merge requests via GitLab are finally here on Drupal.org.

On July 13th, the week of DrupalCon Global, we began the beta process allowing projects to opt in to using issue forks and merge requests. More than 100 projects have opted in so far. We’re getting close to enabling issue forks and merge requests for all projects, but we have a few more steps to go. In particular, we want to make sure that core contributors can test issue forks and merge requests for core.

As part of the beta program, we’re going to enable these features on specific core issues - nominated by core contributors as good issues to test these features.

Are you a core contributor who would like to try the new workflow on an issue?

Nominate your issue for the merge request beta

Contributors should opt-in issues which are:

  • Well-scoped.
  • Likely to be completable in days or weeks, rather than weeks or months.
  • Issues with enough complexity to exercise the forks and merge request system.
  • Issues that they themselves intend to work on.

Once these core contributors have signed off on the issue fork/merge request workflow - we’ll be enabling these features across all projects.

Keep your eye on this blog for further updates!

… one more thing

Tugboat.qa (a new venture by Drupal Association Supporting Partner Lullabot) are donating an enterprise license of their tool, which generates automated deployment previews of software. We’re going to be enabling this for core issues as part of our beta process as well, to see if these development previews can help accelerate core contribution, and what resources this tool might require in our infrastructure. Our thanks to Lullabot for the partnership!

Sep 03 2020
Sep 03


The requirement

In a majority of cases, document (and on a bigger picture, media) management is done on Drupal directly. Especially now that there are the Media and Media Library modules in Core, media management in Drupal has received a lot of improvements during the last years.

But sometimes, you need to be able to connect to a DMS (document management system) for one or several of the following reasons:

  • The tool is already in place into your customer’s information system architecture.
  • This allows you to delegate access control management on documents to this external tool. And therefore keep your Drupal website “simple”.
  • DMS, by their specialization/name/designation, have more advanced features than Drupal on documents:
    • Versioning,
    • Metadata,
    • Edition,
    • Etc.

The project driving our contribution on the module was to develop an intranet for storing documents and delivery forms on an Alfresco DMS, using Drupal as a simplified user interface to interact with the documents in the DMS.

What is CMIS?

“CMIS (Content Management Interoperability Services) is an open standard that allows different content management systems to interoperate over the Internet.“

CMIS query example:

CMIS query examples

As you may have guessed, the CMIS API module has been used as it provides the link between Drupal and Alfresco (or any CMIS compliant system).


Module’s history

Drupal 7 and before (hypothesis)

There is an ecosystem of CMIS modules already present on Drupal.org, here is an overview of its:

  • CMIS Alfresco (D6)
    • Deprecated in favor of the CMIS API module.
  • CMIS API (D7)
    • Initially an initiative (maybe partnership?) between Acquia and Alfresco because a lot of people involved indicate working at Alfresco on their drupal.org profile.
  • CMIS Views (D7)

Now we will focus on CMIS API as it is the one providing a generic implementation and tools for other modules.

Drupal 8

There were 2 Drupal 8 branches on the CMIS API module :

  • 8.x-1.x-dev
    • Port of the Drupal 7 version but non-optimal usage of object oriented code provided by Drupal 8 (no service, object non easy of use (DX), …)
  • 8.x-2.x-dev (our contribution started from this branch)
    • Use a new version of the dkd/php-cmis-client library (Guzzle 6 compatible)
    • Codebase stabilization (Drupal Coding Standard, deprecations removal) 
    • Add new features

We focused on the 8.x-2.x branch and among fixing coding standards, removing deprecated code, fixing some bugs, we added new features. And now we will see the features of the module.


Current features

CMIS connection

The first thing to do with the CMIS module is to configure a connection to the DMS.

CMIS Connection

We added the “CMIS folder ID” setting to get a file browser already opened from this folder (new).

Sub module: CMIS Alfresco Auth User (new)

When the user logs in using Drupal login form, the username and password are also sent to an Alfresco endpoint to authenticate on Alfresco too and retrieve an authentication “ticket”.

Authentification ticket 1

Authentification ticket 2

Authentification ticket 3

This allows you to use different users for the CMIS connection without having to define a CMIS connection for each user.

File browser

The main feature of the module is to provide a file browser allowing users to view, upload or delete folders and documents.

Now the access control if the user can upload or delete a file / create or delete a folder, is no more using a Drupal permission but checking permission in the DMS directly (new).

CMIS Browser

CMIS query page

A page to make CMIS queries directly without UI limitation.

Request CMIS

Field formatters:

There is a CMIS field type that allows you to select a CMIS document or folder. This information can be displayed using two field formatters:

  • Link to the CMIS document
  • File browser starting on the selected folder (new)



Next steps

The module currently provides some nice features that may answer a lot of needs. But the current codebase is difficult to work with, so adding new features is hard, or impossible.

Therefore to ensure the module will be and stay healthy, we may be doing the following steps which are a mix of refactoring and features addition:

  • Rethink codebase’s architecture:
    • Implement services
    • Add a connections factory service
    • Routes: to have proper non-ajax support if needed and better organized routes
  • Rethink how the display is done to ease the theming and overrides
  • Audit the UI strings
    • Translating strings in French highlighted that even in English some UI strings are not correct
  • Refactor authentication part
    • Support Nuxeo, etc.
  • Implement sort and pager on the file browser
    • Depends on the PHP CMIS Client library
  • Media integration
    • Import a CMIS document as a Media entity so it can be used as any “standard” image for example
  • Implement automated tests
    • The setup will be hard to do


Thanks to Ian Norton for granting us access to the CMIS API module.

And thanks to our customer’s project needing improvements on the CMIS API module to have permits us to contribute back.

Now the Drupal 8 version of the CMIS API module is back on track and by releasing the 8.x-2.0-alpha1 version, we hope that this will help raise the Drupal 8 module’s usage and gather momentum.

PS: On Tuesday, September 1st, Florent Torregrosa held a meetup on various topics such as Entity Share V3, CMIS and File Extractor. You can find his article here [FR] and the presentation slides here [EN]

Aug 31 2020
Aug 31

What We're Doing Here: Webforms and Third Party Integration

In Drupal 8, the Webform module can do a lot out of the box. It can do even more with the multitude of its contributed modules. But every now and then a situation arises where you need to get into the guts of create some custom webform magic to get the job done.

Overview: Submitting Results to a Third Party Site as a Query

We will look at one way to integrate the power of webforms with some third party integration and custom code. We are going to have a webform modify the submitted results into a query string, and redirect the user to a third party url with the query attached. We will use a remote submission handler to tell Drupal that when the form is submitted, it also needs to submit those values to a remote, third party URL. In our case, the third party site is bookdirect.com, the client is a Destination Marketing Organization (DMO) and we need to format the submitted values to work with their jackrabbit api. Ultimately, we are using a Drupal webform, to send the user to Bookdirect/Jackrabbit with their lodging search filled in.

Our remote submission handler will define our base URL, but outside of that, the handler doesn't give us much else to do what we need to do in the UI. And while we wanted to give our client the freedom to add more fields to the webform in the future, we wanted to keep it simple for them so they would only have to add the correct base URL and not have to worry about any code. 

For our form, it wasn't necessary to save any submitted results, however, we are going to use a webform api hook that fires right after a submission would normally be saved. That hook is hook_webform_handler_invoke_alter and hook_webform_handler_invoke_METHOD_NAME_alter.

More specifically, since we want to act after saving and everything else has ran, the hook we want is: 

Even if the results are set to not save, webforms will still trigger this "post save" hook. Versions of these hooks are: 

  • hook_webform_handler_invoke_pre_create_alter
  • hook_webform_handler_invoke_post_create_alter
  • hook_webform_handler_invoke_post_load_alter
  • hook_webform_handler_invoke_pre_delete_alter
  • hook_webform_handler_invoke_post_delete_alter
  • hook_webform_handler_invoke_pre_save_alter
  • hook_webform_handler_invoke_post_save_alter

Looking at the method name in these hooks, you can see when they act on a webform submission. For example, if you need to alter a value before the submission is initially saved, you can use hook_webform_handler_invoke_pre_save_alter.

How We're Doing It: 10 Steps

Even though this example is based on working with Bookdirect, I will try to keep the code somewhat generalized so that you can hopefully adjust it to your needs.

1. Create a simple webform

For our form, we required a date form item with the name of start_date, a date form item with the name of end_date, and a taxonomy select form item with the name lodging_category, where we choose from a list of terms. Use any form items you need and adjust the code as needed. I will show you ways to alter those field values before passing them into our remote url query.

2. Add a remote submission handler to your webform

Once you have your webform, you need to add a remote submission handler. Go to your forms Settings tab, then click on Emails/Handlers. Click on Add Handler. Select Remote post handler from the modal and fill in the Completed URL as the base URL that we will be submitting to. Remember to Save your handler. You can also select or deselect what values will be submitted. For our case we only need the 3 form items. We will add some of our own values in the submission query later.

3. Make a module to hold your code

Create a new module or use an existing custom module. The hook and code will need to go into the MYMODULE.module file of your module. For instructions on how to create a module, please see the Drupal.org manual page on module creation

4. Declare your hook

In your MYMODULE.module file, add our hook snippet

 *  Implements hook_webform_handler_invoke_post_save_alter().
function MYMODULE_webform_handler_invoke_post_save_alter(\Drupal\webform\Plugin\WebformHandlerInterface $handler, array &$args) {


Make sure to adjust the MYMODULE name with the actual name of your module

5. Setting up some variables

To make things a little easier to play with, we will create some variables to help define our data and info that we will work with. Inside of your new function add:

$webform = $handler->getWebform();

$webform_submission = $handler->getWebformSubmission();

$webform_id = $webform->id();

$handler_id = $handler->getHandlerId();

6. Narrowing down our code

And since we want to make sure we only run on our desired webform and with our remote submission handler, add the following snippet after the variables:

    // Our magic goes here  

(make sure to update the IDs above with the actual ID's of your webforms.

7. Get your handler configuration

To get the configuration setup of your handler, use:

$configuration = $handler->getConfiguration();

To pull the settings out of that configuration, step into the settings array and look for the completed_url value.

$bookdirect_url = $configuration['settings']['completed_url'];

8. Alter your data

We need to alter the start_date data from what webform submits (MM-DD-YYYY), to what bookdirect requires (MM/DD/YYY). We will use the getElementData() on the webform submission data to pull out the initial submitted value. We will make our change to that submitted data, and then apply the altered value back into the submission array using the setElements() method. The same alteration needs to be done to the end_date field. 

$start_date = $webform_submission->getElementData('start_date');
$start_date = explode('-', $start_date);
$start_date = [$start_date[1], $start_date[2], $start_date[0]];
$start_date = implode('/', $start_date);
$webform_submission->setElementData('start_date', $start_date);

Another alteration we need to make for our example bookdirect form is to take the taxonomy term value and switch it out with a field value on that term. Our taxonomy terms have term id's that the webform uses in the select widget, but we need to submit a bookdirect ID that corresponds to those taxonomy terms. You can use this concept to switch out field values with different field values from different entities on your webform submissions.

// First check if a value was submitted.
if ($lodging_term_id = $webform_submission->getElementData('lodgingID')) {
    // Load up our term to test if it has a book direct value
    $lodging_term = \Drupal\taxonomy\Entity\Term::load($lodging_term_id);
    if ($lodging_term->hasField('field_bookdirect_id') && $bookdirect_id = $lodging_term->get('field_bookdirect_id')->first()->getValue()) {

        // If it has a bookdirect field and a value, switch out our tid value with our bookdirect ID value.
        $webform_submission->setElementData('lodgingID', $bookdirect_id['value']);

9. Build your query

Get our submitted data.

$query = $webform_submission->getData();

Alter values into another key. Maybe the fields were created before you knew what the required name should have been for the final destination. In this example, start_date is now supposed to be checkin, but we can't easily change it on our webform.

$query['checkin'] = $query['start_date'];
$query['checkout'] = $query['end_date'];

Add some static values to our query that were not part of our submitted webform values. Since this is a bookdirect example, these are values that bookdirect requires, but we don't need or want to add to our form directly.

$query['widget_id'] = 'WIDGET_ID_HERE';
$query['campaign'] = 'CAMPAIGN_ID_HERE';

10. Build the URL and redirect the user

Build your URL with our built up query and send our user to the URL with a 301 redirect.

$url = \Drupal\Core\Url::fromUri($bookdirect_url);
$url->setOptions(array('query' => $query));
$destination = $url->toString();

$response = new RedirectResponse($destination, 301);


Final Code and Related Case Study

You can find the final code here on github. And you can read more about the client website here: Visit Rapid City Case Study.

Aug 28 2020
Aug 28

Working in the digital industry has both its perks and its pains. In fact, in the last half a year, even people who haven’t been working in digital have got a taste of what it’s like to do so, some with positive and some with more negative experiences. 

One thing that’s certainly an advantage in digital, however, is the luxury of being able to have a much better work-life balance - if you don’t fall into some of the common pitfalls that come with this luxury, that is. 

In this article, we’ll take a look at some tips for achieving better work-life balance when working at a digital agency, both your own if you are an employee, or that of your team(s) if you are a manager or CEO of that agency.

Additionally, we’ll look at some benefits that come with achieving a healthy work-life balance, and take into account the context of it being 2020, with most of the world already expecting Covid 2.0. 

Advantages of a healthy work-life balance

Let’s start with the benefits of improving your work-life balance or that of your employees. We’ll list 4 of the main ones here.

1. It reduces burnout

Burnout can be quite a problem in the digital industry, more so than in some others, and especially in the field of software development. Employees are often asked to work overtime, or a push to production on a Friday entails a whole weekend lost. 

One of the biggest remedies for burnout is a healthy work-life balance. While burnout can also occur if we are not overworked, due to some other reasons, having a good balance between work and personal life can greatly reduce the risks and/or the severity of burnout.

2. It leaves time for self-actualization

Naturally, having more time for yourself means, well, having more time for yourself - and the things outside work that you enjoy in life. If we remember Maslow’s hierarchy of needs, its highest level is dedicated to self-actualization. 

If your job is something you greatly enjoy doing, this is somewhat taken care of by your work; but if you have other endeavors and aspirations, taking care to balance your work and personal life is pretty much the only way to dedicate enough time to those areas to truly drive satisfaction. 

3. It leaves time for family and loved ones

This goes hand in hand with the previous point. Having more time outside work means having more time for the people you care about, be they friends, partners or children. 

The recent lockdown due to COVID-19 has made it particularly difficult for parents to have a great work-life balance, due to the combination of working from home and homeschooling their children. We’ll say a few more words on this when we’re discussing Covid-specific considerations.

4. It improves motivation and productivity

This one is a plus for both employee and employer. Feeling unmotivated at work has a direct impact on productivity, which in turn feeds back into the lack of motivation, only perpetuating this cycle. 

By having enough time for yourself and loved ones outside work, you’ll feel more at ease tackling challenges at work and produce better results, which will likely be noticed and highlighted by management, making you even more productive and motivated, and as such perpetuating a healthier and much more positive cycle. 

Do’s & don’ts for a healthy work-life balance

Here’s what you should do to achieve a healthy work-life balance:

  • Get enough rest and exercise. It’s easier to maintain other healthy habits if you’re well rested and physically feeling good.
  • Learn how to effectively manage your time and clearly separate work from personal life.
  • Make sure you do something meaningful after you finish work, something that isn’t work-related, to help with your self-actualization mentioned above.

And here are some things to avoid if you’re striving for a great work-life balance:

  • DON’T let work-time creep into your you-time. Clearly delineate when you’re working on your job and when you’re doing things for personal enjoyment.
  • DON’T let work be the only thing you have going on. If your work is the only thing you drive satisfaction from, you may find yourself feeling lackluster and/or unable to follow the previous point, which is basically a recipe for burnout.
  • DON’T be a perfectionist. If you’re never satisfied with your output, you can never stop worrying about it, and you’re bound to break the time limits you’ve set for yourself by overthinking and/or constantly tweaking things. Another point to note is that perfectionism can often translate into imposter syndrome.

Bonus tip: when working at a digital agency, you typically need to keep up to date with the latest trends and innovations in your particular field. While this can help your work-life balance by offering something to do outside of work, if it’s too closely related to your daily job, it may start to contradict the first two points above, eating into your you-time and making it indistinguishable from your work. 

So, just something to be mindful of; the most important thing here is being aware of this and trying to maintain a balance. 

If you’re, for example, a software developer, of course it’s great if you enjoy working on side projects, learning new things and contributing to the projects you support. But it’s also perfectly okay if you don’t code in your spare time because you have other hobbies, and only dedicate yourself to it while at work. Do what works for you. That’s key. 

Quote: If you’re a software developer, of course it’s great if you enjoy working on side projects, learning new things and contributing to the projects you support. But it’s also perfectly okay if you don’t code in your spare time because you have other hobbies, and only dedicate yourself to it while at work. Do what works for you. That’s key. 

Tips and tricks for business leaders and managers

Now that we’ve covered what you can do on your own to achieve and maintain a healthy work-life balance, let’s take a look at some do’s & don’ts if you’re an owner, CEO or manager. We’ll start with the do’s:

  • Offer remote work whenever needed or desired. This is the number one thing in times of Covid and likely will be going forward. And, in any case, a lot of digital agencies have been offering full- or at least part-time remote work way before 2020, so this should not be an issue at all. 
  • If working from home isn’t possible or physical presence is necessary for a certain time, make sure to enable flexible working hours. In the digital industry, you often work across different timezones, so keeping very strict schedules for everyone will likely not be possible, especially during Covid with many people at home with kids.
  • Provide necessary equipment for optimal work. This includes ergonomic equipment (e.g. chair, mouse, keyboard) and additional monitors for those who need them. In the case of remote work, allow and communicate the option of employees taking the needed equipment home with them or have it shipped to their home. 
  • Be transparent and give praise. Both of these make employees feel valued and part of what’s going on in the company, which improves the employee experience and reduces risks of things such as burnout. Transparency is absolutely key with Covid-related communications, while praise boosts motivation and productivity.
  • Organize team activities to boost team spirit and help people connect. Again, this is even more important during the Covid lockdown; try to replicate watercooler chats virtually, with daily casual check-ins with the team, weekly meetings and other activities. 
  • Foster a culture of learning and knowledge-sharing. The workplace, be it physical or virtual, shouldn’t be exclusively about work; it’s also a place to connect and learn new skills, both soft and hard. Offer options for further education for employees who are on standby, and promote sharing the acquired knowledge with the whole team - this is something which can easily be done via video conferencing, so it can be a way to connect even with everyone working from home. 

Now let’s look at what not to do if you want to help your employees achieve a healthy work-life balance:

  • DON’T micromanage and track employees. You should take other measures to ensure that you can trust them and that they remain productive - preferably ones that benefit rather than hinder them (e.g. praise). They will likely find ways around the stricter measures, but if you approach it correctly, they will instead be more dedicated and make better use of their time.
  • DON’T make generalized rules. Your employees have different needs and different workflows, often also working with different clients in different timezones. Make sure you accommodate and empower those who are working while at home with their kids rather than sanction them if they don’t work on specific tasks to the minute.
  • DON’T under-communicate and make false promises. This ties back to being transparent: make sure to timely and accurately communicate any new measures or demands, and don’t make false promises to clients with regards to employee availability or overtime, nor to employees about a promotion or raise. 


Man in business suit holding rolled up yoga mat

The COVID-19 pandemic and the subsequent global lockdown have introduced major shifts to the way we work, significantly speeding up digitalization and necessitating mass adoption of remote work. Both of these trends make a healthy work-life balance even more of a priority when working in the digital. 

We hope this article helps you pinpoint what to do and not to do in order to improve your work-life balance, or that of your employees, and keep it healthy. 

Remember to take into account the potential limitations of working from home and changes to work scope due to certain clients going out of business, while those specializing in, say, e-commerce, suddenly requiring more work. 

If you make sure to foster a company culture that’s people-centric, it isn’t difficult to achieve good work-life balance at your digital agency. It’s a win for the employees, as well as for the business leaders and clients, who all benefit from the employees’ well-being. 

Aug 28 2020
Aug 28

On July 13, we released another version of the Droopler distribution. In version 2.1, we focused on the functionality needed by many companies nowadays – we have added e-commerce. Check out what exactly the new version of Droopler – one of the most popular Drupal distributions – brings. 

Why e-commerce?

Recent months have forced many companies to switch to online sales. Since March 2020, the number of searches for the phrase "e-commerce" in search engines has increased significantly. More and more companies are looking for ready-made solutions that will enable them to conduct sales via the Internet.


Therefore, at Droptica we have decided to introduce a ready-made e-commerce functionality to the Droopler system. As in previous versions of Droopler, also in the case of e-commerce, our goal was to create a functionality that is nice-looking, easy to manage and ready to use right after installation. 

We provide all this for free and as open source code. 

E-commerce in Droopler

Droopler is a distribution in which we try to use the best Drupal core elements and the best Drupal modules within one system. We combine them into a coherent whole that is convenient to use and add a ready-made template adapted to mobile devices.

That is why in version 2.1 we have used the module Drupal commerce and we have created a ready-made online store on its basis. We have added one example product type and created a product listing. 

Everything looks very nice right away; you do not have to worry about graphic designs or creating CSS styles. This is already done in Droopler 2.1

Check out the demo version

We have also prepared a new demo version showing the e-commerce capabilities of Droopler. Just go to the website https://droopler-commerce.droptica.com and see it for yourself. 


On the home page consisting of paragraphs, you can see selected products. This is one example of how you can promote selected products. 

The list of all products can be found on the website https://droopler-commerce.droptica.com/shop This list is based on the Views and SearchAPI modules. On the left side, you can filter products by category (faceted search). 

Sorting options are available above the product list. The user can change the order of the products being displayed according to their needs. 


When visiting the page of a given product, you see a photo gallery, the product price, the option to add it to the cart, and its description.

The basis is Droopler, so the editor can add any of the 16 existing paragraphs to the product description and make the product page look very eye-catching.

In the header of the page, the user can see the number of items in the cart. From there, they can go to the purchase page and complete the order.

Purchases can be made as a logged-in user and as a guest. 

You can go ahead and test all the purchase steps by clicking around the demo version. 

Adjust the system to your needs

Droopler is based on Drupal, so you can adjust it to your needs. You can also do this with an e-commerce system built on Droopler.

Do you need an online payment system? No problem – there are over 100 free payment modules.

Do you need dedicated shipping options? You can find an appropriate module for this also.

All modules can be found on the website https://www.drupal.org/project/project_module

While working on version 2.1, we have also prepared new additional modules dedicated to Polish companies:

If you have very uncommon requirements, ask us for help. Droptica is a Drupal agency that helps to adapt Drupal (also Drupal Commerce) and Droopler to the individual needs of its clients.

More information on Droopler

By releasing subsequent versions of Droopler, we want to create a convenient tool for business owners and people from marketing departments. With Droopler, we want to help companies in their marketing and sales activities.

From the very beginning, the system is available for free. Information on how to download it can be found on the website droptica.com/droopler/
We have also built a tips section – "Droopler tutorials" – where we describe how to work with Droopler.

If you need help with Droopler, you have found a bug, or you have an idea for new functionality, please notify us here: https://www.drupal.org/project/issues/search/droopler

Aug 27 2020
Aug 27

In one of my last posts, I provided examples of Drupal-based corporate websites. The first one referred to the companies of the medical industry, the second one – to the companies operating within the industrial sector. I presented the Drupal functionalities, as well as the dedicated solutions that the organisations mentioned in this article introduced in their websites. In this text, however, I would like to present Drupal-based websites from the commerce industry.


The company offers co-packing products and accessories. Therefore, it represents an industry in which competition is fierce – the more reasons for an online store to stand out. And so, there are a few attention-grabbing elements that really make this commerce attention-grabbing.

The first thing is the attractive form of displaying banners and photos on the home page. Slide in was used here – by scrolling the page, the mentioned elements "slide" into their places. The effect is eye-catching and makes you want to stay on the store's website. 

The second thing is definitely the search engine. When typing a search term, suggestions appear. This way, you can find the given product faster – you can immediately see if such a product even is in the store at all. And if it is available there, after calling this product you are taken to a page where further filtering options are provided. It is important because, remaining "on the product", you begin to narrow down the search in terms of the features of this product. All this means that you are encouraged step by step to look for the goods you want to find – you do not give up, and we do not leave the website. 


Another thing is the menu. It is located in the upper left corner. After clicking it, a list with categories appears. After selecting the "+" sign, the given category expands – you see the next subcategories, and in the next steps you go to the page with this very product. 

Speaking of the menu, it is worth mentioning the rather frugal form of presenting the headline. In addition to the aforementioned search engine, there is also a shortcut for logging-in into the customer account and a shopping cart. All this makes the whole thing legible and easy to navigate.

When browsing the Drupal-based Hermes store, it is impossible not to get the impression that it was very well-thought-out and designed with the customer in mind. So, if you are considering starting your commerce, this example can be a great inspiration. And in combination with the Drupal consulting, you can gain knowledge and advice on how to make your customer stay in your store as long as possible and choose what they are looking for.


It is one of the most well-known brands that probably does not require a detailed introduction – and also another Drupal-based store. You can find here other amenities for the customer, as well as inspiration.

Have you wondered how to make the search engine more attractive? If you add to the Hermes' example a product image along with the information about the number of variants available in the store, you may obtain a really attractive effect. This is how it looks like at JYSK. You might say it is nothing, but this detail makes all the difference. It undoubtedly meets the customers' expectations and makes searching for a product significantly easier.


Let us go further. If you offer many products and have many categories, why not present these categories as a gallery on the home page? Thanks to the solution proposed by JYSK, the customer who visits the store receives a visual, and at the same time – friendly, message. You can see then that the owner of the store took care to make it easier for the visitor to navigate the brad product offer. 


The above solution is continued. After selecting the category, you are still being guided through photos with subcategories, until you finally choose the given product. Between individual steps you can find, e.g. the section with a blog/guide regarding the category you are currently in. It is good to pay attention to this because on other websites the blog is often placed "beside" and sometimes it is a separate element – here it is an integral part of the purchasing process and supports the customer in choosing the product that meets their expectations.


And when you are finally taken to the cart, there is also a well-thought-out solution that takes into account the decisions that the customer may be considering. "Availability check" and "online reservation" caught my attention. 

By checking the availability of the goods, at the very beginning, you can check out whether the product is in stock and in how many brick and mortar stores.


When selecting the checked button, a pop-up appears, where – after entering the city – you receive information about the quantity of the product in the specific store. It is good to mention here that there is also information available about the latest inventory update – I think it is very important knowledge for the user, on the basis of which the customer can be sure that they are viewing the most up-to-date. A similar pop-up with its functionalities appears when making an online reservation.


When conducting sales online, you should not forget about the sales at brick and mortar shops – but rather support them in order to provide the customer with a broad range of possibilities and present them with options at every step of the shopping experience. And finally – the customer panel. JYSK took care of the basic functions such as: the profile, the order history, the wish list, and the list of recently viewed items. The FAQ section can be checked here. And just like the blog section placed within the purchasing process, the most frequently asked questions and answers are at hand.



Probably almost everyone knows the Wilson brand, but maybe not everyone knows that their online store is built on Drupal.

In this case, I also have to start with the search engine again, because it seems that of all the previous examples, this one looks the best. Moreover, it shows that with Drupal you can develop functionalities that may seem inflexible at first glance.

The main difference is the fact that after entering a phrase, you are taken straight to the store, where the page with the desired product, categories and quantity is displayed. In addition, I must mention that the design is characterised by minimalism, thanks to which the whole is uncluttered.


However, I want to focus on the element that makes this store unique and distinguishes it from others. In the main menu, there is a CUSTOM button, which allows for the possibility to "design" a product according to individual needs and tastes.


After pressing the button, you are taken to the model (in this case – of a tennis racket) and the selection option.



And this is where the adventure begins, one could say. The possibilities of personalising the product are really wide. From the colour, gloss, type of coating, through the choice of the shades of the logotype, to the use of patterns resembling the ones on the rackets of the world's most famous tennis players. Posting here more screenshots made by me would take up too much space, and at the same time – prevent the interaction with the store's capabilities. So, I encourage you to visit it and personalise a tennis racket yourself. However, I will attach here the final view of the product, including the information about the estimated time of order completion.


The above example is perfect if your business offer includes products that are being personalised for your customers. With Drupal, you can achieve a unique effect that will keep up with the expectations, and at the same time provide the user with an unusual experience. So, when you will be preparing a brief for a Drupal agency, and your vision will resemble Wilson's example even a little, I encourage you to include this example. Thanks to this, Drupal team will understand your idea well.

Let us go back for a moment to the home page with the option for finding a dealer. 


The use of a map turns out to be extremely useful here. After selecting the brick and mortar store you are interested in, its detail appears on the side of the screen, which provides additional filtering by category. In the case of Wilson, the search can be narrowed down depending on the sports discipline in the context of which you will be able to purchase appropriate equipment and accessories.


This Drupal-based cosmetics shop may be a good example of a product presentation and designing a customer panel.

As for the former, the gallery plays a key role. Every subpage with a specific type of product is created according to the following pattern: banner, best seller product, other products. Additionally, some of them have information about the stock ending in the warehouse. In addition, there are also references to the content on the blog - so if you have doubts about which product to choose or you want to broaden your knowledge, you do not have to leave the subpage, because everything is here in one place. 




Although there are a lot of photos, you do not get the impression of being overwhelmed with their number. So if you are considering a similar style for your store, use a professional design service.

The second element is the already mentioned customer panel. The clear menu draws attention. Navigating and finding your way around your profile is easy and pleasant, which means that the customer may log in there willingly.


Further down the panel, some blocks allow for previewing the content in reference to the panel menu item.



And finally, the WAM publishing house as an example of a Drupal-based store with a large number of books. The distinguishing feature of the home page is its transparency. My attention is drawn to the thematic blocks with books from a given series. Thanks to using the slider, you do not have to enter the given block, but by pressing the arrow, you can move the titles.


After selecting a book, you go to the product page, where we can learn more about the publication. You also have the option to download an excerpt from the book. 


An interesting fact in the store during the ordering is the option of shipping the purchased product as a gift. The customer can choose not only the recipient of the goods but also a decorative packaging. As a result, the buyer of the product to be a gift does not have to worry about packaging anymore. This is a convenient and useful option.


By choosing a Drupal-based store, you can take advantage of its many possibilities. Depending on what you expect, what you sell, you have a chance to build e-commerce so that your customers stay on your website as long as possible, and the number of conversions is as high as possible. I hope the above examples have inspired you, and you will want to use some of the solutions.

Aug 26 2020
Aug 26

The creation and delivery of ethical medical systems is an urgent concern for healthcare professionals and systems around the globe. A worldwide pandemic has only heightened the stakes for those involved in ensuring that delivery of patient care is driven by ethical and transparent decision-making across the international, private healthcare sector. To help drive the adoption of ethical systems, the International Finance Corporation (IFC) partnered with the World Bank to create the EPiHC (Ethical Principles in Health Care) initiative, which seeks to work with partners around the globe to sign onto a set of 10 principles to guide the behavior of healthcare providers, payors, and investors.

Chapter Three worked with the IFC’s programmatic and communications teams to provide strategy, design and development for this global initiative. We’re especially proud of these key accomplishments for this project:

  • Efficient project work: from kickoff to completion of development in under 2 months. The client had critical, short deadlines that needed to be met in order to announce a more public phase of this effort to recruit new organizations to sign on to EPiHC.
  • A completely remote collaboration: with the client. Given that this was one of the first new projects established during the current pandemic, we turned what might have been in-person strategy sessions into a series of smaller online workshops.
  • A detailed Signatory form and backend workflow: that allows the IFC team to vet organizations interested in joining the EPiHC initiative.
  • Built on Drupal 8: providing the IFC team a platform to build a robust Signatory community via user profiles (with engagement that will be expanded over time).
  • Content strategy: we suggested refactoring content previously locked away in a PDF and turning that into “chapters” incorporated on the left side of the Principles page
EPiHC Principles Page

The Principles Page at the new website provides an easy-to-use "chapters" style interface to quickly access each of the 10 principles that make up the EPiHC initiative.

The EPiHC initiative was previously housed deep within the IFC website. This setup was suitable as an incubator while the content and program was being built up, but over time became increasingly impractical from both a visibility and architectural perspective. As shown below, the navigation structure of the previous mini-site looked like it all related to the EPiHC project but in fact those links ("Thought Leadership", "Case Studies" and "Publications") referred to IFCs other topical content, not specifically content for EPiHC. This was confusing and necessitated moving the pages to their own, uniquely branded site.

EPiHC Old Minisite

The old EPiHC minisite inherited navigation (including "Thought Leadership", "Case Studies" and "Publications") from the main IFC website and not directly related to EPiHC. Though temporary, this caused confusion and necessitated a move to a standalone site.

To make EPiHC visible, sustainable and marketable to organizations interested in signing on, we created a clean, elegant design that provides easy to understand pathways to their essential content: the “EPiHC Principles” and the “Become a Signatory” form.

EPiHC New Website by Chapter Three

The new EPiHC website designed and built by Chapter Three shows clean design, prominent highlight of the Signatory Form and elegant branding between imagery and the project's logo. 

The EPiHC team has already secured dozens of Signatories to this effort and expects to recruit hundreds more. The recruitment effort will rely heavily on the clear content architecture and clean design of the new EPiHC website, powered by Drupal 8 and built quickly as a result of close collaboration between the IFC and Chapter Three.

For more information on this project, or to discuss yours, please contact us here


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