hook_theme()如何工作?

Chr*_*nch 8 hook drupal drupal-7 drupal-templates

我很难理解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),
    ),
  );
Run Code Online (Sandbox Code Playgroud)

你能提供一个如何运作的例子吗?

Cli*_*ive 22

它为模块提供了一个定义主题的位置,然后可以被任何其他模块/主题覆盖.它还将为任何模块提供使用钩子的机会,例如mymodule_preprocess_theme_name更改传递给最终主题函数或模板文件的变量.

初始化主题函数基本上有两种方法:

theme('poll_results', array('raw_title' => 'title', 'results' => $results, etc...));
Run Code Online (Sandbox Code Playgroud)

$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.
Run Code Online (Sandbox Code Playgroud)

请记住,你应该避免直接调用theme()(根据theme.inc中的文档),因为它:

  • 绕过缓存.
  • 绕过hook_element_info()中定义的类型的默认值,包括附加资产
  • 绕过pre_render和post_render阶段.
  • Circumvents JavaScript陈述信息.

在Drupal 8中,theme()是一个私有函数_theme().有关更多详细信息,请访问www.drupal.org/node/2173655.

当你将上述两个poll_results元素与上面给出的例子中的元素进行比较时,你可能会发现正在发生的事情......因为PHP不是强类型语言,Drupal通过传递给theme函数的键控数组提供"命名参数" ,或作为渲染数组中的散列键.

就"渲染元素"而言,这基本上告诉主题系统将使用渲染数组调用此主题函数,该数组具有一个命名参数(在本例中form).代码看起来像这样:

$build = array(
  '#theme' => 'poll_choices',
  '#form' => $form
);
Run Code Online (Sandbox Code Playgroud)

这会将$form变量中的任何内容传递给主题函数,因为它是唯一的参数.

关于template关键:

'poll_vote' => array(
  'template' => 'poll-vote',
  'render element' => 'form',
)
Run Code Online (Sandbox Code Playgroud)

定义一个名为" poll_vote使用模板文件(因此是template密钥)"的主题,名称为"poll-vote.tpl.php"(这是按惯例).通过使用实现它的模块的路径(例如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...
}
Run Code Online (Sandbox Code Playgroud)

如果您正在使用的模板文件,而不是对同一方法的变量将可为$raw_title,$results等等,如Drupal的运行extract$vars解析模板文件之前.

我确信我错过了很多,但是如果你有任何更具体的问题请求,我会尽力帮忙.