Phát hành ghi đè html.tpl.php từ một mô-đun?


8

Có cách nào để ghi đè đầu ra của trang từ mô-đun đã đóng góp và phát hành html.tpl.php của riêng bạn, kiểm soát hiệu quả đầu ra từ chủ đề không?

Tôi muốn làm điều này trong nỗ lực tạo ra trải nghiệm đăng nhập / đăng ký duy nhất, nhưng dường như chỉ có thể ghi đè lên mẫu cấp độ trang chứ không phải mẫu cấp độ html. Tôi thấy rằng loại mô-đun in làm điều này, nhưng đó có phải là cách để tiếp cận nó?


Tôi không có thời gian để bổ sung ngay bây giờ, nhưng tôi nghĩ bạn có thể sử dụng hook_menu_alter()để thay đổi đường dẫn delivery callbackcho người dùng / đăng nhập thành phiên bản của riêng bạn drupal_deliver_html_page(). Điều đó sẽ cung cấp cho bạn quyền kiểm soát tuyệt đối đối với những gì được hiển thị trên màn hình, mặc dù điều đó có nghĩa là tự mình thiết lập các tiêu đề phù hợp
Clive

Vâng, đó là nơi tôi bắt đầu hướng tới, nhưng không chắc bạn có cần phải làm tất cả những việc đó không.
Kevin

Tôi không chắc chắn có một cách tròn nó phải trung thực, một ví dụ điển hình từ lõi là ajax_deliver()chức năng, mà được cùng $page_callback_resultnhư drupal_html_deliver_page()nhưng quá trình nó khác nhau. Tôi không chắc liệu bạn có thể làm gián đoạn quá trình xuống một cách có ý nghĩa trước khi công cụ chủ đề được tham gia hay không
Clive

Có bất kỳ lý do cụ thể để thay đổi đầu ra của html.tpl.php không? Có nhiều chức năng thay đổi những gì tập tin mẫu đầu ra.
kiamlaluno

@kiamlaluno, Đây là một câu hỏi thú vị. Tôi cũng đang tìm cách ngừng kết xuất trang Drupal trước khi công cụ chủ đề được tham gia. Mục đích là để hiển thị một trang (một loại dịch vụ web) giống như đầu ra JSON hoặc bất cứ thứ gì được cung cấp bởi Views Datasource khi using_views_api_modeTẮT.
Sithu

Câu trả lời:


4

Theo câu trả lời này , bạn chỉ có thể in nội dung trang trong hàm gọi lại trang menu thay vì trả lại.

Để lấy dữ liệu từ cơ sở dữ liệu của Drupal và / hoặc được sản xuất bằng PHP, bạn cần có một cuộc gọi lại trang (trong một mô-đun tùy chỉnh) để xuất dữ liệu mà không cần hiển thị bố cục đầy đủ. Điều này có thể dễ dàng thực hiện bằng cách in trực tiếp nội dung của trang trong cuộc gọi lại trang của bạn thay vì trả lại.

Tôi đoán mô-đun In đã triển khai trang thân thiện với máy in theo cách này. Sau đây là đoạn mã từ mô-đun.

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;
    ......
}

Theo đó, mô-đun sử dụng mẫu HTML tùy chỉnh print.tpl.php. Nó là một mẫu mức HTML. Sau đó, mô-đun nhận được HTML bằng cách gọi theme('print',...)và kết xuất trực tiếp tới trình duyệt bằng cách sử dụng print $html;.

Đây là một ý tưởng chung cho mục đích của bạn: 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;
} 

Bản mẫu: 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>

Tôi hy vọng điều này sẽ tùy chỉnh trang đăng nhập của bạn khi bạn cần.


2

Cả @Sithu@Ayesh K đều cung cấp câu trả lời tuyệt vời. Trong ví dụ này, tôi sẽ kết hợp phương pháp của @ Ayesh và các phần của mã @ Sithu để có một giải pháp hoàn chỉnh.

Các hàm hook_menu hoặc hook_menu_alter đều cung cấp a delivery callback, hướng dẫn Drupal về cách bạn muốn mã của bạn được bọc. Theo mặc định, Drupal đặt delivery callbackthành drupal_deliver_html_page () , điều này đại khái cho Drupal bao bọc trang của bạn html.tpl.phppage.tpl.php.

