Friday, August 13, 2010

How Drupal works?

Drupal can be confusing on this front, partially because it has a relatively deep function stack. Although it's procedural PHP it's purely event/listener driven in its architecture, and there's no simple "flow" in the main PHP script for you to look though. I recently did a presentation on this very subject, and the slides are posted on slideshare, but a quick high-level summary may be useful.

  • Drupal's index.php file functions as a frontside controller. All page are piped through it, and the "actual" url/path the user requested is passed to index.php as a parameter.
  • Drupal's path router system (MenuAPI) is used to match the requested path to a given plugin module. That plugin module is responsible for building the "primary content" of the page.
  • Once the primary page content is built, index.php calls theme('page', $content), which hands off the content to Drupal's theming/skinning system. There, it's wrapped in sidebars/headers/widgets/etc..
  • The rendered page is then handed back to apache and it gets sent back to the user's browser.
During that entire process, Drupal and third-party plugin modules are firing off events, and listening for them to respond. Drupal calls this the 'hook' system, and it's implemented using function naming conventions. The 'blog' module, for example, can intercept 'user' related by implementing a function named blog_user(). In Drupal parlance, that's called hook_user().

It's a bit clunky, but due to a PHP quirk (it keeps an internal hashtable of all loaded functions), it allows Drupal to quickly check for listeners just by iterating over a list of installed plugins. For each plugin it can call function_exists() on the appropriately named pattern, and call the function if it exists. ("I'm firing the 'login' event. Does 'mymodule_login' function exist? I'll call it. Does 'yourmodule_login' exist? No? How about 'nextmodule_login'?" etc.) Again, a touch clunky but it works pretty well.

Everything that happens in Drupal happens because of one of those events being fired. The MenuAPI only knows about what urls/paths are handled by different plugin modules because it fires the 'menu' event (hook_menu) and gathers up all the metadata plugin modules respond with. ("I'll take care of the url 'news/recent', and here's the function to call when that page needs to be built...") Content only gets saved because Drupal's FormAPI is responsible for building a page, and fires the 'a form was submitted' event for a module to respond to. Hourly maintenance happens because hook_cron() is triggered, and any module with mymodulename_cron() as a function name will have its function called.

Everything else is ultimately just details -- important details, but variations on that theme. index.php is the controller, the menu system determins what the "current page" is, and lots of events get fired in the process of building that page. Plugin modules can hook into those events and change the workflow/supply additional information/etc. That's also part of the reason so many Drupal resources focus on making modules. Without modules, Drupal doesn't actually DO anything other than say, 'Someone asked for a page! Does it exist? No? OK, I'll serve up a 404.'


FWIW, it's a bit different in D7 (theme('page') is gone and the symbols are now cached in the code registry), but the overall process remains the same. – FGM Jul 2 '09 at 7:42

Great explanation Eaton, Thanks for hanging out here. My question for you is, how do you debug all this, other than putting var_dump in each module to find out what happened? – Brian G Jul 3 '09 at 14:16

Good question. It depends on what you're debugging. Installing the devel module can help by giving you some useful tools. The step (in most cases) is identifying what module is responsible for building a given page. hook_menu() maps urls/paths to modules, so that can help. Then identifying what its menu callback is doing -- calling drupal_get_form() to build a form, or theme('some_custom_thing') to build HTML, etc. watch for use of functions like drupal_alter() or module_invoke_all() that trigger events for other modules, too... – Eaton Jul 3 '09 at 15:43

I found this super helpful. Do you know how Drupal 7 differs? – Hortitude Nov 18 '09 at 4:26

D7 Update: (see also) – dreftymac Feb 12 at 16:40

Look at Chapter 1 "How Drupal Works" of the Pro Drupal Development Book ( 2nd edition) - Joe Jul 1 '09 at 12:40

Read the handbooks, especially the theme developer's guide. Drupal supports several theme engines. Zen uses phptemplate, so pay attention to that portion of the guide.

For module development, the API is documented at

specially when you need to get the info fast and fast

Eaton's answer provides a good overview. (I'm new here so I can't mod him up, thus the comment.)

The brutal "aha" moment for me was realizing everything happens through index.php, and then through the waterfall of modules (core first, then by site). To extend core functionality don't rewrite it. Instead copy the module into /sites/all/modules/ or /sites/[yoursite]/modules and extend THAT, or create a new module in those places. Same for themes. Module directories can contain display code as well, in the form of tpl, css etc.

If you're used to stricter MVC type frameworks like Rails, Django etc. all this gets a little confusing. Modules can mix in a lot of display code, and if you're looking at someone else's modules or templates you'll eventually wind up walking backwards through the stack. That's the beauty/pain of working in PHP.

Ironically, "just build an app" might be the worst way to learn this. Drupal does so much out of the box that's simply obscure until you figure out the control flow. There's nothing in a tpl file that tells you where a function with a fun name like l() comes from, for example. - Jul 1 '09 at 17:18 Paul Souders

The best books on the subject are "Pro Drupal Development" and "Using Drupal."

"Pro Drupal Development" includes several nice flowcharts and thorough summaries of each of Drupal's APIs (forms, theming, etc.). It's intended to be especially instructive to people making their own modules and themes, but has lots of value to the average PHP-savvy developer who wants to understand Drupal. Besides which, I've created a custom module for every site I've built, just to gain the extra control over things like selectively hiding fields on various forms (which you generally want to do for the sake of simplifying node forms for end-users), so it's good to have this knowledge under your hat.

"Using Drupal" is aimed at the site developer who wants to know how to build the good stuff like galleries, blogs, and social networking sites. It goes through several use-cases and shows how to configure existing modules to do each job. In the process it familiarizes you with the essential add-on modules "Content Construction Kit" (CCK) and "Views," how to make custom blocks and templates, and the ins-and-outs of maintaining a Drupal site. I recommend this book especially for those who want to get up to speed and actually USE Drupal right away. In the process you gain an understanding of the internal organization of Drupal. - Jul 8 '09 at 2:06
Scott Lahteine

I learned loads by importing the drupal .php code into a NetBeans project. You can then run the netbeans debugger and watch the different phases of the page come together. - Jul 1 '09 at 11:39 Ben Hammond

This is a pretty good architectural overview of drupal. If you want more detail then I would start writing something most of the documentation is good. Trying to learn it at a high level of detail without something concrete to achieve will be much more difficult that trying something out. - Jul 1 '09 at 14:30 Jeremy French

It depends on how deep an understanding you're looking for; if you have a good knowledge of php, I would suggest reading through the code itself, starting with index.php, and then going on to the includes/, and then some of the other scripts in that directory.

The key include files:

  • is very important to understanding how the overall system works, as it handles a lot of the implicit mapping of URLs to content.
  • has most of the otherwise-mysterious functions that form the basis of the API.
  • handles the hook invocations that Eaton mentioned
  • deals with form display, submission and processing
  • handles presentation.
There's also some key functionality in the modules/ directory; in particular, modules/node/node.module forms the basis of the node system, which is in general what's used to encapsulate site content.

The code is, in general, very well-commented and clear. The use of Doxygen markup within the commenting means that the code effectively is the canonical documentation.

It also helps to do this using an editor that can quickly jump to the definition of a function. Using vim in combination with ctags works for me; you do have to tell ctags to index .inc, .module, etc. files as php files. - Mar 21 at 0:12 intuited


No comments: