According to this answer, you could simply print the page content in the menu page callback rather than returning it.
To get data from Drupal's database and/or produced in PHP, you need a
page callback (in a custom module) that output the data without the
full layout rendering. This is easily doable by printing the content
of the page directly in your page callback instead of returning it.
I guess the Print module implemented the printer-friendly page in this way. The following is the code snippet from the module.
function print_menu() {
$items = array();
$items[PRINT_PATH] = array(
'title' => 'Printer-friendly',
'page callback' => 'print_controller_html',
'access arguments' => array('access print'),
'type' => MENU_CALLBACK,
'file' => 'print.pages.inc',
);
........
}
/**
* Generate an HTML version of the printer-friendly page
*
* @see print_controller()
*/
function print_controller_html() {
$args = func_get_args();
$path = filter_xss(implode('/', $args));
$cid = isset($_GET['comment']) ? (int)$_GET['comment'] : NULL;
// Handle the query
$query = $_GET;
unset($query['q']);
$print = print_controller($path, $query, $cid, PRINT_HTML_FORMAT);
if ($print !== FALSE) {
$node = $print['node'];
$html = theme('print', array('print' => $print, 'type' => PRINT_HTML_FORMAT, 'node' => $node));
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
drupal_send_headers();
print $html;
......
}
According to this, the module uses the custom HTML template print.tpl.php
. It is a HTML-level template. The module then gets the HTML by calling theme('print',...)
and render it directly to the browser using print $html;
.
Here is a general idea for your purpose: mymodule.module
/**
* Implements hook_menu().
*/
function mymodule_menu() {
$items = array();
$items['mylogin'] = array(
'title' => 'Custom Login Page',
'page callback' => 'mymodule_custom_login_page',
'type' => MENU_CALLBACK,
'access callback' => TRUE,
);
return $items;
}
/**
* Implements hook_theme().
*/
function mymodule_theme() {
return array(
'mylogin' => array(
'variables' => array('page' => array()),
'template' => 'mylogin', // mylogin.tpl.php in your module folder
),
);
}
/**
* Generate a custom login page
* @see more in print_controller_html() in print.pages.inc of the Print module
*/
function mymodule_custom_login_page(){
$page = _mymodule_login_page_prerequisite(); // get/prepare necessary variables, js, css for the page
$page['form'] = drupal_render(drupal_get_form('user_login')); // get login form
// prepare html in mylogin.tpl.php
// See more in print.tpl.php() in the Print module
$html = theme('mylogin', array('page' => $page));
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
drupal_send_headers();
print $html; // cease Drupal page rendering and render directly to the browser
}
/**
* Prepare the array for the template with common details
* @see more _print_var_generator() in print.pages.inc of the Print module
*/
function _mymodule_login_page_prerequisite(){
global $base_url, $language;
$page = array();
$page['language'] = $language->language;
$page['head'] = drupal_get_html_head();
$page['title'] = '';
$page['scripts'] = drupal_get_js();
$page['favicon'] = '';
// if there is a custom css file for this page
// drupal_add_css(drupal_get_path('module', 'mymodule') . '/css/mylogin.css');
$page['css'] = drupal_get_css();
$page['message'] = drupal_get_messages();
$page['footer_scripts'] = drupal_get_js('footer');
return $page;
}
Template: mylogin.tpl.php
<?php
/**
* @file
* Custom login page template
*
* @ingroup page
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php print $page['language']; ?>" xml:lang="<?php print $page['language']; ?>">
<head>
<?php print $page['head']; ?>
<title><?php print $page['title']; ?></title>
<?php print $page['scripts']; ?>
<?php print $page['favicon']; ?>
<?php print $page['css']; ?>
</head>
<body>
<h3>This is custom login page.</h3>
<?php
if (!empty($page['message'])):
foreach($page['message'] as $type => $message):
?>
<div class="messages <?php print $type; ?>">
<ul>
<?php foreach($message as $msg): ?>
<li><?php print $msg; ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php
endforeach;
endif; ?>
<div><?php print $page['form']; ?></div>
<?php print $page['footer_scripts']; ?>
</body>
</html>
I hope this will customize your login page as you need.
hook_menu_alter()
to change thedelivery callback
for the user/login path to your own version ofdrupal_deliver_html_page()
. That should give you absolute control over what is rendered to the screen, although it will mean setting appropriate headers yourselfajax_deliver()
function, which gets the same$page_callback_result
asdrupal_html_deliver_page()
but processes it differently. I'm not sure if you can interrupt the process any further down in a meaningful way before the theme engine gets involvedusing_views_api_mode
is OFF.