簡體   English   中英

hook_theme()如何工作?

[英]How does hook_theme() work?

我很難理解hook_theme()的作用。

我的理解是它與可以覆蓋模板有關。

我在看:

  $theme_hooks = array(
    'poll_vote' => array(
      'template' => 'poll-vote',
      'render element' => 'form',
    ),
    'poll_choices' => array(
      'render element' => 'form',
    ),
    'poll_results' => array(
      'template' => 'poll-results',
      'variables' => array('raw_title' => NULL, 'results' => NULL, 'votes' => NULL, 'raw_links' => NULL, 'block' => NULL, 'nid' => NULL, 'vote' => NULL),
    ),
    'poll_bar' => array(
      'template' => 'poll-bar',
      'variables' => array('title' => NULL, 'votes' => NULL, 'total_votes' => NULL, 'vote' => NULL, 'block' => NULL),
    ),
  );

你能提供一個如何運作的例子嗎?

它為模塊提供了一個定義主題的位置,然后可以被任何其他模塊/主題覆蓋。 它還將為任何模塊提供使用諸如mymodule_preprocess_theme_name的鈎子來更改傳遞給最終主題函數或模板文件的變量的機會。

初始化主題函數基本上有兩種方法:

theme('poll_results', array('raw_title' => 'title', 'results' => $results, etc...));

$build = array(
  '#theme' => 'poll_results',
  '#raw_title' => 'title',
  '#results' => $results,
  etc...
); // Note the '#' at the beginning of the argument name, this tells Drupal's `render` function that this is an argument, not a child element that needs to be rendered.

$content = render($build); // Exact equivalent of calling the previous example now that you have a render array.

請記住,你應該避免直接調用theme()(根據theme.inc中的文檔),因為它:

  • 繞過緩存。
  • 繞過hook_element_info()中定義的類型的默認值,包括附加資產
  • 繞過pre_render和post_render階段。
  • Circumvents JavaScript陳述信息。

在Drupal 8中,theme()是一個私有函數_theme()。 有關更多詳細信息,請訪問www.drupal.org/node/2173655

當你將上述兩個例子中的poll_results元素與上面給出的例子中的poll_results元素進行比較時,你可能會發現正在發生的事情...因為PHP不是強類型語言,Drupal通過傳遞給它的鍵控數組提供'命名參數'。 theme函數,或渲染數組中的散列鍵。

就“渲染元素”而言,這基本上告訴主題系統將使用渲染數組調用此主題函數,該數組具有一個命名參數(在本例中為form )。 代碼看起來像這樣:

$build = array(
  '#theme' => 'poll_choices',
  '#form' => $form
);

這會將$form變量中的任何內容傳遞給主題函數,因為它是唯一的參數。

關於template鍵:

'poll_vote' => array(
  'template' => 'poll-vote',
  'render element' => 'form',
)

定義了一個名為poll_vote的主題,它使用名為“poll-vote.tpl.php”的模板文件(因此是template鍵)(這是按慣例)。 通過使用實現它的模塊的路徑(例如modules / poll / poll-vote.tpl.php)可以找到該模板文件的路徑,因此可以將模板文件放在主模塊文件夾的子文件夾中。

通過實現物理函數名稱(在本例中為theme_poll_vote )或使用模板文件,有兩種方法可以實際返回主題函數的輸出。 如果template鍵為空,Drupal將假設您已實現了物理功能並將嘗試調用它。

如果您為主題輸出相當多的HTML,或者您根本不喜歡在PHP中的字符串中編寫HTML(我個人不這樣做),那么模板文件是首選。 但在任何一種情況下,調用主題時傳遞的變量(使用theme()或如上所述的渲染數組)本身都會傳遞給模板文件或主題函數。 所以:

function theme_poll_results(&$vars) {
  $raw_title = $vars['raw_title'];
  $results = $vars['results'];
  // etc...
}

如果您使用模板文件而不是相同的方法,則變量可用作$raw_title$results等,因為Drupal在解析模板文件之前在$vars上運行extract

我確信我錯過了很多,但是如果你有任何更具體的問題請求,我會盡力幫忙。

Drupal 6

我整天都陷入困境,現在已經成功實施,所以在這里分享我的發現,可能有助於理解hook_theme

涉及3個步驟:

  1. hook_theme

     function YOURMODULENAME_theme() { return array( 'xxx_xxx' => array( 'template' => 'xxx-xxx', // define xxx-xxx.tpl.php inside module 'arguments' => array('xxx' => null), //define $xxx so it will available in your xxx-xxx.tpl.php ), ); } 
  2. echo / return .tpl或任何.module的主題

     $output = theme('xxx_xxx', $xxx); 
  3. 現在變量在你xxx-xxx.tpl.php中神奇可用。

     <?php echo $xxx ?> 

注意:你可以傳遞$ xxx作為數組,對象或任何東西:)

還有另一種方式:(可以在Bartik主題中找到)

這里的場景是我們已經創建了自己的模塊,並希望覆蓋默認輸出,讓我們說一個標題為'zzz'的節點。
我們不知道也不關心如何生成默認輸出。 我們所需要的只是告訴Drupal使用我們自己的自定義模板文件(node-custom-name.tpl.php)來呈現該特定節點。

這些是步驟:

  1. 告訴Drupal我們的模板文件所在的位置。 (請記住,此功能僅在清除Drupal緩存后生效一次):

     // Implements hook_theme() function mymodulename_theme() { $theme = array(); $theme['node__custom__name'] = array( 'render element' => 'node', 'template' => 'path_from_mymodule_root/node__custom__name', ); return $theme; } 
  2. 告訴Drupal在何時何地使用它

     //Implements hook_preprocess_node() function mymodulename_preprocess_node($vars) { if($vars['node']->title == 'zzzz') { $vars['theme_hook_suggestions'][] = 'node__custom__name'; ... your other code ... } } 

    現在Drupal將僅針對該特定情況使用我們的模板文件,前提是'node-custom-name.tpl.php'文件位於聲明的路徑中,否則它將繼續根據回退模板的建議命名約定進行搜索。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM