Useful Drupal modules

Click on the module name for notes, comments, patches.
Recommendations (for and against) are my personal opinion only and may be out of date. Feel free to email with corrections/suggestions.

Why doesn't the table mention Drupal 9 or 10?

1. Nowadays, I try and use Drupal as little as possible. Specifically I do not recommend it for a new website. I'd also strongly caution you against choosing Drupal if you're at the beginning of your career and trying to learn web development (front / back / full stack) or just want to manage/maintain a website. More details why by email on request.

2. By February 2022 I'd updated all the sites I look after to Drupal 9 (experience: mixed). As of March 2023, a year later, none of them were fully ready for Drupal 10 (waiting on support for various modules). By 13 Nov 2023 (a week or two after D9 lost support) I had updated a couple of them.

Q: What's the Drupal 9 to 10 upgrade experience like? A: it's what I'd describe as "just bearable", slightly better than D8 to D9, though with plenty of things to still trip you up. There is still deprecated code that needs fixing in D10 modules, and policy changes mean odd things will break (be prepared to turn off Aggregate CSS/JS files if your themes stop working, and note that Drush launcher doesn't work with Drush 12...)

Admittedly the upgrade_status module is the best solution they could have come up with for tracking compatibility. Also watch out for a nasty session headers bug with redirect_after_login.

What about sites still running Drupal 7? In short I still recommend leaving them on Drupal 7 or moving to another platform entirely. My prediction was that Drupal will extend D7 support year after year (note that drupal.org itself is still running D7). It's now been confirmed as 5 Jan 2025. There will have to be some sort of third-party long term support, because of the sheer volume of sites that are not being upgraded.

Your decision is really what specifically you think you will gain from Drupal 8/9/10 - often the answer will be not enough, and one of the main hassles - apart from converting each content type one at a time, and setting up a new theme, will be recreating all your views by hand, as views can't be automatically upgraded.

(134 modules in list)
Module name or machine name
Any text in the notes
Name D8 Personally Tested Sort descending Last Updated
Autosave (autosave)

d.o. page

Saves snapshot of content type form using AJAX.  Content types and save frequency can be configured.  No sign of a D8 port yet.

Automatic Nodetitles (auto_nodetitle)

d.o. page

You can hide a node's title field (for reference, every node has to have a title) and generate it automatically, similar to pathauto.  No-one's porting this to D8 yet.

Datetime Range (datetime_range)

d.o. page

"Essential"

Now in core, but you need to enable it.

Adds an 'all-day' option.

Twig Tweak (twig_tweak)

d.o. page

Adds Twig syntax to insert views, view results, regions, entities (e.g. nodes, blocks, webforms), menus, images, image styles, tokens, breadcrumbs, messages, contextual links and more.

Mollom (mollom)

d.o. page

Deprecated

Not recommended

DO NOT USE - security issue and Acquia will no longer support or maintain it.

Spam filtering SaaS from Acquia. Free for up to 50 "ham" messages a day.  Scans message then provides a captcha if appropriate, scores each message for reputation, spam etc.  I never tried this module and anecdotally I've seen mixed reports / people suggesting it's not all that good.

Coder (coder)

d.o. page

Checks your code against Drupal coding standards.

No need to install this - isn't actually a module, it's a set of phpcs rules installed as standard in /vendor/drupal/coder/coder_sniffer

Block Visibility Groups (block_visibility_groups)

d.o. page

Rather than change visibility for individual blocks, you can group them together and assign complex visibility settings to all of them. Module page promotes it as a simpler alternative to Panels.

Flood Control (flood_control)

d.o. page

Protect against brute-force login attacks. Unclear what's happening with porting of this.

Feeds (feeds)

d.o. page

"Essential"

As of Sep 2018, up to alpha3 in D8 (but not personally tested).

Lets you import CSV/RSS etc.  files and various other formats and map them to nodes/user/taxonomy terms, either one-off or periodically.

Alexa (alexa)

d.o. page

