Làm thế nào để nói với Drupal tìm kiếm các mẫu trong thư mục mô-đun?


11

Tôi muốn cung cấp triển khai mẫu trong mô-đun của mình và cho phép các chủ đề ghi đè lên nó. Về cơ bản, tôi thêm một đề xuất bằng mã đơn giản này:

function attach_preprocess_node(&$vars) {
  $vars['theme_hook_suggestions'][] = 'node__test';
}

(Tôi không muốn sử dụng hook_theme để thêm một chủ đề mới bởi vì tôi muốn sử dụng lại chức năng nút preprocess. Tên chủ đề là vụng về nhưng tôi không muốn viết node_ đính kèm _% để tránh nhầm lẫn với loại nút.)

Sau đó, tôi sử dụng hook_theme_registry_alter () để thêm đường dẫn mô-đun:

function attach_theme_registry_alter(&$theme_registry) {
  $path = drupal_get_path('module', 'attach') . '/themes';
  $theme_registry_copy = $theme_registry;
  _theme_process_registry($theme_registry_copy, 'phptemplate', 'theme_engine', 'node', drupal_get_path('module', 'node'));
  $theme_registry += array_diff_key($theme_registry_copy, $theme_registry);
  if (!isset($theme_registry['node']['theme paths'])) {
    $theme_registry['node']['theme paths'] = array();
  }
  if (!isset($theme_registry['node']['theme paths'])) {
    $first_element = array_shift($theme_registry['node']['theme paths']);
    if ($first_element) {
      array_unshift($theme_registry['node']['theme paths'], $first_element, $path);
    }
    else {
      array_unshift($theme_registry['node']['theme paths'], $path);
    }
  }
}

Tuy nhiên, nó không hoạt động. Điều đó có nghĩa là: các chủ đề / nút tệp - super.tpl.php không được sử dụng. Nó chỉ được sử dụng nếu tôi sao chép nó vào thư mục theme.


Làm rõ: Tôi muốn Drupal tìm trong thư mục mô-đun (và cả trong thư mục chủ đề) cho một mẫu được xác định bởi mã (ở đây: mẫu nút). Tôi không muốn xác định một mẫu mới.
jcisio

Câu trả lời:


5

Về cơ bản, bạn có thể tiết kiệm cho mình một chút đau đầu bằng cách thực hiện hook_theme()thay vì thay đổi sổ đăng ký.

Tôi đề nghị xem xét theming_example trong dự án Ví dụ , được sao chép một cách cẩn thận trên trang tài liệu API này , có lẽ với mã đặc biệt hữu ích trên trang này .

function theming_example_list_page() {
  $items = array(
    t('First item'),
    t('Second item'),
    t('Third item'),
    t('Fourth item'),
  );

  // First we'll create a render array that simply uses theme_item_list.
  $title = t("A list returned to be rendered using theme('item_list')");
  $build['render_version'] = array(
    // We use #theme here instead of #theme_wrappers because theme_item_list()
    // is the classic type of theme function that does not just assume a
    // render array, but instead has its own properties (#type, #title, #items).
    '#theme' => 'item_list',
    // '#type' => 'ul',  // The default type is 'ul'
    // We can easily make sure that a css or js file is present using #attached. 
    '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), 
    '#title' => $title, 
    '#items' => $items, 
    '#attributes' => array('class' => array('render-version-list')),
  );

  // Now we'll create a render array which uses our own list formatter,
  // theme('theming_example_list').
  $title = t("The same list rendered by theme('theming_example_list')");
  $build['our_theme_function'] = array(
    '#theme' => 'theming_example_list', 
    '#attached' => array('css' => array(drupal_get_path('module', 'theming_example') . '/theming_example.css')), 
    '#title' => $title, 
    '#items' => $items,
  );
  return $build;
}

Đây là tất cả cho Drupal 7.


Như tôi đã nói trong câu hỏi, tôi không muốn sử dụng hook_theme () vì tôi muốn sử dụng lại các biến $ trong mẫu nút. Các biến đó được tạo trong quy trình hook_ (trước) của nhiều mô-đun không biết sự tồn tại của chủ đề của tôi (nếu tôi xác định một mô-đun).
jcisio

Cách bạn xác định một chủ đề là ... với hook_theme (). :-) Bạn có thể định nghĩa các hàm theo chủ đề trong hook_theme (). Đặt tên cho họ bất cứ điều gì bạn muốn. Thực hiện các chức năng shim nếu bạn muốn. Tài liệu API: "hook_theme_HOOK () ... chỉ nên được sử dụng nếu một mô-đun cần ghi đè hoặc thêm vào tiền xử lý chủ đề cho móc chủ đề mà nó không xác định."
paul-m

Tôi không muốn xác định một chủ đề. Nếu bạn xác định chủ đề 'mynode' thay vì sử dụng lại 'nút', bạn không có bất kỳ biến nào trong tệp .tpl.php của mình.
jcisio

1
Điều này có vẻ không đúng: các cuộc gọi chủ đề được tích lũy, do đó việc triển khai hook_themesẽ cung cấp cho bạn $existingtham số cho phép bạn sửa đổi điều đó, không ghi đè lên nó. Nếu không phải như vậy thì có lẽ bạn đang gặp lỗi.
Countzero

@Countzero khi bạn khai báo một chủ đề node_attach, thì tất cả các hàm hook_pre process_node sẽ không xảy ra với chủ đề mới của bạn. Tức là bạn không có bất cứ điều gì trong nút-Đính kèm của bạn.
jcisio

