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 Last Updated Sort ascending
Webform Views Integration (webform_views)

d.o. page

"Essential"

This module lets you add fields from submissions to view, and sort/filter the view on them, in the same way you would standard fields from the Field API.

It's still alpha and not as polished/robust as the webform module itself - but it's certainly OK to use in production provided you test things first - check every combination of exposed filters works, and double check you aren't seeing duplicate rows (right now I've locked it to a recent commit on the dev-5.x branch, which doesn't need any patches).

Layout builder (layout_builder)

d.o. page

Benefits:

  • Build layouts using GUI - arrange fields in columns/blocks (or add a block, or menu, or tag cloud, user info etc.) 
  • Easily override layout of individual nodes without needing to clone/design/apply a template (and reset to default easily afterwards)


Status:

Nov 2018: core, experimental in 8.6.x
May 1 2019: due for stable release in 8.7.0

Issue queue

Installation:

  • Enable the layout_builder module (which also enables layout_discovery)
  • Clear cache.
  • Activation:  Content type -> Manage Display -> scroll down to Layout Options - tick Use Layout builder

By turning on Layout Builder, you switch from the standard Manage Display view (field, label, format/widget settings) and the layout builder GUI.

Resources:

Compatibility:

  • A migration path is being built for Panels / Panelizer.
  • Undecided (Nov 2018) how Layout builder will work in conjunction with Paragraphs

 

Password policy (password_policy)

d.o. page

Not recommended

There are still quite a few bugs open. I dropped this for a project, partly because it adds a load of clutter with the 'resets' and reset dates.
The minimum password policy in Drupal is already 12 characters anyway (and one issue is changing the minimum length doesn't change the help text.) 
You need to enable the submodules to use the various constraints:
drush pm:list | grep 'password_policy_'
Admin users see password policy stuff on the user profile page.
You need to set password reset days to 0 if you don't want to enforce a reset policy.
Policies can be applied by role.  
You get a generic warning about the password 'not matching the password policy'. Suggest using string overrides to change the "To change the current user password, enter the new password in both fields." message users see.
Instructions: add/edit the policy, click next, choose constraint then click 'Configure constraint settings' otherwise you won't be able to change anything.
It also lets you do a forced reset by role.

Environment Indicator (environment_indicator)

d.o. page

"Essential"

Change the colour of the admin menu according to whether you're using dev, staging, production etc.

(You can also add 'switcher' menu links, e.g. Open in dev, Open in Prod). 

Notes:

- need to reset the cache after you've made changes [#2406619]

Computed Field (computed_field)

d.o. page

Add a field whose value is calculated using raw PHP; specifically $value = 'foo';

(The recommendation is you write your PHP in a module of your own, and then call that method from the UI - for security and version control reasons).

Note: value is only calculated when nodes are saved (i.e. will initially be empty for existing content).

D8 status; alpha but working.

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

 

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.

AJAX Comments (ajax_comments)

d.o. page

Not recommended

Not very actively maintained and it can be quite buggy.

Needs this patch:

Reply button can be pressed multiple times, resulting in multiple comment forms

I abandoned it for a project because the admin XHR response when you submit comments sends back comments you've already filtered out (I had written code to restrict visibility of certain comments).   Also had a problem where the initial comment form was left in place rather than being replaced, so you ended up with duplicates.

Serial Field (serial)

d.o. page

"Essential"

Creates a field with a serial number, so you can have the equivalent of a MySQL AUTO_INCREMENT field for a content type (if nodes are deleted the old serial number is not reused).

Although this only has a dev branch which hasn't had updates since April 2016, it does work in D8.

There's no direct migration path previous versions, but people have written their own migrations.

Check issue queue for patches - including:

 

 

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).

Simple OAuth (simple_oauth)

d.o. page

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

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.

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.

Pathologic (pathologic)

d.o. page

There's a D8 version but I've only tested D7.

It's a filter that fixes incorrect paths in your content - e.g. if you have content with an old domain or IP address specified, you can redirect it.

Field Tools (field_tools)

d.o. page

"Essential"

Provides:

  • /admin/reports/fields/tools - new Tools tab contains a more detailed field list that lists the instances (e.g. entities/content types) where each field is in use
  • editing individual fields in a content type - new Clone tab which will let you copy it to other Bundles (it also copies form and view display options)
  • Manage Fields page of a content type - new Clone tab where you can selectively clone multiple:
    • fields
    • displays
    • copy display settings

 

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.

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

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.)

