6

Assuming the minimal module install (to keep things simple), what are the core "responsibilities" of the two top level functions in Drupal's index.php?

drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
menu_execute_active_handler();

I'm trying to understand, from a high level, how Drupal's core systems work, particularly in relationship to web based MVC. So in a Code Igniter like system, the following

  1. Examine the URL, turns it into a class and action

  2. Calls the action method on the class, where information is loaded from models, "businessy logic" is done

  3. Information is handed off to a view layer

  4. Layout system renders HTML page

  5. Part of the layout (often a "content area") is driven by the information handed off in step 3

What's the equivalent dispatch process in Drupal? I understand how the module system works, but I don't quite follow Drupal's philosophy on the how/why of data loading and theme/layout rendering, and where the handoff between the two happens.

I realize Drupal is radically different from web app MVC system; I'm trying to understand how. I realize Drupal is designe to be successfully used without fully understanding this. Preference given to Drupal 7 answers, but if there's been radical changes information from previous versions is welcome.

apaderno
  • 28,547
  • 16
  • 75
  • 90
Alana Storm
  • 164,128
  • 91
  • 395
  • 599
  • Drupal isn't MVC, period. Tryihng to think of it in a pattern that is totally *is not* isn't going to help you understand it. It's such a complex system that this is sort of a fruitless task. The whole point of Drupal is that you don't have to care about this stuff. Modules / themeing code only have to deal with the bits they need to work with directly, – Tyler Eaves Feb 15 '11 at 16:22
  • 1
    @tyler I tried to make it clear from my question that I'm well aware of that. I understand there's no direct comparison. However, at the end of the day Drupal needs to do all the things an MVC system does. That is, based on a URL, it loads certain information from a database/data-store, and then a layout is rendered. It's **because** Drupal is so different that I'm asking the question. How do Drupal's systems interact to make that happen. – Alana Storm Feb 15 '11 at 16:27

3 Answers3

14

Good answers from Berdir and Apemantus already (+1), but some room for an additional try:

Concerning Drupals relationship to MVC, I took a stab at the topic with this answer to a question for 'A metaphor for Drupal module's inner workings', which might fit with your request for a 'high level' overview.

As for the top level function calls - well, some things just come in threes, so I would suggest taking the theme('page, $return) call into the mix, as this will complete the overview:

drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
$return = menu_execute_active_handler();

// Menu status constants are integers; page content is a string.
if (is_int($return)) {
  switch ($return) {
    // [...] Snipped error page handling code
  }
}
elseif (isset($return)) {
  // Print any value (including an empty string) except NULL or undefined:
  print theme('page', $return);
}
drupal_page_footer();

One by one:

  1. drupal_bootstrap()
    As the name suggests, this is mainly concerned with 'setting the stage', that is e.g.

    • Initialize basic configuration
    • Initialize database access
    • Initialize session handling
    • Identify the requesting user
    • Eventually shortcut the request by serving cached content
    • ... (more stuff)

    An important point here is that already during this phase, the hook system will invoke other modules, if they ask for it, giving them a chance to inject custom logic in this early phase. While it is not common for modules to do this, it adds to the flexibility of Drupal that it can be done for special needs like e.g. influencing the user identification process, preventing or enforcing a cache hit, rewriting the requested path and other 'low level' manipulations.

  2. menu_execute_active_handler()
    This roughly matches steps 1. and 2. from your CodeIgniter sketch. It will inspect the requested path, match it to the proper callback function (including some 'turn wildcards into parameters' logic), and invoke that callback, passing the extracted (or predefined) parameters. The callback is usually expected to return the main page content, but is free to do other stuff like e.g. just redirecting the request. Most "businessy logic" will be done here, but note that the returned content is quite often already a Markup Fragment, so this phase includes some parts of the view layer already!

  3. theme_page() (Indirectly invoked via the theme() function, which adds a lot of surrounding 'magic')
    This (very) roughly matches the usual view layer, as this is where the final assembly of the markup to be returned takes place. But it is also the place where the 'surrounding' elements of a page get assembled (think menus, headers, sidebars, etc.) so there is still a lot of potential for "businessy logic" going on during this stage as well.

During all these steps, the hook system (along with the similarly designed theme system), will provide quite a number of 'hook in' points for other modules to 'subscribe' to, if they need to. When invoked, they will get passed the relevant information being processed at that point, with the option to step in and manipulate it (or just trigger some separate processing). All this adds up to a quite flexible system (because of the huge amount of 'intercept and manipulate' options for custom modules), but is also responsible for a lot of the difficulties in learning Drupal, as the question of 'what happens when' is often not easily answered :/

So to sum it up shortly:

  1. bootstrapping - Initialization grunt work, eventually enriched with early intrusions of 'business logic'.
  2. execution - Main 'business logic' processing, already with some 'view' generation logic (assembly of Markup fragments).
  3. theming - Main Markup generation, with some significant portions of 'business logic' still in the mix.
Community
  • 1
  • 1
Henrik Opel
  • 19,341
  • 1
  • 48
  • 64
  • 1
    Great summary, note that in D7, the third step has been integrated into the second and is also a configurable, see http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_deliver_page/7 and http://api.drupal.org/api/drupal/includes--common.inc/function/drupal_deliver_html_page/7 – Berdir Feb 15 '11 at 23:29
  • @Berdir - Thanks for the hint/correction. Haven't had much time to get into detail with D7 so far, as I'm still involved with a major D6 project, but looking forward to switching sooner or later :) – Henrik Opel Feb 15 '11 at 23:42
3

Have a look at http://drupaldepth.blogspot.com/2009/07/flow-of-drupal.html

Apemantus
  • 683
  • 6
  • 20
  • A very useful article, but it was written in 2009 (drupal 6 i assume). Are there any changes in this flow for drupal 7? – jan Mar 14 '14 at 08:27
3

After the bootstrap, the only given thing that happens is the menu router system, which figures out which page callback is responsible for this request. To do that, it relies on the information that all the installed modules returned in their hook_menu() definition (this is stored in the database and only updated when explicitly requested to do so, when new modules are enabled for example).

That hook can control a lot. For example access permissions, defining arguments, title of the menu links and so on. Also, menu routers can be almost as complex as you want, they are not limited to the usual controller/action patterns. I think you can define menu router items up to 9 elements deep, for example 'yourmodule/view/%/sub/%/%/whatever'.

See http://drupal.org/node/109131 for a short overview with an example.

Inside that page callback, the providing module is free to do whatever it wants. It can use the theme system if it wants to, fire hooks or do anything else with the "content" portion of a page. The theme system will include all other portions of a themed page including other regions and other blocks that are included in those regions automatically. This is important to remember when creating callbacks that respond to AJAX request or provide things like xml feeds etc. In those cases you would need to take further steps to make adjustments in the theme to accommodate requests that shouldn't include the "rest" of the page.

mirzu
  • 1,831
  • 2
  • 13
  • 15
Berdir
  • 6,881
  • 2
  • 26
  • 38
  • 1
    Got it. So the menu system isn't so much about rending links on the page, but it's actually the router that determines what URLs do what in the system? – Alana Storm Feb 15 '11 at 17:52
  • 3
    Actually, it's currently pretty much tied to together. Defining menu router items will by default also control the corresponding menu links. So it is kinda responsible for both. This will maybe be decoupled in D8. On top of the menu *system* (includes/menu.inc) is the optional menu.module, which provides (among a few other things) the administrative user interface to create/maintain menus and menu links. But the logic is (mostly) in menu.inc. – Berdir Feb 15 '11 at 17:57