Primary tabs
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)Name | D8 | Personally Tested | Last Updated Sort descending |
---|---|---|---|
Alexa (alexa) | ✔ | ✖ | |
Integrates with Amazon Echo. Allows Drupal to respond to Alexa skills requests. See Dries' blog with video demo. |
|||
Exclude Node Title (exclude_node_title) | ✔ | ✔ | |
There are situations where you will want to hide a node title - e.g. if you have a view and insert an image field that's an entity reference to another content type. Module allows you to hide titles by content type or view mode and for all nodes or just a custom selection. Beta in D8. |
|||
Flippy (flippy) | ✔ | ✔ | |
Add Next/previous links to node view for specific content types - e.g. image gallery. Powerful - supports: next/last, random link, you can specify exact text used etc. Currently a dev version in D8. Setup: activate for a content type in the 'Edit' tab (NOT manage display). Once Flippy is active, Manage Display tab will have a pager field so you can reposition the links relative to other fields on the page (e.g. above or below image). |
|||
Group (group) | ✔ | ✖ | |
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. |
|||
AddToAny Share Buttons (addtoany) | ✔ | ✖ | |
Nice, clean, SVG sharing buttons. Project page says it's specifically optimised for Drupal. |
|||
Pathauto (pathauto) | ✔ | ✔ | |
"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). |
|||
PDF Reader (pdf_reader) | ✔ | ✔ | |
Render a file field with one of several PDF readers. Mixed success with pdf.js support - seems to force a full screen view. |
|||
Entityqueue (entityqueue) | ✔ | ✔ | |
Build a custom list of nodes. The setup is via Admin > Structure. Currently D8 alpha. |
|||
Automatic Nodetitles (auto_nodetitle) | ✖ | ✖ | |
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. |
|||
HMS Field (hms_field) | ✔ | ✔ | |
Hours/minutes/seconds field type (formats: h:mm, h:mm:ss, m:ss, h, m or s). Drupal 8 in beta. |
|||
Field collection (field_collection) | ✔ | ✖ | |
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. |
|||
Telephone (telephone) | ✔ | ✔ | |
Telephone number field type. This is in core, but you need to enable it. |
|||
Twig Xdebug (twig_xdebug) | ✔ | ✔ | |
Use Xdebug breakpoints in Twig templates - |
|||
Prepopulate (prepopulate) | ✔ | ✔ | |
Allows you to prefill form fields by supplying values in a query string. Syntax (also in readme) Useful for bookmarklets. D8 alpha version. |
|||
Unique field ajax (unique_field_ajax) | ✔ | ✔ | |
"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. |
|||
Restrict Login or Role Access by IP Address (restrict_by_ip) | ✖ | ✖ | |
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. |
|||
IMCE (imce) | ✔ | ✔ | |
Adds a file browser to the CKEditor link dialog, so you can select files that have already been uploaded. Settings in Admin > Config > Media. In many cases will be better IA to add a dedicate file field to the content type and use that, or wait for the new media browser (currently being designed, follow the Drupal UX group.) |
|||
Autofocus (focus) | ✖ | ✖ | |
Autofocuses the first field of form (forms can be specified). No sign of a D8 port. |
|||
Autosave (autosave) | ✖ | ✖ | |
Saves snapshot of content type form using AJAX. Content types and save frequency can be configured. No sign of a D8 port yet. |
|||
Block Visibility Groups (block_visibility_groups) | ✔ | ✖ | |
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) | ✖ | ✖ | |
Protect against brute-force login attacks. Unclear what's happening with porting of this. |
|||
TagCloud (tagclouds) | ✔ | ✔ | |
Provides a block with a tag cloud of chosen taxonomy term. Works but a bit buggy, e.g. UI taxonomy setting reverts to 'tags'. Requires clearing the cache to update (including changing any settings). Choice of numbers after each tag to indicate quality, or 'wordcloud' style with varying sizes (will need you to modify your CSS to add some spacing between words). |
|||
Redirect (redirect) | ✔ | ✔ | |
"Essential" Add redirects, including specifying from the full range of HTTP codes (e.g 307 Temporary). Won't let you redirect from the homepage, use Config > Basic Site Settings for that. |
|||
Token (token) | ✔ | ✔ | |
"Essential" Adds a user interface for browsing tokens (the tags you can insert into various fields). |
|||
Module builder (module_builder) | ✔ | ✔ | |
"Essential" Add a UI to easily create scaffolding for new modules (including hooks, plugins, permissions etc.) NB: first, you need to download drupal-code-builder from GitHub and place it in a /libraries top-level directory (see module builder's README.txt). You can preview and edit the output files before writing to disk - and each module's configuration is saved as a node, so you can add another hook etc. at a later date, regenerate the files and copy/paste the extra things you need. Video walkthrough. |
|||
Web Profiler (webprofiler) | ✔ | ✔ | |
"Essential" Install the devel module first. The profile is a toolbar at the bottom of the screen. Features:
Tip: there are further reports ("collectors") you can turn on in the module preferences, and there's a shortcut to these from the menu in the first icon (Drupal logo). The toolbar is only a summary, all icons are clickable to view a full report. Each report is saved in the DB for later reading. This module was ported from Symfony |
|||
Image Lazyloader (lazyloader) | ✔ | ✖ | |
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. |
|||
Flag (flag) | ✔ | ✔ | |
"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. |
|||
Warden (warden) | ✔ | ✔ | |
A fork of the System Status module, but with a Symfony app for you to install to act as a server, rather than using a paid third-party service. Monitor core/module update status of multiple Drupal sites. If you're familiar with Nagios and NRPE, it's a little bit like that, but for Drupal modules, and more lightweight. Note the server uses MongoDB, so you need to install that, plus the PHP extension, and it communicates with a public key-pair, though it should set that up itself. |
|||
Advanced Page Expiration (ape) | ✔ | ✔ | |
Not recommended I would avoid this. The idea is you enter URL paths with wildcards and override the cache expiration. I was unable to get it to work properly for pages (settings on config under Development > Performance) Also, re: caching images, those are files being served directly by Apache or Nginx, not via the Drupal front-controller, so caching settings need to be configured there. |
|||
Two Factor Authentication (tfa) | ✔ | ✔ | |
"Essential" install tfa and ga_login (TFA is just a framework, it doesn't come with it's own login plugins.) Use this patch I wrote - it adds display of validation skip times and an admin reset button for users who are got locked out. My installation instructions: Next you need to generate an encryption profile. Set key provider to File rather than Configuration, this means the key won't end up in your version control. Tick the 'strip trailing line breaks' box to avoid the "The selected key size does not match the actual size of the key." error Key path should be relative to Drupal so the config will work on multiple sites Remember to save the key somewhere in your password manager, or your ansible variables, in case you lose the files later. In the TFA settings (/admin/config/people/tfa) you probably want to increase the number of times a user can skip validation. Note that TFA has a separate 'Tfa user login' block (replacing the ordinary 'User login') |
|||
Features (features) | ✔ | ✖ | |
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. |
|||
Configuration Update Manager (config_update) | ✔ | ✔ | |
You also need to enable config_update_ui, which adds an 'Updates report' tab to Config Sync (/admin/config/development/configuration/report) |
|||
Configuration Override Warn (config_override_warn) | ✔ | ✔ | |
"Essential" Displays a message on config pages indicating which config settings have been override by settings. |
|||
Bamboo Twig (bamboo_twig) | ✔ | ✔ | |
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. |
|||
Views Secondary Row (views_secondary_row) | ✔ | ✔ | |
"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. |
|||
General Data Protection Regulation (gdpr) | ✔ | ✔ | |
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. |
|||
@font-your-face (fontyourface) | ✔ | ✔ | |
Not recommended For using typekit, google fonts etc. But it's simpler to do web fonts manually in Twig templates/CSS. 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 |
|||
CKEditorHeight (ckeditorheight) | ✔ | ✔ | |
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.) |
|||
Memcache API and Integration (memcache) | ✔ | ✔ | |
"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. |
|||
String Overrides (stringoverrides) | ✔ | ✔ | |
"Essential" Replace text on the site. |
|||
SEO Checklist (seo_checklist) | ✔ | ✔ | |
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. |
|||
Structure Sync (structure_sync) | ✔ | ✔ | |
"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. |
|||
Datetime Range (datetime_range) | ✔ | ✖ | |
"Essential" Now in core, but you need to enable it. Adds an 'all-day' option. |
|||
D8 Editor Advanced link (editor_advanced_link) | ✔ | ✔ | |
Adds options should as choice of target, title, class ID etc. to the link dialog in CKEditor. Needs configuring after install. |
|||
Masquerade (masquerade) | ✔ | ✔ | |
"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:
|
|||
Better Exposed Filters (better_exposed_filters) | ✔ | ✔ | |
"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'.
Limitations:
So all you can really do with BEF at the moment is use the AJAX setting. |
|||
Automatic Entity Label (auto_entitylabel) | ✔ | ✔ | |
"Essential" Hide entity labels (i.e. titles) or auto-generate them. (Works for anything - nodes, comments, taxonomies). |
|||
ClamAV (clamav) | ✔ | ✔ | |
"Essential" Virus check files uploaded by users. In Drupal - when it can't connect you get an error on the Status Report. 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) Patch: Requires core patch to avoid possible data loss (race condition) - use my rerolled patch (#35) |
|||
SMTP Authentication Support (smtp) | ✔ | ✔ | |
"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:
(note to self: see SM notes) |