You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal如何跨Twig传递自定义块变量到渲染的视图块

问题根因

Twig中调用drupal_block()传入的第二个数组参数,是作为块插件的配置项传入的,不会自动映射为Views可直接读取的内置参数,因此无法在hook_views_pre_view中直接读取到product_type变量。另外直接修改$view->display_handler->display['display_options']数组的写法不会生效,Views要求通过官方提供的setOption()方法修改配置,才能触发配置校验、缓存处理等逻辑。


实现方案

方案1:保留现有Twig写法,通过钩子中转取值

不需要调整现有Twig模板的调用代码,通过两个钩子配合完成参数传递,稳定性最高:

  1. 首先在自定义模块中添加临时存储函数+块视图 alter 钩子,提前拿到传入的块配置:
/**
 * 临时存储视图块传入的自定义参数
 */
function _mymodule_temp_view_params(string $key = NULL, mixed $value = NULL) {
  static $storage = [];
  if (!is_null($key) && !is_null($value)) {
    $storage[$key] = $value;
  }
  return is_null($key) ? $storage : ($storage[$key] ?? NULL);
}

/**
 * Implements hook_block_view_alter()
 */
function mymodule_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  // 仅处理目标视图块,避免影响其他块
  if ($block->getPluginId() === 'views_block:my-view-block_1') {
    $block_config = $block->getConfiguration();
    if (!empty($block_config['product_type'])) {
      _mymodule_temp_view_params('product_type', $block_config['product_type']);
    }
  }
}
  1. 修改原有hook_views_pre_view逻辑,读取临时存储的参数完成过滤设置:
/**
 * Implements hook_views_pre_view()
 */
function mymodule_views_pre_view(&$view, &$display_id, &$args) {
  // 仅处理目标视图的对应显示
  if ($view->id() === 'my_view' && $display_id === 'block_1') {
    $product_type = _mymodule_temp_view_params('product_type');
    if ($product_type) {
      // 获取原有过滤器配置,避免覆盖其他过滤器
      $filters = $view->display_handler->getOption('filters');
      // 修改目标过滤项的默认值
      $filters['field_product_type_target_id']['default_value'] = $product_type;
      // 存回配置,不要直接修改display下的原始数组
      $view->display_handler->setOption('filters', $filters);
    }
  }
}

方案2:使用Views原生上下文过滤(推荐,无需大量自定义代码)

这是Drupal Views推荐的传参方式,不需要写临时存储逻辑,维护成本更低:

  1. 调整Twig中的调用写法,将参数放到Views识别的arguments节点下:
{{ drupal_block('views_block:my-view-block_1', {
  arguments: ['clothes']
}) }}
  1. 在视图编辑页,给对应块显示添加上下文过滤器,选择产品类型(field_product_type)字段,根据需求配置「当过滤值不存在时」的逻辑(比如隐藏视图、显示所有结果、展示404等),保存视图即可。
    如果需要额外自定义过滤逻辑,可以直接在hook_views_pre_view中读取$args数组拿到传入值:
function mymodule_views_pre_view(&$view, &$display_id, &$args) {
  if ($view->id() === 'my_view' && $display_id === 'block_1') {
    // 对应arguments数组的顺序,第一个参数索引为0
    $product_type = $args[0] ?? NULL;
    // 自定义逻辑
  }
}

注意事项
  • 所有视图相关的自定义逻辑必须加视图ID、显示ID判断,避免逻辑误用到站点其他视图上
  • 视图块必须配置对应缓存上下文,否则会出现不同参数值下缓存串数据的问题,如果用上下文过滤方案,Views会自动添加对应缓存上下文;如果用方案1,需要手动给块添加url或者自定义参数对应的缓存上下文
  • 如果product_type是多值字段,需要将传入值处理为数组格式再赋值给过滤器,不要传字符串

内容的提问来源于stack exchange,提问作者Asad ullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:54:02