The result of a menu callback is cached only when the menu callback returns the output; when the menu callback prints the output, it's not cached.
The code execute to bootstrap Drupal when a page is requested is the following:
require_once './includes/bootstrap.inc';
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) {
case MENU_NOT_FOUND:
drupal_not_found();
break;
case MENU_ACCESS_DENIED:
drupal_access_denied();
break;
case MENU_SITE_OFFLINE:
drupal_site_offline();
break;
}
}
elseif (isset($return)) {
// Print any value (including an empty string) except NULL or undefined:
print theme('page', $return);
}
drupal_page_footer();
drupal_page_footer()
is the function that caches the result.
function drupal_page_footer() {
if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED) {
page_set_cache();
}
module_invoke_all('exit');
}
page_set_cache()
is the function that does the real work.
function page_set_cache() {
global $user, $base_root;
if (!$user->uid && $_SERVER['REQUEST_METHOD'] == 'GET' && page_get_cache(TRUE)) {
// This will fail in some cases, see page_get_cache() for the explanation.
if ($data = ob_get_contents()) {
if (variable_get('page_compression', TRUE) && extension_loaded('zlib')) {
$data = gzencode($data, 9, FORCE_GZIP);
}
ob_end_flush();
cache_set($base_root . request_uri(), $data, 'cache_page', CACHE_TEMPORARY, drupal_get_headers());
}
}
}
The content is compressed (if the zlib
is enabled), and saved in the cache.
If you want the cache the output of a custom menu callback, then you just need to return the output, instead of printing it directly.
function mymodule_callback() {
// …
return $output;
}
Instead of caching the output of the page, you can cache the data the module used to build its output. If, in example, the output data is obtained with an SQL query, you can cache the result of the query.