You may say that Drupal does not follow the MVC way. In my opinion, Drupal have the implicit MVC pattern like these:
- Model: database layer and entity module;
- Controller: menu system;
- View: Drupal render and theme system.
What i want to talk is view layer. Let us still begin the journey with menu_execute_active_handler() in index.php. This function maps the request path with menu and call the function "page callback " defined in the menu array. Usually, the page callback function returns the array data with theme entry. In the following steps, Drupal use drupal_deliver_page and drupal_deliver_html_page to render the theme array-type data.
print drupal_render_page($page_callback_result);
Behind this code statement's scene, drupal use render and theme to supply the look and feel.
- Render system: drupal_render_page() and drupal_render
- Theme system: theme functions or template files
Drupal render methods help to add the page element and invoke the theme to display html markup.
function drupal_render_page($page) {
$main_content_display = &drupal_static('system_main_content_added', FALSE);
// Allow menu callbacks to return strings or arbitrary arrays to render.
// If the array returned is not of #type page directly, we need to fill
// in the page with defaults.
if (is_string($page) || (is_array($page) && (!isset($page['#type']) || ($page['#type'] != 'page')))) {
drupal_set_page_content($page);
$page = element_info('page');
}
// Modules can add elements to $page as needed in hook_page_build().
foreach (module_implements('page_build') as $module) {
$function = $module . '_page_build';
$function($page);
}
// Modules alter the $page as needed. Blocks are populated into regions like
// 'sidebar_first', 'footer', etc.
drupal_alter('page', $page);
// If no module has taken care of the main content, add it to the page now.
// This allows the site to still be usable even if no modules that
// control page regions (for example, the Block module) are enabled.
if (!$main_content_display) {
$page['content']['system_main'] = drupal_set_page_content();
}
return drupal_render($page);
}
In the drupal_render, you can add pre_render, wrapper and post_render to decorate your content, but the core is theme element.
if (isset($elements['#theme'])) {
$elements['#children'] = theme($elements['#theme'], $elements);
}
Drupal theme can render the html content by theme function.
$output = '';
if (isset($info['function'])) {
if (function_exists($info['function'])) {
$output = $info['function']($variables);
}
}
else {
// Default render function and extension.
$render_function = 'theme_render_template';
$extension = '.tpl.php';
}
Function theme_render_template follow the PHP internal way to render file.
function theme_render_template($template_file, $variables) {
extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
ob_start(); // Start output buffering
include DRUPAL_ROOT . '/' . $template_file; // Include the template file
return ob_get_clean(); // End buffering and return its contents
}
In Summary, this is Drupal default workflow, you can alter them by hooking your extension points.