Understanding the directory structure of a default Drupal installation will help you debug your site and teach you several important best practices, such as where downloaded modules and themes should reside and how to have different Drupal profiles. A default Drupal installation has the structure shown in Figure 1-4.
Figure 1-4. The default folder structure of a Drupal installation.
Details about each element in the folder structure follow:
The files folder doesn't ship with Drupal by default, but it is needed if you plan on using a custom logo, enabling user avatars, or uploading other media associated with your new site. This subdirectory requires read and write permissions by the Web server that Drupal is running behind.
The modules folder contains the core modules, with each module in its own folder. It is best not to touch anything in this folder (you add extra modules in the sites directory).
The profiles folder contains different installation profiles for a site. If there are other profiles besides the default profile in this subdirectory, Drupal will ask you which profile you want to install when first installing your Drupal site. The main purpose of an installation profile is to enable certain core and contributed modules automatically. An example would be an e-commerce profile that automatically sets up Drupal as an e-commerce platform. The scripts folder contains scripts for checking syntax, cleaning up code, and handling special cases with cron. It is not used within the Drupal request life cycle; these are shell and Perl utility scripts.
The sites directory (see Figure 1-5) contains your modifications to Drupal in the form of settings, modules, and themes. When you add modules to Drupal from the contributed modules repository or by writing your own, they go into sites/all/modules. This keeps all your Drupal modifications within a single folder. Inside the sites directory will be a subdirectory named default that holds the default configuration file for your Drupal site -- settings.php. The default directory is typically copied and renamed to the URL of your site, so your settings file would be at
sites/www.example.com/settings.php. The themes folder contains the template engines and default themes for Drupal.
Figure 1-5. The sites folder can store all your Drupal modifications.
Serving a Request
Having a conceptual framework of what happens when a request is received by Drupal is helpful, so this section provides a quick walk-through. If you want to trace it yourself, use a good debugger, and start at index.php, which is where Drupal receives most of its requests. The sequence outlined in this section may seem complex for displaying a simple Web page, but it is rife with flexibility.
The Web Server's Role
Drupal runs behind a Web server, typically Apache. If the Web server respects Drupal's .htaccess file, some PHP settings are initialized, and clean URLs are enabled. (Drupal supports clean URLs, that is, URLs that look like "http://example.com/foo/bar." A
mod_rewrite rule in Drupal's .htaccess file translates the path to index.php?q=foo/bar. So internally, Drupal always deals with the same path, stored in the URL query parameter
q, whether clean URLs are enabled or not. In this case, the internal path would be foo/bar. The internal path is also called the "Drupal path".) In alternate Web servers, such as Microsoft IIS, clean URLs can be achieved using a Windows Internet Server Application Programming Interface (ISAPI) module such as
The Bootstrap Process
Drupal bootstraps itself on every request by going through a series of bootstrap phases.
This phase populates Drupal's internal configuration array and establishes the base URL (
$base_url) of the site. The settings.php file is parsed via
include_once(), and any variable overriding established there is applied.
Early Page Cache
In situations requiring a high level of scalability, a caching system may need to be invoked before a database connection is even attempted. The early page cache phase lets you include
include()) a PHP file containing a function called
page_cache_fastpath(), which takes over and returns content to the browser. The early page cache is enabled by setting the
page_cache_fastpath variable to TRUE, and the file to be included is defined by setting the
cache_inc variable to the file's path.
During the database phase, the type of database is determined, and an initial connection is made that will be used for database queries.
Drupal allows the banning of hosts on a per-hostname/IP address basis. In the access phase, a quick check is made to see if the request is coming from a banned host; if so, access is denied.
Drupal takes advantage of PHP's built-in session handling but overrides some of the handlers with its own to implement database-backed session handling. Sessions are initialized or reestablished in the session phase.
Late Page Cache
In the late page cache phase, Drupal loads enough supporting code to determine whether or not to serve a page from the page cache. This includes merging settings from the database into the array that was created during the configuration phase and loading or parsing module code. If the session indicates that the request was issued by an anonymous user and page caching is enabled, the page is returned from the cache and execution stops.
At the path phase, code that handles paths and path aliasing is loaded. This phase enables human-readable URLs to be resolved and handles internal Drupal path caching and lookups.
This phase completes the bootstrap process by loading a library of common functions, theme support, and support for callback mapping, file handling, Unicode, PHP image toolkits, form creation and processing, automatically sortable tables, and result set paging. Drupal's custom error handler is set, the locale is set, and all enabled modules are loaded. Finally, Drupal fires the init hook, so that modules have an opportunity to be notified before official processing of the request begins.
Once Drupal has completed bootstrapping, all components of the framework are available. It is time to take the browser's request and hand it off to the PHP function that will handle it. The mapping between URLs and functions that handle them is accomplished using a callback registry that takes care of both URL mapping and access control. Modules register their callbacks using the menu hook. When Drupal has determined that there exists a callback to which the URL of the browser request is mapped and that the user has permission to access that callback, control is handed to the callback function.
Processing a Request
The callback function does whatever work is required to process and accumulate data needed to fulfill the request. For example, if a request for content such as "http://example.com/q=node/3" is received, the URL is mapped to the function
node_page_view() in node.module. Further processing will retrieve the data for that node from the database and put it into a data structure. Then, it's time for theming.
Theming the Data
Theming involves transforming the data that has been retrieved, manipulated, or created into HTML. Drupal will use the theme the administrator has selected to give the Web page the correct look and feel and hands over the resulting HTML to the Web browser.
John VanDyk has been a Drupal developer since 2004 and has contributed several modules to Drupal, including the actions, workflow, publish, subscribe, and pubcookie modules. Matt Westgate is a core developer of the Drupal project and original author of the e-commerce package for Drupal. This article was excerpted from their book Pro Drupal Development. Copyright (c) 2007 Apress. All rights reserved.