在 Drupal 8 中的特定节点类型上使用预处理挂钩

Using preprocess hook on specific node type in Drupal 8

我已成功使用预处理页面挂钩,例如:

function mytheme_preprocess_page__node_front(&$variables) {
    ...
}

function mytheme_preprocess_page__node_12(&$variables) {
    ...
}

分别与名为 page--front.html.twig 和 page--12.html.twig 的自定义模板相关联。

我正在尝试为名为“视频”的内容类型实施相同的挂钩和模板配对。我知道区别在于我的示例是特定页面的自定义模板,而我的目标是整个内容类型的自定义模板,但我有一个名为 node--video.html.twig 的自定义模板所有视频页面的模板。但是,当我尝试基于此模板名称编写一个钩子时:

function mytheme_preprocess_node__video(&$variables) {
    ...
}

这行不通。我认为我要么不能像这样定义一个钩子,要么我只是错误地命名它。我发现了一些与此相关的线程,例如 this,这似乎暗示我需要为所有节点定义一个挂钩,然后编写一个单独处理每种类型的 if 语句。 所以.......

最后一个问题:我可以为整个内容类型定义一个挂钩吗?如果可以,我做错了什么?

在预处理器中使用条件获取节点类型,然后在其中执行您的逻辑,或调用另一个函数。

function mytheme_preprocess_node(&$variables) {
  switch ($variables['node']->getType()) {
    case "video":
      // ...
    break;
    case "something_else":
      // ...
    break;
  }
}

从理论上讲,您可以通过尝试调用名为 mytheme_preprocess_node__" . $variables['node']->getType() 的函数(如果它存在)来模拟您试图实现的目标,但是没有明显的好处就太麻烦了。

在 zen 模板的 drupal 7 中,我曾经使用过这个通用解决方案。我认为它在 drupal 8 上仍然是一个可行的解决方案:

function mytheme_preprocess_node(&$variables) {
  ...
  // Add global modification that works for all node type
  $function = __FUNCTION__ . '__' . $variables['node']->getType();
  // Each node type can have its own specific function
  if (function_exists($function)) {
    $function($variables, $hook);
  } 
  ...
}

您现在可以添加仅适用于您的节点类型的预处理函数。

function mytheme_preprocess_node__video(&$variables) {
    ...
}

每个节点类型的预处理逻辑不是只有一个大功能,而是有自己的功能。更利于维护。