Nagios (nagios)

d.o. page

Generate customisable Nagios reports for things like module updates, cron not running etc.  

The D8 version is now compatible with NRPE because there's a Drush command to generate the Nagios string. 

Entity Embed (entity_embed)

d.o. page

Lets you insert any entity type (supposedly) via the WYSIWYG editor, and like images you can set alignment etc.  It creates a toolbar button that can be added to the toolbar configuration in 'Text formats and editors'.  The strings needed can be pretty long - e.g. 

<drupal-entity data-embed-button="snippet" data-entity-embed-display="entity_reference:entity_reference_entity_id" data-entity-type="snippet" data-entity-uuid="216914ab-1bc2-4a73-975b-dc1de79e849a"></drupal-entity>
 

Views exposed form layout (vefl)

d.o. page

Not recommended

Layouts for exposed filters - i.e. you can move each filter into a region (supports Panels and Display Suite).

When I tried this (Summer 2018) the D8 branch wasn't really there yet - you could only rearrange the basic filter components in D8 (like search term, submit button, reset button), not all the extra ones you've added.   I went with using CSS (e.g. clear: both) instead.

Menu Token (menu_token)

d.o. page

Add tokens, such as a user ID, to text or URL paths of menu items. 

Be wary of this issue: Current-user:uid not correct

Field Formatter Condition (fico)

d.o. page