5

Có lẽ cái này hoạt động:

/**
 * Implements hook_theme().
 */
function MODULE_theme($existing, $type, $theme, $path) {
  return array (
    'node__CONTENTTYPE' => array (
      'variables' => array( . . . ),
      'template' => 'node--CONTENTTYPE' ,
      'base hook' => 'node',
      'path' => drupal_get_path('module', 'MODULE'),
    ),
  );
}

Quan trọng ở đây là chìa khóa ' móc cơ sở '.


Đây là vấn đề để thêm tài liệu cho base hook: drupal.org/node/2106635
Andy

Upvote +1 - điều này và câu trả lời phái sinh từ batigotix tôi tìm thấy để làm việc. Cảm ơn.
trị liệu

2

Tôi thích giải pháp của dashohoxha về việc triển khai hook_theme nhưng không thể làm cho nó hoạt động. Sau một vài lần googling tôi đã tìm thấy một biến thể phù hợp với tôi:

/**
 * Implements hook_theme().
 */
function mymodule_theme($existing, $type, $theme, $path) {
  $theme = array();
  $theme['node__blog_post'] = array(
    'render element' => 'content',
    'base hook' => 'node',
    'template' => 'node--blog_post',
    'path' => drupal_get_path('module', 'mymodule') . '/templates',
   );
  return $theme;
}

Lưu ý: mô-đun tùy chỉnh của tôi được gọi là 'mymodule' và loại nội dung tùy chỉnh của tôi được gọi là 'blog_post'. Tpl.php mà tôi sử dụng được gọi là 'nút - blog_post.tpl.php' và nó nằm trong thư mục con 'mẫu' của mô-đun của tôi.


+1 cảm ơn tôi đã tìm thấy nó để làm việc. Nếu bạn cũng quan tâm đến việc ghi đè các hàm template.php bên trong mô-đun tùy chỉnh của mình, hãy xem: snugug.com/musings/override-theme-fifts-drupal-7-module - Tôi thấy điều này hoạt động rất tốt
nghĩa là

1

Đây là đoạn trích của tôi để khai báo các mẫu chế độ xem được lưu trữ trong thư mục "mẫu" của "custom_module" của tôi:

/**
 * Implements hook_theme_registry_alter().
 */
function custom_module_theme_registry_alter(&$theme_registry) {
  $extension   = '.tpl.php';
  $module_path = drupal_get_path('module', 'custom_module');
  $files       = file_scan_directory($module_path . '/templates', '/' . preg_quote($extension) . '$/');

  foreach ($files as $file) {
    $template = drupal_basename($file->filename, $extension);
    $theme    = str_replace('-', '_', $template);
    list($base_theme, $specific) = explode('__', $theme, 2);

    // Don't override base theme.
    if (!empty($specific) && isset($theme_registry[$base_theme])) {
      $theme_info = array(
        'template'   => $template,
        'path'       => drupal_dirname($file->uri),
        'variables'  => $theme_registry[$base_theme]['variables'],
        'base hook'  => $base_theme,
        // Other available value: theme_engine.
        'type'       => 'module',
        'theme path' => $module_path,
      );

      $theme_registry[$theme] = $theme_info;
    }
  }
}

Hy vọng nó sẽ giúp được ai đó.


-1

Tôi đã hỏi điều này một lần trên Stack Overflow . Về cơ bản, bạn phải triển khai hook_theme_registry_alter()để thêm đường dẫn của mình vào đường dẫn mẫu móc chủ đề; sau đó, hook_enable()bạn gọi drupal_theme_Vbuild () để xóa bộ đệm của sổ đăng ký chủ đề và quét đường dẫn của bạn cho các mẫu.


Có lẽ những gì giữ bạn lại chỉ là xóa bộ nhớ cache.
Capi Etheriel

Vì vậy, về cơ bản cùng một giải pháp. Tôi đã thử "drush cc all" không dưới 50 lần, đã thử nó trên một trang cài đặt mới, v.v. nhưng không thành công. Tôi sẽ sửa đổi và nén mã của mình thành một mô-đun tối thiểu để mọi người có thể kiểm tra.
jcisio

hook_enable()được gọi khi một mô-đun được kích hoạt; nếu mô-đun đã được kích hoạt, nó phải được tắt và sau đó kích hoạt lại.
kiamlaluno

@kiamlaluno: i sử dụng hook_enable để xóa bộ nhớ cache, nếu nó đã được cài đặt thì người dùng có thể chỉ cần xóa bộ nhớ cache theo cách thủ công.
Capi Etheriel

KHÔNG , -1 điểm. Giải pháp đó quá cũ (2009), tôi thậm chí không chắc nó có ý nghĩa với D7. Mặc dù giải pháp cũ của bạn được tùy chỉnh cho Chế độ xem, nhưng nó không lý tưởng cho các tình huống không xem, trong đó các nhà phát triển có thể muốn đóng gói nhiều hơn 1 mẫu mặc định cho mỗi khóa chủ đề trong các mô-đun của họ. Hãy tưởng tượng thực hiện giải pháp của bạn cho 100 đề xuất chủ đề động cho một khóa chủ đề duy nhất. Áp dụng bên ngoài bối cảnh Lượt xem Tôi sẽ gọi giải pháp của bạn là mô hình đối lập.
barista nghiệp dư
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.