The Drupal Way™

The Drupal Way

I've worked with a wide variety of developers, designers, content managers, and the other Drupal users in the past few years, and I'm pretty sure I have a handle on most of the reasons people think Drupal is a horrible platform. But before I get to that, I have to set up the rest of this post with the following quote:

There are not a hundred people in America who hate the Catholic Church. There are millions of people who hate what they wrongly believe to be the Catholic Church — which is, of course, quite a different thing.

Forgive me for diverging slightly into my faith, but this quote is from the late Fulton J. Sheen, and is in reference to the fact that so many people pour hatred on the Catholic Church not because of what the Church actually teaches, but because of what they think the Catholic Church teaches. Once someone comes to understand the actual teaching, they are free to agree or disagree with it—but there are comparatively few people who disagree with teachings they actually understand.

Similarly, the problems most people have with Drupal—and with systems like it—are problems not with Drupal, but with their perception of Drupal.

Java Jane: One-off vs. Flexible Design

A Java developer (let's call her Jane) is used to creating a bunch of base object classes and a schema for a database by hand, then deploying an application and managing the database through her own wrapper code. Jane is assigned to a Drupal project, takes one look at the database, and decides that no sane person would ever design a schema with hundreds of tables named field_data_* and field_revision_* for every single data point in the application!

Why does Drupal have So Many Database Tables?

In reality, Drupal is doing this because The Drupal Way dictates that things like field data should be: flexible (able to be used by different kinds of entities (content)), able to be translated, able to be revised with a trackable history, and able to be stored in different storage backends (e.g. MySQL, MariaDB, MongoDB, SQLite, etc.). If the fields were all stored in a per-entity table as separate columns, these different traits would be much more difficult to implement.

Thus, The Drupal Way is actually quite beneficial—if you want a flexible content management system.

I think a lot of developers hate Drupal because they know they could build a more efficient web application that only has the minimal required features they need by simply writing everything from scratch (or using a barebones framework). But what about the next 72 times you have to build the exact same thing, except slightly different each time, with a feature that's different here, translation abilities there, integration with Active Directory for user login here, integration with a dozen APIs there, etc.?

There's a maxim that goes something like: Every seasoned web developer started with plain HTML and CSS, or some hosted platform, then discovered a dynamic scripting language and built his own CMS-like system. Then, after building the CMS into a small system like many others but hopelessly insecure and unmaintainable, the developer realized that thousands of other people went through the same progression and ultimately worked together on systems like Drupal. Then said developer starts using Drupal, and the rest is history.

I know you could build a small system that beats the pants off Drupal performance-wise, and handles the three features you need done now. But why spend hours on a login form (that probably has security holes), session handling (ditto), password storage (ditto) forms in general (ditto), content CRUD interfaces, a translation system, a theme layer, etc., when you can have that out of the box, and just spend a little time making it look and behave like you want it? The shoulders of giants and all that...

.Net Neil: Letting Contrib/Bespoke Code Let You Down

A .Net developer (lets call him Neil) joins a Drupal project team after having worked on a small custom .Net application for a few years. Not only does he not know PHP (so he's learning by seeing the code already in use), he is also used to a tightly-controlled application code structure, which he knows and owns end-to-end.

After taking a peek inside the custom theme, and a couple of the Drupal modules that the team has built in the past year, .Net Neil feels like he needs to take a shower! He sees raw SQL strings mixed in with user-provided data, he sees hundreds of lines of business logic in two dozen theme template files, and he can't find a line of documentation anywhere!

Why don't you use PDO for Database queries?

Who would blame Neil for washing his hands of Drupal entirely?

However, Neil shouldn't throw out the baby with the bathwater. Unfortunately, due to PHP's (and, by extension, Drupal's) popularity, many non-programmers or junior level programmers work on Drupal sites, and know just enough PHP to be incredibly dangerous.

Now, it doesn't help that Drupal allows PHP inside template files—something that will be corrected in Drupal 8—and it doesn't help that PHP is a quirky language full of inconsistencies and security holes—something that's vastly improved in PHP 5.3+ (especially 5.4+). But while some decide that PHP is a fractal of bad design, or that they simply hate PHP (mostly because of code they've seen that's from either designers or new programmers with a lot to learn... or they have a lot of baggage from pre-PHP 5 days), I think it's best to understand that bad code is bad code regardless of the language. Using Ruby, Django, Go, Node.js, etc. does not automatically make you a better programmer. Just like writing in French doesn't make you a great author. Its just a different language that's useful for different purposes.

One more note here: in all the Drupal code I've seen, there are three levels of quality:

  • Code in Drupal Core: Drupal core is extremely well-documented, has low cyclomatic complexity, has almost full automated test coverage, and has a very high bar for code acceptance. Drupal core is not only a great example of good code in PHP-land, but across languages—especially the latest version (which is on the tail end of some pretty major refactoring).
  • Code in Contrib Modules: Contributed modules can be pretty hit-or-miss. Even with a more rigorous review process in place, many contrib modules have hacked-together code that has some subtle and not-so-subtle security and performance flaws. However, the modules used by a vast array of Drupal installations, and included with popular Distributions (like Views, Panels, Colorbox, etc.) are usually very well constructed and adhere to the Drupal coding standards. (Another good way of knowing a module is good: if uses it).
  • Custom code: Welcome to the wild west. I've seen some of the craziest code in custom templates, hacked installations of Drupal, hacked contrib modules, and strange custom modules that I'm amazed even compile.

When people say Drupal has a terrible security track record, they often point to lists of all Drupal-related security flaws (like this one). Unfortunately for this argument, it holds little water; a quick scan usually finds that well over half the affected modules are used by a very small share of Drupal sites, and a flaw that affects Drupal core is very rare indeed (see how rare on Drupal's security track record page).

The Drupal Way™

Jane and Neil would both come to appreciate Drupal much better if they understood why Drupal does certain things in certain ways. They would also likely appreciate the strictness and thoroughness of Drupal's Coding Standards and security guidelines, and the fact that patches for consideration in Drupal core undergo strict reviews and must pass a full suite of automated tests.

They'd probably also learn to accept some of Drupal's quirks once they realize that the people who built and are making Drupal better range from a mother-of-five-turned-hobbyist-programmer to the world's largest government organizations. Drupal can't be everything to everyone—but it's one of the most flexible web content management systems available.

I'm going to go through some of the main areas where I've seen people get derailed in their understanding of Drupal.

Extending Drupal with Contributed Modules

A lot of first-time Drupal users decide they need twenty or thirty modules to add things like share buttons, fancy blogging features, forum tweaks, etc. Eventually, many fresh Drupal sites end up with over 100 enabled modules (of varying quality), and the site takes seconds to load a single page.

This problem is the open buffet syndrome, outlined in detail here. In addition to adding way too much functionality to a site (usually making the site harder to use anyways), adding a ton of extraneous modules makes it harder to track down problems when they occur, and usually makes for slower performance and a very large memory footprint on a server.

How do you combat the open buffet? Be frugal with modules. Only enable modules you really need to help your site run. Instead of adding a module for something, create a new View for a blog page or for a special block that lists a certain type of content. For larger and more customized sites, having a custom module that performs one or two small hook_alters to change a couple things is better than enabling a beefy module that does what you need and a thousand more things besides.

Don't be a module glutton!

One more tip: Whenever you consider using a contributed module, check out its ranking on the Project usage overview page, and check how many sites are currently using the module (under the 'Project Information' heading on the project home page). If the module is only used by a few hundred sites, that could be a sign that it's not going to be updated in a timely fashion, or thoroughly vetted for performance and security issues. I'd always recommend stepping through a module's code yourself if it's not a very popular module—if it's a tangled mess of spaghetti, steer clear, or submit patches to clean it up!

Configuration and Code

Drupal's philosophy when it comes to configuration and settings is that everything, or nearly everything, should be manageable through a user interface. Many developers who work outside of web applications are used to storing a lot of configuration in code, and don't see much value to making sure everything can be configured by administrators on-the-fly. In fact, many developers scoff at such an idea, since they lose some control over the final application/site.

However, this is one of the traits of Drupal that makes it so powerful, and so beloved by site builders and people who actually use the sites developers build for them.

This presents a problem, though—if things are configurable by end-users, how do we version-control settings? How do we deal with different environments, like moving a feature from a development server to a test server, then to the live server? With Drupal <6, this was very challenging indeed, and usually required a lot of manual SQL work in update hooks. However, in Drupal 6 and 7, the situation has improved quite a bit, and in Drupal 8 and beyond, configuration management will likely be a standout feature (see: Configuration management architecture).

The Features module lets developers take things like content types, image styles, site settings, and even content itself (with the help of something like Universally Unique IDentifier), and export them to code. Then, that code can be version controlled and deployed to different environments with some simple drush commands or the click of a button in the UI. As long as the modules you're using use normal Drupal variables, or use CTools Exportables (most of the top modules do), you can use Features to keep things in sync.

Another thing that irks non-Drupal developers (especially those used to 'cowboy coding'—not using any kind of framework or system when they build sites) is the fact that the database is abstracted away. In Drupal, it should be fairly rare that a developer needs to write database queries. Almost everything within Drupal is wrapped in an API, allowing Drupal to work across a variety of platforms and backends. Instead of writing variables to the {variables} database table (and dealing with serialization and unserialization), you use variable_get() and variable_set()—these functions even take care of static caching for performance, and configuration included via settings.php. Instead of querying twenty different tables to find a list of entities that match your conditions, you use EntityFieldQuery. It may seem inefficient at first, but it's actually quite freeing—if you do things The Drupal Way, you'll spend less time worrying about databases and schemas, and more time solving interesting problems.

One more tip: If you ever see the PHP filter module enabled on a site, or something like Views PHP filter, that likely indicates someone getting lazy and not doing things The Drupal Way™. Putting PHP code into the database (as part of content, the body of a node, or as part of a view) is like pouring Mentos into Diet Coke—it's a recipe for disaster! There's always a way to do what you need to do via a .module file or your theme. Even if it's hacked together, that's a million times better than enabling the insecure, developer-brain-draining module that is the PHP filter.

Themes and the .tpl.phps of DOOM!

Drupal has had a long and rocky relationship with themers and designers—and at some times in Drupal's history, the very idea of the responsibility of a 'theme' has been unclear. One principle has always been clear, however: themes should deal with HTML markup, CSS styling, some JavaScript for the user interface, and maybe a tiny bit of PHP to help sort data into certain templates.

That last bit, however—the 'tiny bit of PHP'—has been abused very often due to the fact that Drupal has been using a custom theme engine called PHPTemplate, which allowed the use of any PHP code inside any template (.tpl.php or sometimes referred to as 'tipple fip') file.

Many themers, designers, and new Drupal developers have mangled templates and thrown all kinds of code into template files which simply doesn't belong. The idea that HTML markup and PHP code can be mixed and mashed together is something that comes out of a 'scripting' mentality that is predominant in very old versions of PHP, custom-coded PHP websites, and an old-school PHP <4 mentality. Nowadays, there should be a distinct separation between markup and styling (a theme's responsibility), and the business logic that generates data to be put into markup and styled (a module's responsibilty—or, rarely, inside a theme's template.php).

I've seen sites where there were 30+ copies of the theme's page.tpl.php file, all just to change one variable on different pages on a site. What the developer should've done is use one page.tpl.php, and implemented template_preprocess_page() (which can be invoked in either template.php, or in a module as hook_preprocess_page()). Inside that function, the developer can set the variable depending on which page is being viewed. If the developer were to continue to duplicate page templates, he'd be in a very sorry situation the first time he had to change the page markup sitewide—instead of changing it in one page template, he'd have to change it in 30+ copies, and make sure he didn't miss anything!

Don't Repeat Yourself - DRY

The DRY principle (Don't Repeat Yourself) applies very strongly to themes and templates—instead of making a bunch of duplicate templates and changing little things in each one, use hook_preprocess_hook() functions in either your theme or custom modules.

One other important note: If you're coming from Wordpress or another PHP-based CMS that often mixes together HTML markup and PHP files throughout modules, plugins, themes, etc., please try to get that concept out of your head; in Drupal, you should have one, and only one opening <?php tag inside any PHP code file, and templates (.tpl.php files) should only include the most basic PHP and Drupal theming constructs, like if, else, print(), hide() and render(). If you have any more than that in a template, that's a sign of code smell.

Thankfully, Drupal 8 will use Twig instead of PHPTemplate as the default template engine. Twig is a true templating language, and doesn't allow PHP. It's also more designer-friendly, and doesn't require a rudimentary knowledge of PHP to use—or an advanced knowledge of PHP to use well.

Code Quality

Spaces versus tabs. Putting curly braces on the same line as the if statement or the next. These are the things that will be argued ad infinitum, and these are the things that don't really matter to a compiler. But they matter greatly to a community of developers. The larger and more diverse the community, the more important they are!

Drupal developers come from around the world, from many different cultures. It's important that we have a common way of communicating, and it helps quite a bit if we all use certain standards when we share code.

Since the mid-2000s, the Drupal community has banded together to make and enforce some very thorough coding standards for PHP, JavaScript, CSS, and other code used in Drupal core and contributed projects. The community is in ongoing discussions about code quality and review processes, and continues to adapt to modern software development best practices, and does a great job of teaching these practices to thousands of new developers every release.

Since early in the Drupal 7 development cycle, the Drupal community has written automated tests to cover almost all of Drupal core and many large contributed projects, and has built testing infrastructure to ensure all patches and bugfixes are thoroughly tested before being accepted.

Since early in the Drupal 8 development cycle, the Drupal community has used the concept of core gates and issue count thresholds, as well as divided responsibilities in different core initiatives, to ensure that development didn't get too scattered or start making Drupal core unstable and incoherent. Drupal 8, though in alpha stages, is already very stable, and is looking to be the most bug-free and coherent release yet.

Drupal's strict coding standards already match up pretty well with the suggested PSR standards from the PHP Framework Interop Group, and Drupal 8 and beyond will be taking future PSRs into account as well. This will help the Drupal community integrate more easily into the larger PHP world. By following standards and best practices, less time is spent trying to get individual PHP classes, methods, and configurations to work together, and more time is spent creating amazing websites, applications, and other products.

One tip: The Coder module will help you to review how well your own code (PHP, JS and CSS) follows the Drupal Coding standards. It also helps you make sure you're using best practices when it comes to writing secure code (though automated tools are never a perfect substitute for knowing and writing secure code manually!).

Even further: Many developers who work with PHP-based systems seem to have followed the progression of designer -> themer -> site builder -> developer, and thus don't have a strong background in software architecture or actual 'hard' programming (thus many ridicule the PHP community as being a bunch of amateur programmers... and they're often right!). I'd suggest trying to work on some small apps in other languages as well (might I suggest Node.js, Go, Java, or Ruby), to get a feel for different architectures, and learn what is meant by terms like SOLID, DRY, TDD, BDD, Loose coupling, YAGNI, etc.

Hacking Core and Contrib modules

Every time you hack core, God kills a kitten. Please, consider the kittens.

The above image comes from an idea originally presented at DrupalCon Szeged 2008 by Greg Dunlap. It goes like this: Every line of code you change in Drupal core or one of the contributed modules you're using will add many man-hours spent tracking the 'hack' over time, make upgrading your site more difficult, and introduce unforeseen security holes and performance regressions.

The times when actually modifying a line of code anywhere outside your custom module or theme's folder is a good idea are extremely rare.

If you find you are unable to do something with Drupal core or a contributed module to make it work the way you want, either you haven't yet learned how to do it the right way, or you found a bug. Drupal is extremely flexible with all it's core hooks, alter hooks, preprocess functions, overrides, etc., and chances are, there's a more Drupalish way of doing what you're trying to do.

On the rare occasion where you do have a problem that can only be fixed by patching core or a contrib module, you should do the following:

  1. Search the project's issue queues to see if someone else had the same problem (chances are you're not the first!).
  2. If you found an issue describing the same problem, see if the issue is resolved or still open:
    • If the issue is resolved, you might need to download a later -dev release to fix the problem.
    • If the issue is not resolved, see if there's a patch you can use to fix the problem, test the patch, and post back whether the patch resolves your problem, so the patch progresses towards being accepted.
    • If the issue is not resolved and there is no patch to fix the problem, work on a patch and submit it to the issue queue.

The key takeaway here is the idea of investing in patches. If you find an actual bug or would like to see some improvement to either Drupal core or a contributed project, you should either test and push forward existing patches, or contribute a patch to get your problem resolved.

When you do things this way, you no longer operate on an island, and you'll benefit from community feedback and improvements to your patch. In addition, by only using patches that are tracked on a issue, you can track your patches more easily. On the rare occasion when I need to use a patch, I put the patch file (named [issue_number]-[comment_number].patch) into 'sites/all/core-patches' directory, and then add an entry in a 'Patches' file along with a link to the issue, a description of the patch, and why it is necessary.

Participating in the Drupal Community

In the previous section, I mentioned the idea of not being an island when developing with Drupal. How true this is! You're using software that's built by thousands of developers, and used by millions. There are people working on Drupal from every continent, and this diverse community is one of the most positive aspects of Drupal.

On's front page, the first line of text reads:

Come for the software, stay for the community.

With so many people using and building Drupal, chances are you aren't the first person to encounter a particular problem, or build a certain piece of functionality. And if you can't find a module or a simple built-in way to do something you need to do, there are plenty of places to go for help:

And these are just a few of the places where you can discover community and get help!

As I said before: don't be an island. With proprietary, closed-source software, you don't have anywhere to go except official (and expensive) vendor support. With Drupal, you get the code, you get to talk to the people who wrote the code, and you can even help make the code better!

Global state / Assuming too much

Not every request for a Drupal resource (most often a path defined in hook_menu()) comes from a web browser, and many variables and things you assume are always available are not. A lot of developers forget this, and write code that assumes a lot of global state that will be missing at certain times—if drush (or the command line in general) is in use, if data is being retrieved via AJAX, or if a data is being retrieved by some other service.

Always use Drupal's API functionality instead of things like $_GLOBALS and $_GET. To get the current URL path of the page being viewed, use current_path(). To use dynamic URL paths, use paths and the arg() function or Drupal's built-in menu router instead of adding a bunch of query parameters.

Additionally, use Drupal's menu router system and Form API to the fullest extent. When you define a menu item in hook_menu(), you can pass an access callback which integrates with Drupal's menu access system and lets you determine whether a given user has access (return TRUE) or not (return FALSE). Drupal takes care of outputting the proper headers and access denied page for you. When building forms, use the built-in validation and submit callback functionality, along with helper functions like form_set_error(). Using APIs that are already built into Drupal saves you time and code, and usually ensures your forms, content, etc. is more secure and more performant.

Finally, always enable logging (typically via syslog on production servers, or logging errors to the screen in development environments) and check your logs over time to make sure you're not generating a bunch of errors in your custom code.

Drupal 8 will be dropping some bits of global state that are often abused in Drupal 7 and below—the use of the global $user object is discouraged, and $_GET['q'] won't be available at all! Use the API, Luke, and the force will be with you.

The Drop is Always Moving

Though this post is one of the longest I've written on this blog, it barely scratches the surface of a full understanding of The Drupal Way™. The only way to start wrapping your head around how to do things properly with Drupal is to build a site with Drupal. And another site, and another, etc. Then build some modules, and some themes. Build an installation profile or two. Learn drush. Contribute to Drupal core.

Every day, learn something new about Drupal. You'll find that Drupal is a constantly-evolving (and improving!) ecosystem. The best practice today may be slightly different tomorrow—and with Drupal 8 just around the corner, there are many exciting opportunities to learn!

Related Posts from Elsewhere

Discuss this post on Hacker News, Reddit, or below...


Great post! The good news is Drupal is getting MUCH better for Symfony Sally, JQuery John, SASSy Sam, and Twigy Tom which makes it easier for people already have those skills to apply them within Drupal. This will hopefully reduce the amount of naval gazing that goes on in Drupal by diversifying the background of people influencing the direction Drupal takes. The "Drupal Way" has often included a lot of secret handshakes, special sauce, and we-have-always-done-it-this-way. However, the reverse is also true... people who master these technologies in Drupal can more easily transition another framework. My fear is that as Enterprise Earl gets more of what he wants from Drupal, the community may become a less friendly place for Hobbist Harry and FOSS Floyd. It's too soon to tell if the approach taken with D8 will grow or shrink the community, but I have no doubt it is changing it.

I think the most radical changes are coming for the hobbyist crowd who likes to tinker under the hood. For many hobbyist users, though, I think they stay far enough away from Drupal core that they will be able to adapt (with a little help) to the refreshed UI and different file structure pretty quickly.

Time will tell, of course, but I'm not too worried at this point—I don't see any paradigm shifts that will be holding back the major Drupal modules in use today from being upgraded to Drupal 8.

Do you have blue in your blood? Very well explained, as usual.

Until you install some module and the client asks "Oh would you change this text header" and then you find yourself trying to figure out whether the actual text is in a module file somewhere or in one of the 100's of tables. Cant beat opening up a php or language file and just editing the text inline. Or how about that onetime you install a module, label a field as an int but cannot save null. Again, you have to either built the module yourself or go digging for 30 mins to only end up using a crappy hack. Stop doing it the drupal way. Saves time and money.

The main problem here is that it makes updating/upgrading many times harder, because you'll have to start maintaining all these patches you're creating. The overhead/time of doing this over time will eventually be much greater, since you're essentially building (and committing to maintain) a fork of Drupal and each contributed module you hack.

it makes updating/upgrading many times harder

Hacks are just patches waiting to be maintained.

Drush and a .make makes "hacking" a module or even core manageable and is a great solution for people who are drawn to open source because it allows them to change things, but lack the patience to wait for the fix to be committed. Once you get into the habit of building sites from an install profile, it only takes a few minutes more to manage your hacks as a patches that are re-applied to module and core updates.

I just added a fix to media_youtube to cm_starterkit_easy...…

I'll leave that patch in place until it fails to apply. Hopefully that will happen when the patch is committed to the module.

It's really interesting look at the patches developers apply to both modules and core in popular Drupal distributions.

Hacks are just patches waiting to be maintained.

Oh, definitely; that's why I bolded the line below, invest in patches. A good hack is one that fixes a problem or adds new functionality—and is submitted back as a patch to hopefully be included in the module/core someday :)

the problems most people have with Drupal are problems not with Drupal, but with their perception of Drupal.

LOL!! Perception is not reality? So who is right? The people that are for or the people that are against? (This applies to all discussions and concepts in the world btw.) There is only perception. There's no such thing as good or bad software.

(This might be slightly too philosophic for a Drupal tech post.)

(Btw: the Submit and Preview buttons after a comment preview are located somewhat strange...)


LOL over your efforts to apply a trademark to the phrase "the Drupal way". Really? Google returns over 125,000 results on the phrase. My suggestion: Remove the TM symbol.


Great article, Jeff! I spend the majority of my workday using Drupal, so I'm a fan from the start. However, you ask "I know you could build a small system that beats the pants off Drupal performance-wise, and handles the three features you need done now. But why spend hours on a . . . "

I think you answered your own question there, which is that if you are looking for performance, and if most of your work requires something especially custom for a client, it makes more sense to build a small system, especially if you write your code in a way that makes it reusable on other projects.

For some projects, yes; but more often than not, when the second iteration of a project comes up, if I didn't use a CMS like Drupal, I kick myself since I have to basically build from scratch again to get some new features/functionality added.

However, for very small projects or one-off sites, or for very custom applications, there is definitely value in scratch-building (but even then, at least using a well-supported framework is helpful so you don't have to do session handling, encryption, database handling, etc... even if you have a nice little custom library you wrote, who will maintain it or take it over if you die or leave town?).

Errata: "paramgers", and two instances of "its" misspelled as "it's". Otherwise, an excellent article. Thanks for contributing to the community!

That Drupal Way = the right way mantra drives a lot of talent from this community/cult. When I present on Drupal/CiviCRM solutions, I have a slide that shows beer bellies vs. in shape bellies. Drupal fanboys/girls are often guilty of staring at a navel of a beer belly and saying it's beautiful. Someone from another project looks at the same thing and sees it for what it is, stays something, and is driven from community with torches and pitch forks for daring to question the "Drupal Way". This behavior reaches an Animal Farm level of ridiculousness if you've been involved long enough. Some of my favorite Drupal Way = the right way religious wars...

  • We'll never include a WYSIWYG editor
  • CVS is better than Git
  • GPLv2 is only license Drupal will ever use
  • We can only include JQuery in Drupal if they license it as GPLv2. MIT isn't enough.
  • PHPTemplate is a much easier to develop w/ than Smarty's { }
  • We don't need a smaller core. Everyone wants Drupal to be a CMS
  • All modules should come from only
  • Managing a CRM and CMS in the same framework is a good idea
  • Users want to build new sites and migrate content very 3-4 years. No one really wants upgrades that work.

Many people think that the better idea/technologies win these wars, but more often than not the people trying to fix an issue w/ "The Drupal Way" give up and move on to other projects.

There are a lot of great things about the Drupal community, but insisting that what Drupal is currently doing is always right isn't one of them.

At least five of those bullet points are things that have, in fact, changed in the past few years. And other ones probably will in the next couple of years. I think you might be conflating individual opinions with community-wide consensus... since pretty much everything in Drupal happens with community input, there are a lot of voices (some louder than others, some more coherent than others), and it takes time to hear the consensus above the noise.

I don't imply that The Drupal Way is 'the right way' or 'the only way' anywhere in this post—only that it is 'the Drupal way', and that many people don't understand why it is so. These things can change, and implementations of best practices can change, but Drupal's main purpose—being a flexible PHP-based framework for content-driven websites and applications—won't.

Please remove the drupal_get_query_parameters() example. This function has a very clear purpose, and the use-case pointed out here doesn't belong to that. You'd kill your site performance if you'd do what you suggest. Thanks!

While it likely wouldn't kill site performance—and there are many cases where using drupal_get_query_parameters() would be better than accessing things via $_GET—I did remove that example, as it was a little contrived. I put in a note about dynamic menu paths instead, because a lot of times I see non-Drupal devs setting up paths like /page?nodeid=123&memberid=1234 instead of /page/123/1234 (or something else similarly compact/efficient).

As a Ruby Developer who worked with Drupal for nearly 11 years, I feel there is a lot more to this then what you mention. But my main gripe is that while there are *reasons* stuff is done the way it is, this, in no way, makes that way a *good* way.

I feel The Drupal Way is okay: if you compare it with other Hobby-grown 200X-PHP CMSes. But it compares really poorly to what is quickly becoming the standard in webdevlopment. Yes, Even PHP is catching up fast.

I could go into many of the details you mention, but that would make this comment even longer then your post :). So let me highlight a few; And rebut these with actual facts and figures :)

«The DRY principle (Don't Repeat Yourself) applies very strongly to themes and templates—instead of making a bunch of duplicate templates and changing little things in each one, use hook_preprocess_hook() functions in either your theme or custom modules.»

Yet, not much to the rest of Drupal. Nor SOLID, YAGNI and many other principles you mention. running phpcd we can get actual metrics.
Drupal core, 7 scores 1.88%: over one and threequarters of 292914-lines analised are copies. That is not DRY.

Composer, HTTPFul, or Slim, libraries I consider the proof that Proper PHP is possible and exists, score 0.
Wordpress (HEAD), the "opponent" of Drupal scores 0.64% duplicated lines out of 219748 total lines of code.
To make stuff worse, amongst the 20+ old Drupal-projects I have lying around on my disk, the worse I could find scored over 20%. That is partly the fault of the developers, but mostly of the 80+ modules it "needs" to work.

Now, about YAGNI: you start off with Jane, who develops everything "from scratch", and then try to sell the database-horrors as something rather good, because flexible. If anything, all these designs of field-foo-bar, and worse all the "divitis, classes and ids that might come in handy" go directly against YAGNI.
While we are at it: Java (and Ruby, and Rails, and Python and Django) don't require you to build everything from scratch: if anything, they have a library and eco-culture of plugins, libs, pips or gems that offer a miriad of re-usable code. You can build your own secure login, if you *need* (because, for example it needs to connect to 3rd party tools to authenticate!) but in many cases you'd simply implement Devise or some other lib to integrate and implement your authentication. I am certain that you are aware of this; but when you say «... why spend hours on a login form (that probably has security holes), session handling (ditto), password storage (ditto) forms in general (ditto), content CRUD interfaces, a translation system, a theme layer, etc., when you can have that out of the box, and just spend a little time making it look and behave like you want it? The shoulders of giants and all that...» you are spreading FUD. Or at the very least making things a lot more black/white then needed.

In fact, I have done some measurements where I implemented a customised Drupal-login/authentication versus one I built in Rails with Devise. The Devise solution took 2 hours, including styling. The drupal 14 hours, and the styling was still a little off. Point is: yes, you get a login "for free", but it is a "product", rather then a "library": you need a lot of additional effort to get it exactly the way you want it. You often find yourself to be, what I call "fighting against how Drupal wants it". Now, if you can afford (or convince the stakeholders) to go with the stock-Drupal-login you'd need 0 hours, but with Rails you'd still need these 2 hours. In that case Drupal wins! In all others: quite often all its "free stuff" actually slow you down.

I can really advise you to have a go with some of the excellent PHP QA tools by Bergman on Drupal: you'll see that D8 is in some places a great improvement over D7, but that in some areas D5 or earlier score a lot better: Drupal's code has not nessecarily improved (which is perfectly reasonable, seen as that it is far more feature-loaden, nowadays).

And I can advise any Drupal-developer to follow closely what is happening in the area of phar, composer and with libraries like Slim, Httpful, Guzzle, Laravel and such: modern PHP libraries that should act as an enlightning example to how beautiful PHP-applications can be!

Many thanks for this, every bit of it is spot on. Drupal Drupal Drupal!

You should mention the up and coming Reddit subreddit /r/drupal as a place to learn more! - we love the exposure, and we have an AMA (Ask Me Anything) series starting up with some big players.

Hi Jeff,

As the author of the linked post "I hate PHP", I'd like to point out that my reasons for hating PHP are not "mostly because of code they've seen that's from either designers or new programmers with a lot to learn... or they have a lot of baggage from pre-PHP 5 days."

If you read my article, you will see that the things I point out are precisely things that are not from pre-PHP 5 days, nor from designers or new programmers with a lot to learn.

I point out that the community sucks because it's hard to find good code and people in the middle of all the crap, and I point out a few *recent* things or things that are part of the language, that boggle my mind.

I've been working with PHP for over 15 years now (since mid 1997), so I've seen a lot of everything and I think I can safely say that you're either not looking at the whole picture, or you haven't yet realised the hole you're in.

So does this mean you consider the programmers behind PHP "designers or new programmers with a lot to learn"? If you know anything of low-level programming and look at PHP's source code, you might come to the conclusion that yes, maybe they are.


Thanks for the comment/clarification, and please know that I found your article to be very thought-provoking (it was one of the many different posts that inspired this one). I think the internal debate this kind of post generates is very valuable to the community.

I agree that PHP is a language full of warts, and that its baggage has caused it to be inelegant for many purposes. The continuous improvement in the PHP community (very much like the improvement I see in the Drupal community) is what keeps me interested; 5.4+'s OOP, Symfony, Composer, Packagist and Twig are very good components of the modern PHP developer's tool belt.

I actively work on projects in other languages, and know how much nicer (and faster) they can be, but for many things (especially web frontends), PHP and the frameworks built on top of it are very, very helpful and useful for getting a project out the door. I don't hate PHP, but I do hate PHP's inconsistencies. Like I mentioned at the top of the post, I'm a Catholic—in a similar way, I don't hate the Catholic Church, but I do hate how many people in the Church are inconsistent in what they believe, teach and/or do.

Thanks for your reply, Jeff.

I agree that these debates are constructive for the community as a whole. I am the first to admit that my post wasn't very constructive at all, because after so many years of fighting the issues, I guess I just ran of of patience. I do hope that it gets people to think, though, and that something good comes out of it.