Drupal中如何正确实现段落预处理函数并检查视频字段值?
Drupal段落预处理与body类添加解决方案
我是Drupal新手,需要实现以下需求:有一个名为ad_section的段落,包含两个字段:field_link(类型:Plain Text)和field_video(类型:Media->Video)。需要在段落展示的页面进行判断:若field_video字段已附加视频文件,则给<body>添加has-video类;若该字段为空,则添加no-video类。
当前html.html.twig中<body>类的输出代码如下:
{% set body_classes = [ logged_in ? 'user-logged-in' ] %} ... <body{{ attributes.addClass(body_classes) }}>
我尝试了多个预处理函数均无效果,现在解决以下两个问题:
1. 正确实现段落预处理函数(及body类传递逻辑)
首先明确:要修改<body>的类,不能仅在段落预处理函数中操作——段落的变量无法直接传递到html.html.twig模板。正确的思路是在html的预处理函数中,检查当前页面是否包含目标段落,再添加对应类。
段落预处理函数的正确写法(针对段落自身模板)
如果只是要给段落模板传递变量(而非修改body类),针对ad_section段落的预处理函数命名规则为[主题名]_preprocess_paragraph__[段落机器名],示例:
function constructor_preprocess_paragraph__ad_section(&$variables) { // 获取当前段落实体 $paragraph = $variables['paragraph']; // 后续可在这里处理段落相关变量,传递到段落模板 }
注意:修改.theme文件后必须清除Drupal缓存,否则函数不会生效。
2. 检查field_video是否附加视频文件
Media类型字段存储的是Media实体引用,需要先获取段落实体,再逐层检查Media及其中的视频文件字段:
完整解决方案(给body添加类)
在自定义主题的.theme文件中添加html预处理函数,逻辑如下:
function constructor_preprocess_html(&$variables) { // 获取当前页面的节点(如果段落挂载在节点上,替换为实际的实体类型/字段) $node = \Drupal::routeMatch()->getParameter('node'); if ($node instanceof \Drupal\node\NodeInterface) { // 遍历节点上的段落字段(替换为你实际存储段落的字段名,比如field_paragraphs) if ($node->hasField('field_paragraphs')) { foreach ($node->get('field_paragraphs') as $item) { $paragraph = $item->entity; // 确认是目标ad_section段落 if ($paragraph && $paragraph->bundle() == 'ad_section') { $has_valid_video = FALSE; // 检查段落的field_video是否有值 if ($paragraph->hasField('field_video') && !$paragraph->get('field_video')->isEmpty()) { $media = $paragraph->get('field_video')->entity; // 检查Media实体的视频文件字段(替换为你Media类型中实际的视频字段名,比如field_media_video_file) if ($media && $media->hasField('field_media_video_file') && !$media->get('field_media_video_file')->isEmpty()) { $has_valid_video = TRUE; } } // 给body添加对应类 $variables['attributes']['class'][] = $has_valid_video ? 'has-video' : 'no-video'; // 找到第一个目标段落就停止,避免重复添加类 break; } } } } }
适配其他场景
如果段落挂载在区块或其他实体上,只需调整获取实体的代码(比如用\Drupal::routeMatch()->getParameter('block')获取区块),核心检查逻辑不变。
内容的提问来源于stack exchange,提问作者Barney Gumble
相关产品推荐
相关产品推荐

