如何在Drupal 10中创建可传入字段名参数的非空字段视图?
在Drupal 10中创建支持字段参数的非空节点视图
这是完全可行的,以下是两种实用方案:
方案一:自定义模块+Views钩子实现(性能最优)
通过修改视图的查询逻辑,动态根据传入的字段ID添加非空过滤条件:
- 创建基础视图:先搭建一个展示目标内容类型节点的视图,添加「内容: 类型」过滤器固定目标内容类型。
- 添加上下文过滤器:添加「全局: 自定义字符串」作为接收字段ID的参数,设置参数名称(比如
field_id)。 - 实现视图查询修改钩子:在自定义模块中编写
hook_views_query_alter(),根据传入的参数动态过滤:
function my_custom_module_views_query_alter(ViewExecutable $view, QueryPluginBase $query) { // 仅针对目标视图生效,替换为你的视图机器名 if ($view->id() !== 'target_view_machine_name') { return; } // 获取传入的字段ID参数 $field_id = $view->args[0] ?? ''; // 校验参数合法性 if (empty($field_id) || !str_starts_with($field_id, 'field_')) { // 参数无效时返回空结果 $query->where[] = ['conditions' => [['field' => '1', 'value' => '0', 'operator' => '=']]]; return; } // 验证字段是否属于目标内容类型,替换为你的内容类型机器名 $content_type = 'target_content_type'; $field_def = \Drupal::service('entity_field.manager')->getFieldDefinitions('node', $content_type)[$field_id] ?? NULL; if (!$field_def) { $query->where[] = ['conditions' => [['field' => '1', 'value' => '0', 'operator' => '=']]]; return; } // 获取字段对应的数据库表和列名 $storage_def = $field_def->getStorageDefinition(); $table = $storage_def->getTableName(); $column = $storage_def->getMainPropertyName(); // 添加字段非空的查询条件 $query->addTable($table); $query->addWhere(0, "$table.$column", NULL, 'IS NOT NULL'); }
- 访问视图:通过URL传递字段ID参数,比如
/your-view-path/field_1即可返回field_1非空的节点。
方案二:使用Views Custom Filter模块(快速实现)
无需编写自定义模块,借助模块快速实现动态过滤:
- 安装模块:在后台扩展中搜索并安装
Views Custom Filter模块。 - 添加自定义过滤器:在视图中添加「全局: 自定义过滤器」,进入设置页面勾选「使用PHP代码」。
- 编写过滤逻辑:输入以下PHP代码,通过URL参数接收字段ID并判断字段是否非空:
// 从URL参数获取字段ID $field_id = $_GET['field'] ?? ''; if (empty($field_id) || !str_starts_with($field_id, 'field_')) { return FALSE; } // 判断当前节点的目标字段是否非空 $node = $row->_entity; return !$node->get($field_id)->isEmpty();
- 访问视图:通过URL参数传递字段ID,比如
/your-view-path?field=field_2即可过滤出field_2非空的节点。
注意事项
- 两种方案都要做好参数校验,避免无效字段或恶意参数导致的错误。
- 多值字段使用
isEmpty()会自动判断是否存在值,符合需求。 - 方案一直接修改SQL查询,性能优于方案二的行级判断。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

