[英]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中的文檔),因為它:
在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
。
我確信我錯過了很多,但是如果你有任何更具體的問題請求,我會盡力幫忙。
我整天都陷入困境,現在已經成功實施,所以在這里分享我的發現,可能有助於理解hook_theme
。
涉及3個步驟:
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 ), ); }
echo
/ return
.tpl
或任何.module
的主題
$output = theme('xxx_xxx', $xxx);
現在變量在你xxx-xxx.tpl.php
中神奇可用。
<?php echo $xxx ?>
注意:你可以傳遞$ xxx作為數組,對象或任何東西:)
還有另一種方式:(可以在Bartik主題中找到)
這里的場景是我們已經創建了自己的模塊,並希望覆蓋默認輸出,讓我們說一個標題為'zzz'的節點。
我們不知道也不關心如何生成默認輸出。 我們所需要的只是告訴Drupal使用我們自己的自定義模板文件(node-custom-name.tpl.php)來呈現該特定節點。
這些是步驟:
告訴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; }
告訴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.