Để sửa đổi cách Drupal kết thúc trang của bạn, sao chép chức năng drupal_deliver_html_page()vào mô-đun của bạn và sửa đổi nó. Sau đó gọi chức năng mới của bạn trong delivery callback. Drupal sau đó sẽ sử dụng chức năng đó để bọc trang của bạn.

Thí dụ

Đây là một mô-đun làm việc. Đặt mã sau vào /sites/all/modules/MYMODULEthư mục của bạn và kích hoạt mô-đun.

Tùy chọn, để ghi đè một đường dẫn hiện có, thay thế hook_menubằng hook_menu_alter.

MYMODULE.module

<?php
function MYMODULE_menu() {
  $items['login'] = array(
    'title' => 'Login',
    'page callback' => 'MYMODULE_page',
    'delivery callback' => 'MYMODULE_deliver',
    'access callback' => TRUE,
  );
  return $items;
}

function MYMODULE_page() {
  global $user;
  if (!$user->uid) return drupal_get_form('user_login'); // Show login for guests.
  else drupal_goto('user/' . $user->uid); // Redirect members to own profile.
}

// Code taken from drupal_deliver_html_page().
function MYMODULE_deliver($page_callback_result) {
  global $language, $base_path;
  // Pass variables to the template.
  $vars = array(
    'language' => $language->language,
    'title' => 'My Custom Login',
    'favicon' => '',
    'css' => $base_path . drupal_get_path('module', 'MYMODULE') . '/MYMODULE.css',
    'messages' => theme_status_messages(array('display' => NULL)),
    'content' => drupal_render($page_callback_result),
  );
  echo theme('MYMODULE_login', array('vars' => $vars)); // Uses template defined in hook_theme().
  drupal_page_footer();
}

function MYMODULE_theme() {
  $items['MYMODULE_login'] = array(
    'template' => 'MYMODULE',
    'render element' => 'page',
  );
  return $items;
}

MYMODULE.info

name = MYMODULE
description = "Module description."
package = Custom
core = 7.x

MYMODULE.tpl.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $vars['language']; ?>" version="XHTML+RDFa 1.0">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title><?php print $vars['title']; ?></title>
  <?php print $vars['favicon']; ?>
  <link rel="stylesheet" type="text/css" href="<?php print $vars['css']; ?>">
</head>
<body>
  <?php echo $vars['messages']; ?>
  <div class="content">
    <?php print $vars['content']; ?>
  </div>
</body>
</html>

MYMODULE.css

.content { color: pink; }

Câu hỏi: ví dụ này có hoạt động với hệ thống bộ đệm của Drupal không và nó có bộ đệm riêng cho các chuỗi truy vấn khác nhau không?
Darvanen

Tôi tin rằng, theo mặc định, Drupal lưu trữ mẫu và trang tương ứng. Tôi không chắc chắn về bất kỳ quá trình bộ nhớ đệm khác.
timofey.com 2/11/2015

Cảm ơn. Tôi đã kết thúc việc tạo một bộ đệm tùy chỉnh cho các phản hồi trên trang của mình bằng API.
Darvanen

1

Tôi nghĩ rằng bạn cần đầu tư một chút thời gian để tìm ra cái móc thích hợp nhất cho việc này. Bạn co thể thử

  • hook_page_alter để thay đổi "những gì sẽ được hiển thị",

  • sử dụng hook_menu_alter để thay đổi cuộc gọi lại phân phối cho các bộ định tuyến menu đăng nhập và đăng ký,

  • sử dụng một trang - tệp user-login.tpl.php để tiếp quản mẫu trang của trang đăng nhập,

  • thêm một số đề xuất mẫu trong template.php để sử dụng tệp html.tpl.php khác chỉ cho các đường dẫn đăng nhập,

  • hoặc cuối cùng, hook_theme_regitry_alter , để thay đổi sổ đăng ký chủ đề và làm những gì bạn muốn làm (thay đổi html.tpl.php)


+1 Điểm trên! hook_theme_registry_alter()có thể không hoạt động vì rất có thể nó sẽ thay đổi mẫu cho tất cả các trang, nhưng delivery callbackchắc chắn sẽ hoạt động. Tôi cũng đã khám phá phương pháp này trong câu trả lời của tôi ở đây.
timofey.com
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.