(based on ffc which hasn't been ported to D8).  

Allows you to configure field display based on value.  Adds a 'Conditions' pane to the cog in Manager Display of all entities (so content types but also comment types, e.g. if you have comments with multiple fields)

Requires Display Suite (ds)

Note: if you wanted to hide say a checkbox when it's value is false - you can do in it core with Manage Display - turn the label off then set (via cog wheel) the output format to Custom, and you can enter a value for true and leave false blank - exactly the same widget for boolean values you use when setting the output of a field in a view.

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.

Snippet Manager (snippet_manager)

d.o. page

Snippets are Twig templates that can be managed using the UI.  They can be inserted in various ways including via CKEditor, tokens.

Support for HTML, CSS, JS, and variables.

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.

Real Name (realname)

d.o. page

Use tokens to merge first name, last name or any other fields.
Then you can display the realname field in various places.  

Note: you have to add code to substitute the default username in the title of user node views - e.g. in mytheme_preprocess_block(&$variables)

Field Permissions (field_permissions)

d.o. page

"Essential"

Control editing/visibility of individual fields by role.  

As well as custom settings ('create own', 'edit own', 'view own', 'edit any' and 'view any' - all per role), there's a Private setting which gives access to the author and administrator only. 

These are automatically applied to views.

Finding the setting: Look for  Field visibility and permissions – on the Edit tab, NOT Field Settings.

In /admin/people/permissions there's also a Access other users private fields permission.

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

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.

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.

Role Delegation (role_delegation)

d.o. page

Ordinarily, if you grant a user "Administer Users", they can do everything *except* change the roles (they don't even see the checkboxes).  You could give them 'Administer Permissions', but that also allows them to do other things.  

This module lets you set which roles they are allowed to enable for a user.  Administrators still see the roles checkboxes in the usual place (below 'status' on /user/123/edit), but everyone  gets a new 'Roles' tab.  

Works with D8 but not updated since April 2016.

Patches:

I'm not using any patches, but there are a couple RTBC-ed  the queue.

 

Config Ignore (config_ignore)

d.o. page

"Essential"

Selectively ignore configuration entries during an import - e.g. site settings / the system.maintenance message.

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'

SMTP Authentication Support (smtp)

d.o. page

"Essential"

Send mail to a remote SMTP server (e.g. a transactional email provider like Postmark).  

You should put your authentication details in settings.php, rather than files you commit to the repo, for security.  

To get this to work - it was sending tests but nothing else - it seemed I needed to switch to a commit on the dev branch:

"drupal/smtp": "dev-1.x#3d354b3911409c9b11716bf2104498fb431eea72"

(note to self: see SM notes) 
 

ClamAV (clamav)

d.o. page

"Essential"

Virus check files uploaded by users.

In Drupal - when it can't connect you get an error on the Status Report.
The status report also shows you the version which includes the virus signature info.
As soon as it can that error goes away.

There's a "verbose" option in the config settings (which logs files that "passed" the virus check as well as failed)

You need to tick 'Enable ClamAV integration' before it will actually scan any files.

Test it's working by creating a small file with the short Eicar test signature string

Notes: ClamAV does use a fair bit of memory (because it keeps a copy of all the virus signatures)

Also sensible to run a Nagios NRPE check to ensure ClamAV is always running.

Patch:

Requires core patch to avoid possible data loss (race condition) - use my rerolled patch (#35) 

Automatic Entity Label (auto_entitylabel)

d.o. page

"Essential"

Hide entity labels (i.e. titles) or auto-generate them. (Works for anything - nodes, comments, taxonomies).

Better Exposed Filters (better_exposed_filters)

d.o. page

"Essential"

My recommendation - safe to use but understand it's currently pretty limited due to bugs.

To activate, change a view's Exposed Form style (Advanced column) to 'Better exposed filters'.  

  • Lets you enable AJAX auto submit. The difference is without BEF, with Use AJAX, an AJAX request (vs a full page reload) is made but ONLY when you click 'Apply'.  With BEF, as soon as you change a dropdown the view updates (like the filters on this site).  
  • You can change the input method for each field (e.g.a single checkbox for what would otherwise be a True/False dropdown), make them "collapsible", add select all/select none links where appropriate.  
  • Rewrite option that lets you reword all the options for the filter and also delete some.

Limitations:

  • If you have a search field - e.g. Combine fields filter - you MUST turn on 'Exclude Textfield' if you are using 'Autosubmit'  
  • Most of these options *aren't* available for taxonomies (e.g. webform where  
  • If you use the default views single or grouped exposed filters, with selects/radios, they work correctly, but when you change them to BEF style, with checkboxes and AJAX, they don't (form is submitted and the checkbox has disappeared)
  • Bug: reset button doesn't use AJAX, it sends you to a view URL instead (disable it in settings)

 

So all you can really do with BEF at the moment is use the AJAX setting.

Documentation 

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:

D8 Editor Advanced link (editor_advanced_link)

d.o. page

Adds options should as choice of target, title, class ID etc. to the link dialog in CKEditor.

Needs configuring after install.

Datetime Range (datetime_range)

d.o. page

"Essential"

Now in core, but you need to enable it.

Adds an 'all-day' option.

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.

SEO Checklist (seo_checklist)

d.o. page

Shows a long checklist, split over a series of tabs, you can tick off items and some (e.g. modules you need to install) are auto-detected. See Module of the Week blog post. 

String Overrides (stringoverrides)

d.o. page

"Essential"

Replace text on the site.

Memcache API and Integration (memcache)

d.o. page

"Essential"

Enable memcache_admin submodule to access stats page.

Requires the PECL PHP memcached module.   I've written a blog post explaining how to install this on Acquia Dev Desktop

CKEditorHeight (ckeditorheight)

d.o. page

Makes CKEditor fields respect the "rows" setting of the fields. (Has to be converted to pixels - there's a global setting, configured via a pixel factor and offset.)

@font-your-face (fontyourface)

d.o. page

Not recommended

For using typekit, google fonts etc.  But it's simpler to do web fonts manually in Twig templates/CSS.
D8 stable/mature - however it's confusing how you're meant to setup Typekit etc. and there are problems with uninstall it…  (there was an old D7 "typekit" module - deprecated).

28 Aug 2018: can't be uninstalled cleanly. The method described in #24 here works: https://www.drupal.org/project/fontyourface/issues/2916712#comment-12751073 if for example, you get an "The "font" entity type does not exist." message when running drush cr

General Data Protection Regulation (gdpr)

d.o. page

Not recommended

Couldn't install either alpha branch (8.1 or 8.2on Debian Stretch (9.5) wants php7.1-zip which doesn't seem to be available.  
Got error about missing checklistapi module after uninstall and had to remove from DB manually

Views Secondary Row (views_secondary_row)

d.o. page

"Essential"

For Views that use Table format. Adds a row underneath each record - you change the format from 'table' to the 'secondary row' option, you get an extra select dropdown in the table *settings*, and you can also specify colspan.  This does mean the label will be missing by default (you won't have a column header any more) - so you need to edit the field and tick rewrite output, and then specify your desired label, followed by the field value in Twig.
 

Bamboo Twig (bamboo_twig)

d.o. page

Way to embed lots of objects in twig. note you have to selectively enable various sub modules for each of the commands.  Seems pretty actively developed and well documented.