I recently spent about a year as a Drupal 7 developer. Years ago I was a PHP web developer and I dabbled with Drupal 4. After discovering Django and the CMS's built on Django, I hoped to never be cursed with Drupal again. Working with Python and Django is an apprenticeship to engineers who know more than me and want me to adopt good habits. By contrast, I think PHP and Drupal encourage bad habits that have to be carefully guarded against; the work-arounds are often painful. Unfortunately for me, the team wanted Drupal. I like my team, and decided to go along with their preference even if it meant using a tool that I disliked.
Developers often have strong opinions about technology. Reasonable people can disagree, and developers can strongly disagree while still having respect for those who manage to solve problems with the hated technology. This is a frank post discussing my frustration with Drupal. I know many talented web developers who make their living with Drupal and I respect many of these developers. However, I often wonder how much more productive they would be if they used a decent tool. Please do not mistake my criticism for Drupal to be disdain for the thousands of talented people who contribute in that community.
This post is meant to be about Drupal, however I will reference Django regularly because that is the alternative that I am best acquainted with. It provides a good contrast to the problems I will describe. My experience is primarily with Drupal 7, but I don't think Drupal 8 significantly changes things.
Where Drupal Fits
Drupal deserves a lot of credit for being the first modern open source web framework to be widely adopted. It brought web development out of the era of CGI style PHP and provided a real architecture for the web. The team behind Drupal have also done an amazing job at building a huge, energetic, and inclusive community that includes everyone from developers, to designers, to content authors. Drupal is so popular because it fit a need that no other open source framework did for many years. Many of my frustrations with Drupal can be understood as early design challenges that are hard to change with such a massive level of adoption.
I like the way this post classifies Drupal, but I will update it a bit:
- WordPress is a simple content management system, getting more advanced over time.
- Drupal is an advanced content management system with framework-like tendencies (that are increasing over time).
- Django is a framework, but has add-ons that provide content management (Django-CMS, Pinax, and others).
The author of this post does a great job explaining the difference between a CMS and a framework (see that post for a less antagonistic comparison of Django and Drupal):
A CMS targets simplification of the user-interface for the end-user in order to input content, manage layouts/views, and apply custom formatting/styling without requiring development intervention. Frameworks on the other hand target the developer – they are independent from the presentation layer and do not incorporate business logic. Frameworks simplify the development process while attempting to enforce best practices and some sort of object model.
The earlier referenced post makes a good recommendation of when to use each technology. If you want something very quick and simple that won't change much over time, WordPress is the best due to its simplicity and ubiquity (I predict that better alternatives will arise). If you want to build a web application, then Django or another real web framework is the best way to proceed. Where things get murky is when you want a traditional site that needs to be customized and will likely expand in functionality over time. This is where most people argue that Drupal fits, and that was true until CMS plugins for Django and other frameworks had matured to become viable alternatives. Given that web sites inherently become more complex over time, any non-trivial site will naturally progress towards needing a framework. I can't think of a modern use case where there are not better alternatives to Drupal.
Why My Team Wanted Drupal
However, my team did select Drupal. Here are their arguments that I believe had real merit:
- Drupal has a mature CMS administration UI available nearly out-of-the-box. This post is a good explanation of why a Django developer selected Drupal for exactly that reason (note that the Django developer did not evaluate any CMS package for Django). I think that currently Drupal has a slight lead in the CMS user interface over Django even with a CMS package like django-cms.
- Drupal has mature enterprise support options. I am not aware of another vendor supporting an open source CMS with the credibility that Acquia has.
- Drupal has mind-share. Vendors worry about integrating with it. It works with our document management system, our translation service, our hosting provider, our network security system. No other open source CMS has similar supported integration options.
Some of their arguments sounded good, but as our familiarity with Drupal increased I found them to be hollow:
- Drupal has a huge and enthusiastic community. This is true, but I did not find it to be a more helpful community than for other projects. Due to its popularity and inclusiveness, Drupal's community consists of a much higher percentage of participants who don't have any idea what they are doing.
- Drupal has a huge number of modules. This is also true, but not very useful. Most of the modules do not get upgraded between versions (see below). Most of the modules are unfinished, unmaintained, poorly designed, or only solve the problem in a specific way that didn't really help other deployments. Using an existing module was often more effort than writing one from scratch, and far more effort than using a decent developer framework. Having to select between multiple modules to do common tasks often took significant time only to discover that none of them worked.
The above description should be enough for you to understand why I find Drupal development painful. The specific problems are too many to describe in detail, but I will list a few.
- Drupal is built on PHP. This post is a detailed list of why that is a problem. I think Drupal makes a noble effort at bringing some sanity to the PHP language, but it is an impossible task.
- Drupal has no concept of configuration management. Data and configuration are mixed in the same database. This makes it very difficult to get your changes from development, through test and staging, to the production site. The Drupal way of getting configuration changes into production is either to do them on the production site or take good notes and follow those notes exactly. In desperation, some developers engineer crazy hacks to merge the important parts of development and production databases. This also means that configuration will not be stored in source control and can not be able to roll back if there is a problem. In Drupal 7, a mixture of the features module, Strongarm, node-import-export, Context, using the APIs directly, and scripted edits to the DB can get close to being a robust release process. But some configuration changes are impossible to do outside of mouse clicks in the UI. Addressing this is a major effort in Drupal 8, but that release will not have a complete solution, and it will break the workarounds used in Drupal 7.
- The database is a mess and constantly changing. Any sane system wouldn't require you to hit the DB to make changes, but since this one does it is important to know that it is poorly documented and risky. It will break during upgrades. Be aware that each module can make changes to the main DB, which will also break during upgrades.
- The templating system is horrible. It is so bad that it is going to be replaced in Drupal 8 with the Symphony templating system. This is a step in the right direction, even though it will make upgrading as painful as migrating to a different system.
- Drupal is not object oriented. The internal state is organized as a pile of nested arrays that don't follow consist logic. Values are repeated, and it is impossible to know which one is the correct instance to use. The organization of the arrays changes with each release.
- All of these changes mean that there is no backwards compatibility. You generally have to re-code customizations for each release. If you are looking at Drupal 8, I suggest that now is the time to migrate to another system.
- How URLs are tied to functions through the menu system is arcane. Adding a simple code driven page requires touching multiple unrelated files.
- It is easy to write insecure code with Drupal. When displaying values on pages you have remember to use the "safe" parameters. Modern frameworks make the sanitized outputs the default and the raw ones available if you need them, but not Drupal.
- Drupal's vaunted hook system is worse then spaghetti code because it is scattered in multiple files. It is not helpful to allow any module to inject code into any function at runtime; it is very hard to follow in a debugger.
- The development tools are poor. Eclipse+XDebug was unreliable. Netbeans was more stable, but still not great.
- The documentation is unorganized, incomplete, and exists in multiple places.
- All of this makes for a steep learning curve, even when simply moving between existing sites or between releases. I was producing sites in Django much quicker than I was able to produce sites in Drupal 7 even after having previously played with Drupal 4.
The slim advantages of Drupal do not outweigh the architectural deficiencies. However, if you are still trying to get something done with Drupal 7, then I highly recommend this book.
Of course this post represents my own experience, and does not reflect the opinion of my employer who considers itself a content Drupal user.
If you see any inaccuracies in this post, then please let me know in the comments or through email.