如何在自定义公开视图过滤器中使用视图过滤条件? -- views 领域 和 8 领域 drupal 相关 的问题

How to use views filter criteria in a custom exposed view filter?


0
vote

问题

中文

我正在使用drupal 8.7.11,并创建了一个公开的过滤器的自定义视图,它为用户提供了使用姓名的复选框列表过滤实体参考字段的选项而不是自动完成。

此刻我已经硬编码了查询条件,以在具有某些内容检查的实体查询中构建列表。日期是未来

但是,我想在不同的视图中重复使用过滤器,这不需要检查日期是否是日期。

是否可以从视图结果中获取节点ID,然后我可以从中构建选项列表或获取视图用于放入我的列表查询的现有视图筛选条件?

这是我到目前为止的代码,用于特定视图。

视图_mods.module

  function views_mods_views_data_alter(&$data) {   $data['node__field_event_tutor']['tutor'] = array(     'title' => t('Tutor'),     'filter' => [       'title' => t('Tutor'),       'help' => t('Select by tutor - provided by views mods module.'),       'field' => 'field_event_tutor_target_id',       'id' => 'views_mods_tutor',       'group' => 'Content'     ],   ); }   

src / plugin / views / filter / tutorviewsfilter.php

  <?php namespace Drupalviews_modsPluginviewsfilter;  use DrupalCoreDatetimeDrupalDateTime; use DrupaluserEntityUser; use DrupalviewsPluginviewsdisplayDisplayPluginBase; use DrupalviewsPluginviewsfilterManyToOne; use DrupalviewsViewExecutable;  /**  * Filters by tutor.  *  * @ingroup views_filter_handlers  *  * @ViewsFilter("views_mods_tutor")  */ class TutorViewsFilter extends ManyToOne {   /**   * {@inheritdoc}   */   public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {     parent::init($view, $display, $options);     $this->valueTitle = t('Tutor');     $this->definition['options callback'] = [$this, 'generateOptions'];   }    /**   * Override the query so that no filtering takes place if the user doesn't   * select any options.   */   public function query() {     if (!empty($this->value)) {       parent::query();     }   }    /**   * Skip validation if no options have been chosen so we can use it as a   * non-filter.   */   public function validate() {     if (!empty($this->value)) {       parent::validate();     }   }    /**   * Helper function that generates the options.   * @return array   */   public function generateOptions() {     $tutor_options = [];      $time = new DrupalDateTime('now');     // use entity query to get nids - this respects group memberships     // so won't show tutors that are attached to nodes the user does not have     // access to.     $eq = Drupal::entityQuery('node');     $or_type = $eq->orConditionGroup()       ->condition('type', 'tutorial')       ->condition('title', 'workshop');     $or_exclude = $eq->orConditionGroup()       ->condition('field_exclude_from_listings', 0)       ->notExists('field_exclude_from_listings'); // IS NULL     $or_eas = $eq->orConditionGroup()       ->condition('field_legacy_eas', 0)       ->notExists('field_legacy_eas'); // IS NULL     $nids = $eq       ->condition('status', 1)       ->condition($or_type)       ->condition($or_exclude)       ->condition($or_eas)       ->condition('field_event_time', $time->format('Y-m-dTH:i:s'), '>=')       ->execute();      $dq = Drupal::database()->select('node__field_event_tutor', 'fe_tutor');     $dq->addField('fe_tutor', 'field_event_tutor_target_id', 'uid');     $dq->addField('f_name', 'field_prof_first_name_value', 'fname');     $dq->addField('l_name', 'field_prof_last_name_value', 'lname');     $dq->leftJoin('profile', 'profile', "fe_tutor.field_event_tutor_target_id = profile.uid AND profile.type = 'employee'");     $dq->leftJoin('profile__field_prof_first_name', 'f_name', 'profile.profile_id = f_name.entity_id');     $dq->leftJoin('profile__field_prof_last_name', 'l_name', 'profile.profile_id = l_name.entity_id');     $dq->condition('fe_tutor.entity_id', $nids, 'IN');     $dq->groupBy('fe_tutor.field_event_tutor_target_id');     $dq->groupBy('f_name.field_prof_first_name_value');     $dq->groupBy('l_name.field_prof_last_name_value');     $tutor_list = $dq->execute()->fetchAll();      if ($tutor_list) {       foreach ($tutor_list as $index => $user) {         $name = trim($user->fname) . ' ' . trim($user->lname);         if (empty($user->lname)) {           $account = User::load($user->uid);           $name = $account->getAccountName();         }         $tutor_options[$user->uid] = $name;       }     }      return $tutor_options;   } }   
英文原文

I am using Drupal 8.7.11 and have created a custom views exposed filter which provides users the option to filter an entity reference field using a checkbox list of names instead of autocomplete.

At the moment I have hardcoded the query conditions to build the list in a entity query with certain content checks e.g. date is in the future

However I would like to reuse the filter in a different view which doesn't need to check if a date is in the future.

Is it possible to either get the node ids from the view result, which I can then build the option list from or get the existing views filter criteria that the view uses to put into my list query?

Here is the code I have so far which works for on specific view.

views_mods.module

function views_mods_views_data_alter(&$data) {   $data['node__field_event_tutor']['tutor'] = array(     'title' => t('Tutor'),     'filter' => [       'title' => t('Tutor'),       'help' => t('Select by tutor - provided by views mods module.'),       'field' => 'field_event_tutor_target_id',       'id' => 'views_mods_tutor',       'group' => 'Content'     ],   ); } 

src/Plugin/views/filter/TutorViewsFilter.php

<?php namespace Drupal\views_mods\Plugin\views\filter;  use Drupal\Core\Datetime\DrupalDateTime; use Drupal\user\Entity\User; use Drupal\views\Plugin\views\display\DisplayPluginBase; use Drupal\views\Plugin\views\filter\ManyToOne; use Drupal\views\ViewExecutable;  /**  * Filters by tutor.  *  * @ingroup views_filter_handlers  *  * @ViewsFilter("views_mods_tutor")  */ class TutorViewsFilter extends ManyToOne {   /**   * {@inheritdoc}   */   public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {     parent::init($view, $display, $options);     $this->valueTitle = t('Tutor');     $this->definition['options callback'] = [$this, 'generateOptions'];   }    /**   * Override the query so that no filtering takes place if the user doesn't   * select any options.   */   public function query() {     if (!empty($this->value)) {       parent::query();     }   }    /**   * Skip validation if no options have been chosen so we can use it as a   * non-filter.   */   public function validate() {     if (!empty($this->value)) {       parent::validate();     }   }    /**   * Helper function that generates the options.   * @return array   */   public function generateOptions() {     $tutor_options = [];      $time = new DrupalDateTime('now');     // use entity query to get nids - this respects group memberships     // so won't show tutors that are attached to nodes the user does not have     // access to.     $eq = \Drupal::entityQuery('node');     $or_type = $eq->orConditionGroup()       ->condition('type', 'tutorial')       ->condition('title', 'workshop');     $or_exclude = $eq->orConditionGroup()       ->condition('field_exclude_from_listings', 0)       ->notExists('field_exclude_from_listings'); // IS NULL     $or_eas = $eq->orConditionGroup()       ->condition('field_legacy_eas', 0)       ->notExists('field_legacy_eas'); // IS NULL     $nids = $eq       ->condition('status', 1)       ->condition($or_type)       ->condition($or_exclude)       ->condition($or_eas)       ->condition('field_event_time', $time->format('Y-m-d\TH:i:s'), '>=')       ->execute();      $dq = \Drupal::database()->select('node__field_event_tutor', 'fe_tutor');     $dq->addField('fe_tutor', 'field_event_tutor_target_id', 'uid');     $dq->addField('f_name', 'field_prof_first_name_value', 'fname');     $dq->addField('l_name', 'field_prof_last_name_value', 'lname');     $dq->leftJoin('profile', 'profile', "fe_tutor.field_event_tutor_target_id = profile.uid AND profile.type = 'employee'");     $dq->leftJoin('profile__field_prof_first_name', 'f_name', 'profile.profile_id = f_name.entity_id');     $dq->leftJoin('profile__field_prof_last_name', 'l_name', 'profile.profile_id = l_name.entity_id');     $dq->condition('fe_tutor.entity_id', $nids, 'IN');     $dq->groupBy('fe_tutor.field_event_tutor_target_id');     $dq->groupBy('f_name.field_prof_first_name_value');     $dq->groupBy('l_name.field_prof_last_name_value');     $tutor_list = $dq->execute()->fetchAll();      if ($tutor_list) {       foreach ($tutor_list as $index => $user) {         $name = trim($user->fname) . ' ' . trim($user->lname);         if (empty($user->lname)) {           $account = User::load($user->uid);           $name = $account->getAccountName();         }         $tutor_options[$user->uid] = $name;       }     }      return $tutor_options;   } } 
     

回答列表

1
 
vote

基于以下文章,我有一个建议: https://zanzarra.com/blog/custom-views-filter-plugin-drupal-8-bounding-box-geofield 。 我自己没有尝试过这个,但我认为以下应该有效:

  • 覆盖过滤器类中的ValueForm和ValueBuit方法:
    • 创建一个表单,允许您配置是否包含过去的实体(以及您希望提供的额外设置)
    • 将所有值滚动在某种编码的某种编码字符串中:json,序列化阵列,无论是
  • 在查询中获取您的编码字符串覆盖值属性,解码它,并使用YUOR设置作为生成方法的参数

显然,valueform是允许yu在将其添加到视图时配置过滤器的表单。

 

Based on the following article, I have a suggestion: https://zanzarra.com/blog/custom-views-filter-plugin-drupal-8-bounding-box-geofield . I haven't tried this out myself, but I think the following should work:

  • Override the valueForm and valueSubmit methods in your filter class:
    • Create a form that allows you to configure whether or not to include entities in the past (and whatever extra settings you wish to provide)
    • Roll all your values together in an encoded string of some sort: json, serialized array, whatever
  • Get your encoded string in the query override out of the value property, decode it, and use yuor settings as parameters for your generateOptions method

Obviously the valueForm is the form that allows yu to configure a filter when you add it to a view.

 
 
 
 
0
 
vote

我开始在某种程度上努力实现这一目标,但是我相信这不是做到这一点的最佳方式,但它正在为我的目的工作。

src / plugin / views / filter / tutorviewsfilter.php 我替换了硬编码实体查询条件,并创建了一些半逻辑来从视图处理程序生成它们。

      $eq = Drupal::entityQuery('node');      $filters = $this->view->getHandlers('filter');      foreach ($filters as $field => $field_data) {       $condition = [];       if ($field_data['exposed'] == TRUE) { //        @TODO: Add option to filter results by user input         continue;       } else {         if ($field_data['table'] == 'node_field_data') {           $condition = [$field_data["field"], $field_data["value"], $field_data['operator']];         } elseif($field_data["plugin_id"] == 'datetime') {           if ($field_data["value"]["value"] == 'now') {             $time = new DrupalDateTime('now');             $time_value = $time->format('Y-m-dTH:i:s');           } else {             $time_value = $field_data["value"]["value"];           }           $condition = [substr($field_data["field"], 0, -6), $time_value, $field_data['operator']];         } elseif ($field_data["plugin_id"] == 'numeric') {           $condition = [substr($field_data["field"],0, -10), $field_data['value']['value'], $field_data['operator']];         } else {           $condition = [substr($field_data['table'], 6), $field_data['value'], $field_data['operator']];         }          switch ($field_data['operator']) {           case 'not empty':             $eq->exists($condition[0], $condition[1], $condition[2]); // IS NOT NULL             break;           default:             $eq->condition($condition[0], $condition[1], $condition[2]);         }       }     }     $nids = $eq->execute();   
 

I started working on a way to achieve this, however I am sure this is not the best way to do this, but it is working for my purposes.

In src/Plugin/views/filter/TutorViewsFilter.php I have replaced the hardcoded entity query conditions and created some semi logic to generate them from the views handlers.

    $eq = \Drupal::entityQuery('node');      $filters = $this->view->getHandlers('filter');      foreach ($filters as $field => $field_data) {       $condition = [];       if ($field_data['exposed'] == TRUE) { //        @TODO: Add option to filter results by user input         continue;       } else {         if ($field_data['table'] == 'node_field_data') {           $condition = [$field_data["field"], $field_data["value"], $field_data['operator']];         } elseif($field_data["plugin_id"] == 'datetime') {           if ($field_data["value"]["value"] == 'now') {             $time = new DrupalDateTime('now');             $time_value = $time->format('Y-m-d\TH:i:s');           } else {             $time_value = $field_data["value"]["value"];           }           $condition = [substr($field_data["field"], 0, -6), $time_value, $field_data['operator']];         } elseif ($field_data["plugin_id"] == 'numeric') {           $condition = [substr($field_data["field"],0, -10), $field_data['value']['value'], $field_data['operator']];         } else {           $condition = [substr($field_data['table'], 6), $field_data['value'], $field_data['operator']];         }          switch ($field_data['operator']) {           case 'not empty':             $eq->exists($condition[0], $condition[1], $condition[2]); // IS NOT NULL             break;           default:             $eq->condition($condition[0], $condition[1], $condition[2]);         }       }     }     $nids = $eq->execute(); 
 
 

相关问题

1  如何在Ajax视图的公开日期过滤器中更改日期格式,该过滤器使用Bef?  ( How to change date format in an ajax views exposed date filter that uses bef ) 
我有一个使用ajax选项的视图,并使用带有更好的暴露过滤器(最新版本)的一些日期过滤器。我想做的是将日期过滤器的默认日期格式从mm / dd / yy更改为dd / mm / yy。 我试图实现这个解决方案。格式更改,弹出窗口工作正常,但在应用过滤器时出现问题,似乎日期过滤器值似乎没有验证。 如何在AJAX视图中更改...

-2  如何在一个页面中放置多视图?  ( How to place multi view in one page ) 
我有两个内容类型,我想用不同的显示模式在一个页面中放两个内容视图。 如何解决它? ...

-2  如何以编程方式添加“更多”链接?  ( How to programmatically add a more link ) 
在视图UI(在中心列)中,我们可以选择"更多链接" ,该"更多链接" 将"创建更多链接" 复选框。选择此选项返回一个链接以获取视图的更多结果。 如何以编程方式添加此"更多" 链接?这是一个与Drupal 7视图的所有结果的链接? ...

0  如何使用hook_views_pre_render()修改视图字段  ( How do use hook views pre render to modify view fields ) 
想要使用hook_views_pre_render()根据另一个字段中的数据以视图修改字段。从此代码开始: function sbn_views_pre_render(ViewExecutable $view) { drupal_set_message($view->id()); foreach ($...

1  使用hook_views_pre_render()将字段更改为URL链接  ( Use hook views pre render to change field to url link ) 
我想在视图中读取hook_views_pre_render(),并将字段输出更改为可点击的链接。 这里是代码: function sbn_views_pre_render(ViewExecutable $view) { // https://drupal.stackexchange.com/questio...

0  用分类权重排序  ( Sort by taxonomy weight ) 
我有一个内容类型"成员" ,带有一个名为"成员角色" 的分类术语,它是一个多价值字段。每个成员最多可包含3个成员角色。 我已经创建了一个视图,以参考分类场与分类学术语重量排序的成员。但问题是每个成员在视图结果页面中重复3次。 我的问题是如何删除重复项,并且仅在多价字段(成员角色)中的最后一个值排序。 ...

2  如何在自定义字段中使用替换模式?  ( How can i use a replacement pattern in a custom field ) 
我刚刚在视图中创建了一个新的自定义字段,但我想在该字段中使用替换模式。是否有可能这样做? class CustomButtonField extends FieldPluginBase { /** * {@inheritdoc} */ public function usesGroupBy(...

0  只在首页上完全显示最近的帖子,其他人  ( Fully display only most recent post on front page furl the others ) 
目前我的首页只会为我所有新帖子显示一款预告片。 我知道我可以转到 Structure > Views > Frontpage 并将其更改为 show Content | Full ,它将在首页上显示每个帖子的完整帖子。 我想做的是,虽然只是我最近的帖子的全部帖子,然后是所有其他帖子的速度。 是可以这样做吗? ...

1  如何在视图模板中单独访问链接字段(URL和文本)值?  ( How to access link fields url and text value separately in views template ) 
我的视图块有一个名为 field_link 的链接字段,附加到内容类型命名为 products ,和我正在尝试在视图模板 views-view-unformatted.html.twig 中单独访问链接字段值(URL和Text)。 以下代码给出格式化的html。 {{ row.content['#view']....

0  配置导入错误  ( Configuration import error ) 
我在本地系统中有drupal8。我想将我的生产环境配置导入我当地的。所以我正在运行 醉汉cim -y 我收到以下错误。 Unexpected error during import with operation update for core.entity_view_display.paragraph.card...

0  我们可以访问视图 - 查看-unformatted.twig中的段落字段吗?  ( Can we access paragraph field in views view unformatted twig ) 
有没有办法访问视图中的视图中的段落中的字段 - 查看-unformatted.twig。 我想在打印行之前执行检查段落的字段 这样的东西 {% for row in rows %} {% set row_classes = [ default_row_class ? 'views-row'...

3  如何在视图块上获取总行数  ( How to get total number of rows on a block of a view ) 
在 hook_block_view_alter() 我需要获得这个块显示的总行数。 例如,我有一个下列块的视图: 在 hook_block_view_alter() 我做了适当的检查,以便杂草不必要的块,并获得上图所示的一个。 function mymodule_block_view_alter(array...

1  为什么我不能从上下文过滤器评估的URL中删除%20?  ( Why cant i remove the 20 from a url evaluated by a contextual filter ) 
我用上下文过滤器创建了一个具有分类术语的上下文过滤器,具有两个单词,使得空间在URL上创建%20。我发现解决方案是检查"转换空间" 框中的"转换空间" 框,但仍然不会摆脱URL。有人在这里知道为什么?我正在附加视图的配置的屏幕镜头和我使用pathauto模块设置的URL模式。谢谢! ...

0  在URL中发送视图字段 - Drupal  ( Send view field in url drupal ) 
我有一个使用drupal 8视图中的嵌入式过滤器创建的搜索页面。在我有一个字段的字段列表中 - [field_program_id]。在单击此按钮时,我还有一个按钮"了解更多" ,我希望通过[Field_program_id]并显示该页面中的程序的详细信息。不知道从哪里开始。任何指导?! 我的视图如下所示: ...

0  在preprocess_views_view_field中调用另一个字段  ( Call another field inside preprocess views view field ) 
如何访问Preprocess_views_view_field中另一个字段的值。 这是一个例子: function homename_preprocess_views_view_field(&amp; $变量){ $ view = $ Variables ['View']; $字段= $ Variables...

0  在MySQL中的视图中使用分类学曝光过滤器只能使用61个表加入  ( Using taxonomy exposed filter in a view ends in mysql can only use 61 tables in ) 
场景 一个名为300分类术语的国家的分层词汇,每个国家/地区,缩进,如: 美国(1级) 安圭拉(2级) 安提瓜y巴布达(2级) ......(2级) 欧洲(1级) 奥地利(2级) 亚美尼亚(2级) ......(2级) 一个名为Office的内容类型...

1  如何添加自定义串行程序来更改REST导出的输出  ( How to add a custom serializer to alter the output of rest export ) 
响应/输出的一个视图,我想添加一个额外的行。 所以我在我的模块中创建了一个自定义串行程序。 文件的路径为: My_Module/src/Plugin/views/style/HindiCustomSerializer.php 这里我扩展了 core/modules/rest/src/Plugin/views...

1  分类学期组内容,但随后还列出了每一行中的所有术语  ( Group content by taxonomy term but then also list all terms in each row ) 
我正在寻找创建视图的帮助。 我有一个内容类型,事情。事情有一个领域,您可以在分类,类别中选择多个术语。我希望我的观点看起来像这样: 类别1 事物1 第1类 第2类 事物2 第1类 第3类 类别2 事1 第1类 第2类 所以基本上,我想按照条款进行组,然后列出每件事下面...

0  如何在Twig [Views.view.unformatted]中获取翻译内容?  ( How to get translated content in twig views view unformatted ) 
我正在尝试在我的自定义视图 - 视图 - 未格式化的枝条文件中获取翻译节点标题。 以下是我在Twig文件中检索我的节点标题的方式 <div class="col-md-6 title"> {% for row in rows %} <strong>{{ row.content['#row']._en...

0  包含包含空字段值的计数聚合  ( Aggregation with count that includes empty field values ) 
我看到了关于聚合的其他问题,但我没有找到类似于我需要的东西。 我有一个通过启用聚合的视图,结果由字段值(文本字段)分组,也与该字段的计数进行分组。 一切都好,但我想包括空值的数量,我不能让这件事工作...... 现在我有类似的东西 | FIELD VALUE | COUNT | |-------------...




© 2021 it.wenda123.org All Rights Reserved. 问答之家 版权所有


Licensed under cc by-sa 3.0 with attribution required.