首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从上下文筛选器中通过父项过滤公开筛选器中的子项?

如何从上下文筛选器中通过父项过滤公开筛选器中的子项?
EN

Drupal用户
提问于 2019-12-12 09:25:04
回答 2查看 1.2K关注 0票数 1

我有一个带有嵌套分类法术语的区域词汇表,如下所示。

我对Drupal 8中的分类法术语有一个视图,它对父和子的所有术语都有一个公开的过滤器。我想要的是,当我添加术语父级的上下文过滤器时,exposed过滤器应该只显示与上下文过滤器中父项匹配的子术语。

例如,如果URL包含Deoghar,那么公开的过滤器(如下面的filter)应该只显示术语Karon作为选项。

EN

回答 2

Drupal用户

发布于 2019-12-12 10:33:32

我最近在我的一个使用MYMODULE_form_views_exposed_form_alter的项目中做了这件事。代码假设在第一个位置上有一个带有术语ID的视图作为上下文过滤器,例如domain.com/myview/123

代码语言:javascript
复制
getStorage('view');
  $display_id = $view['view']->current_display;

  if ($form_id == 'views_exposed_form' && $view['view']->id() == 'MY_VIEW' && $display_id == 'MY_VIEWDISPLAY') {
    if (!empty($view['view']->args) && $view['view']->args[0]) {
      //get the term ID from the contextual filter
      $contextTermId = $view['view']->args[0];
      $entriesToRemove = [];

      $currentFilterValue = $form_state->getUserInput()['FIELD_FILTER_TAXONOMY'];
      foreach ($form['FIELD_FILTER_TAXONOMY']['#options'] as $idx => $entry) {
        if ($idx === 'All') {
          //remove the old root '- Any -' option
          $entriesToRemove[] = $idx;
        }
        //the next line is a bit shaky might need rework:
        //sometimes filter entries are a stdClass, 
        //but I've also seen entries as array in other exposed forms (grouped filters?)
        elseif ($entry instanceof stdClass && is_array($entry->option)) {
          $termId = key($entry->option);
          $termName = current($entry->option);
          //the context filter term is our new root, so we change its label to '- Any -'
          if ($termId == $contextTermId) {
            $form['FIELD_FILTER_TAXONOMY']['#options'][$idx]->option = [$termId => t('- Any -')];
            if (empty($currentFilterValue) || $currentFilterValue == 'All') {
              //we've removed the default empty/All entry, reset it to our newly created, faked '- Any -' category
              $form_state->setUserInput(['FIELD_FILTER_TAXONOMY' => $contextTermId]);
            }
          }
          else {
            //this is the core part: for each filter option load the term
            //and check if it is a child of the contextual filter term
            $parents = \Drupal::entityTypeManager()
              ->getStorage('taxonomy_term')
              ->loadParents($termId);
            if (!in_array($contextTermId, array_keys($parents))) {
              $entriesToRemove[] = $idx;
            }
            else {
              //optional: we are in a sub-filter now,so we no longer need the leading '-' to indicate hierarchy
              $form['FIELD_FILTER_TAXONOMY']['#options'][$idx]->option = [$termId => trim(preg_replace('/^-/', '', $termName))];
            }
          }
        }
      }
      foreach ($entriesToRemove as $idx) {
        unset($form['FIELD_FILTER_TAXONOMY']['#options'][$idx]);
      }
      //optional: if there is only 1 entry left, hide the filter
      if (count($form['FIELD_FILTER_TAXONOMY']['#options']) == 1) {
        $form['FIELD_FILTER_TAXONOMY'] = [
          '#type' => 'hidden',
          'value' => $contextTermId
        ];
      }
    }
  }
}

注意:不要在庞大的分类法上这样做,我的代码加载每个分类法术语来决定是否需要删除它。

票数 1
EN

Drupal用户

发布于 2019-12-12 13:06:42

正如@Hudri所说,您可以使用MYMODULE_form_views_exposed_form_alter()修改表单。

与其检查每个术语是否是上下文筛选器参数,不如使用TermStorage::loadTree()方法加载术语下的术语树。

代码语言:javascript
复制
$vocabulary_id = 'tags';
// Get this from your view object's contextual argument, e.g. $view->args[0], etc
$parent_id = 11;

$child_terms = \Drupal::entityTypeManager()
  ->getStorage('taxonomy_term')
  ->loadTree($vocabulary_id, $parent_id);

// Next build an options array of the child terms.
$child_term_options = [];
// Maybe you want an Any option
$child_term_options[''] = '- Any -';
foreach ($child_terms as $term) {
  $child_term_options[$term->tid] = $term->name;       
}

// Next update your filter options with only the child terms:
$form['MY_EXPOSED_FILTER']['#options'] = $child_term_options;
票数 0
EN
页面原文内容由Drupal提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://drupal.stackexchange.com/questions/289212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档