Integrates with Amazon Echo. Allows Drupal to respond to Alexa skills requests.  See Dries' blog with video demo.

Field collection (field_collection)

d.o. page

Allows you to group a set of fields together.  In active development for D8 but still a lot of open bugs at time of writing - project page says it will likely be replaced by Paragraphs.

Refreshless (refreshless)

d.o. page

Only loads the parts of page that change when navigating between pages.

Unclear if still being maintained (no updates since Sep 2016) - part of the issue is it requires a core patch.

Trash (trash)

d.o. page

Adds a trash bin for all content, so you may later restore (or permanently delete) it.  Depends on Content Moderation module.  Alpha in D8.

CKEditor Custom Config (ckeditor_config)

d.o. page

I've not actually used this but I adapted it's code to enforce a configuration setting (I wanted to remove the HTML dom elements that are shown in the status bar).

The module allows you to supply your configuration using the UI.

Node Export (node_export)

d.o. page

Tto actually export node content. An 8.x version has begun development:

composer require 'drupal/node_export:1.x-dev'

Twig Extensions (twig_extensions)

d.o. page

Text filters, array and date manipulation.

(haven't tried this yet)

Restrict Login or Role Access by IP Address (restrict_by_ip)

d.o. page

Can specify single IP address or ranges. Two modes: restrict login, so they can only login from certain IPs, and restrict role, so they can login from anywhere but only access a role's permissions from the defined IPs. There's a D8 dev branch, last updated June 2016.

Entity Access Audit (entity_access_audit)

d.o. page

This is a way of visualising - via grids of ticks and crosses - which roles have access to different operations on different entities.

Introductory blog post

Group (group)

d.o. page

Alternative to the Organic Groups module. Allows you to create groups - e.g. classes, subscriptions, multiple communities.  Drupal module of the week post. Blog post.  It is by all accounts solidly written, but I found the initial UI confusing (in a "so what do I do now?" way) - you probably need to watch the YouTube video to understand it.

Features (features)

d.o. page

Not recommended

Update: most people are now moving away from features. There is a Configuration Management initiative under discussion in Drupal 8.

Package up selected configuration for "features" (e.g. a blog or a photo gallery etc.) for reuse on other sites.  Not the same as the new D8 Config sync, which is for exchanging configs between different environments of the same site and requires a cloned DB sharing the same UUIDs.

Simple OAuth (simple_oauth)

d.o. page

An implementation of  OAuth 2.0 Authorization Framework RFC - based on a PHP League package.

AddToAny Share Buttons (addtoany)

d.o. page

Nice, clean, SVG sharing buttons. Project page says it's specifically optimised for Drupal.

Autofocus (focus)

d.o. page

Autofocuses the first field of form (forms can be specified).  No sign of a D8 port.

Image Lazyloader (lazyloader)

d.o. page

Images are hidden until they scroll into view.  Can specify distance before loading is triggered, also placeholder image, loading GIF and any pages to be excluded.  There's been some Drupal 8 development but unclear how complete it is.

Pathauto (pathauto)

d.o. page

"Essential"

Generates URL aliases for new content automatically - using token-based patterns per content type - e.g. /reports/[node:title]

When you install this, the settings are in /admin/config/search/path – normally this page has no tabs, with this module you get Patterns, Settings, Bulk Generate, Delete Aliases). 

Contact Storage (contact_storage)

d.o. page

"Essential"

Store all contact form messages in the database (as an entity), rather than just emailing them.

Integrates with views, if you want a view of messages.

Messages are accessible (can be edited or deleted) at /admin/structure/contact/messages.

(May be useful considering From: address SPF/DMARC problem with contact forms, i.e. there may be cases where some emails aren't delivered.)

Flag (flag)

d.o. page

"Essential"

Handle favourites, reading lists, spam, friend lists etc.  Can be applied to any entity (nodes, users, comments etc.)  It appears as a clickable link. Can choose between page reload and AJAX when user toggles it.  Linked with views, and you can trigger events when flag count reaches a threshold.

String Overrides (stringoverrides)

d.o. page

"Essential"

Replace text on the site.

Allowed Formats (allowed_formats)

d.o. page

"Essential"

Control which text formats are available per field. (Often you'll want some fields to be simpler than others - e.g. you might want restrict everyone to a single format so they don't see a dropdown menu. 

You can hide the 'About text formats' link and the list of available HTML tags, again per field, in the Form Display tab using the widget icon.

Double Field (double_field)

d.o. page

"Essential"

Store a pair of fields together (numbers and text, boolean, email, telephone, Url).  As normal you can specify the quantity of double fields per entity, or allow an unlimited number.

Note: D7 version doesn't support 'date'.

Don't use it for:

  • links - you might have one field for the URL and one for the description, but the display widget won't let you merge them into a clickable link.  That's what the dedicated link field type is for.
Administration Views (admin_views)

d.o. page

"Essential"

D7 only (as this is in D8 core as standard).

Converts /admin/people into a fully-fledged configurable view (i.e. fields, filters, exposed filters, header/footer, pagination settings etc.) 

(Dependency: views_bulk_operations)

Upgrade Status (for Drupal 9) (upgrade_status)

d.o. page

"Essential"

Very useful module for scanning installed modules (including your own custom code) for compatibility issues - gives a detailed report of necessary fixes.

NB: scanning using the UI (rather than Drush) won't work on a dev server without a valid SSL certificate.

Entityqueue (entityqueue)

d.o. page

Build a custom list of nodes. The setup is via Admin > Structure. Currently D8 alpha.

Paragraphs (paragraphs)

d.o. page

For those familiar with WordPress, this is the equivalent of the ACF repeater field.  You can create paragraph types, which are collections of one or more fields, and the user can add as many of them as they like.  So you could have distinct paragraph styles, e.g. with images aligned in a certain way, or a page consisting of parallax backgrounds etc.

Structure Sync (structure_sync)

d.o. page

"Essential"

Lets you synchronise taxonomies, custom blocks and menus.  

Important: always double check after importing if menu / block etc. has been correctly updated - if not, you may need to use a more forceful option.

Permissions Filter (permissions_filter)

d.o. page

"Essential"

The admin permissions page can get pretty long. 

This lets you narrow it down by typing permission names into a text field.

Address (address)

d.o. page

Used to be called addressfield.  Adds one dependency - commerceguys/addressing.

This is a bundle of address fields, the correct combinations are shown depending on which country the user selects via a dropdown.
You can configure which countries are allowed per field instance.
To set the default, use the Manage Form Display tab.

It validates postcodes are in the correct format. 

Also supports 'zones' (groups of countries/subdivisions) for shipping/tax purposes.

Views taxonomy term name into ID (views_taxonomy_term_name_into_id)

d.o. page

Allows you to use /my-view/foo instead of /my-view/123 when adding a contextual filter based on taxonomy terms

Username policy (username_policy)

d.o. page

This gives you a single box where you can enter tokens to form the default username.

It seems to work, but in D7 the patterns section ("Only use the below pattern elements") was empty. This is supposedly because there's a dependency on the 'profile' module, except profile doesn't exist in D7 (I tried profile2 instead but it made no difference) and profile2 doesn't exist in D8.

auto_username displays tokens OK and is more powerful / has more settings including customise at what point names are truncated, etc.

Masquerade (masquerade)

d.o. page

"Essential"

Allows you to browse the site as another user (to see what they see) and then quickly switch back again.  A general Drupal recommendation is to create test accounts for each of your roles, so this is useful for testing them.  (As per notes, don't use it for anonymous access, just log out.)  Replacement for 'Switch User'.

Patch and known bug:

Metatag (metatag)

d.o. page

"Essential"

This comes with a whole series of modules, including metatag_verification that will allow you to insert a google-site-verification tab. Instructions

How to add it to a content type/bundle:

  • You need to add the metatag field to the content type and position it on the form (it'll display as a disclosure triangle in the sidebar)
  • You also need to configure the level of available options at /admin/config/search/metatag/settings
Field group (field_group)

d.o. page

"Essential"

Add group' button to /admin/config/people/accounts/form-display (or any other form), can then group fields inside fieldset/other HTML wrappers.  

 

Types of groups:

  • Fieldsets
  • Horizontal tabs
  • Vertical tabs
  • Details
  • Accordions
  • Divs
  • HTML elements

In theory can use this to add <div>s with css styles such as flexbox, like webform uses, but CSS to support that needs to be present on the page.
 

Raven (raven)

d.o. page

"Essential"

This module logs events and sends them to Sentry.  Sentry is an open source application you can self-install, but also a free/paid SaaS version.

For a content management framework as complex as Drupal it's worth logging errors.

Tips:

  • In Raven config, recommend not logging debug and info messages, but do select Enable fatal error handler and Enable stacktraces.
  • You can enable the javascript error handler as well, but personally I only use PHP.


Drupal benefits:

  • logs the Drupal uid
  • logs referrer URLs
  • you can tag versions (e.g. commits) as well as different environments
  • you get a full breakdown of AJAX requests

 

Views infinite scroll (views_infinite_scroll)

d.o. page

  • supports both a 'Load more' button and automated load
  • need to turn AJAX on for the view
  • patch needed to support back button (adds a preserve history option to settings, which then needs to be turned on)
Unique field ajax (unique_field_ajax)

d.o. page

"Essential"

Gives you a checkbox for 'Unique' when editing fields - can have it checked during form entry (via AJAX) and specify a custom error message per field.  Seems to have bug where field you're checking is sometimes refocused (even if no errors) if you've already tabbed away from it and continued typing.

View Migration (view_migration)

d.o. page

Not recommended

Migrate views from D7 to D8.
Once installed on D7 - you need to go to /admin/config/view-migration 
It outputs multiple YML files and you're specifying a directory to put them in, which you need to create first.

My experience of the YAML output has been:

- incomplete (e.g. multiple missing displays in a complex view, views without a machine name)
- invalid UTF8 due to the next and previous arrows in pager.options.tags being encoded wrong
- the dependencies section at the top of the file not being set out correctly

It doesn't look like there's much current development activity (likewise migrate_views, which is the other plugin people usually mention).

Comment Notify (comment_notify)

d.o. page

"Essential"

Allows users to receive emails for replies to their comments (or optionally for all comments on a node).  Can be toggled by content type (although not by comment type, if you have more than one comment entity).  In permissions, you can also control which roles can subscribe.  Can also set it so the author of a node also automatically gets emailed for every comment.

I'm using three patches:

I also have a site which uses two comment types; I wrote a patch to turn off the notification checkbox for one of them.

Devel (devel)

d.o. page

"Essential"

Key features:

  • Kint (enable kint submodule, for pretty variable printing, way to view properties and methods)
  • DevelMailLog (redirect all mail to text files instead, specify location directory, specify filenames using tokens for recipient, subject, timestamp) - DevelMailLog requires that you also install the MailSystem module to activate it
  • Config Editor and State Editor (enable via /admin/config/development/devel/toolbar)
Add another (addanother)

d.o. page

"Essential"

For this to work for any content type after you activate it, you have to manually edit and save that content type's settings, otherwise the buttons will be missing.

Responsive and off-canvas menu (responsive_menu)

d.o. page

This uses a JS library and works without a second copy of the menu in the HTML, and you don't need to make any changes to your existing navigation menu.

Look at the README file for instructions.
You need to install mm_menu and superfish in your libraries folder.

Note you're forced with the mobile version of the menu to have it expand to full depth (although the hack/workaround, if you want a top-level menu only,  is to hide the lower elements in CSS)

For hand-crated CSS / minimal javascript solutions, see https://css-tricks.com/responsive-menu-concepts/