Drupal 8:分类法页面限制基于父项的公开过滤器选项

Drupal 8: Taxonomy page limit exposed filter options based on parent term

在 Drupal 8 站点中,我有一个带有视图块的分类页面。该视图列出了用您所在页面的术语标记的文章。它还显示用当前分类页面的子术语标记的文章。

我正在使用公开过滤器 "Content: Has taxonomy terms (with depth) (exposed)" 让用户根据子术语过滤文章。目前,无论您当前使用哪种分类法,该过滤器都会显示所有术语。

以下是公开过滤器中列出的项目的示例:

Mammals
 - Cat
 - Dog
Reptiles
 - Lizard
 - Snake
Amphibians
 - Frog
 - Salamander

父术语之一的 URL 为:

网站.com/animal/mammals

我需要将公开过滤器中的选项列表限制为仅显示基于 URL 的术语的子项。所以在上面的 URL 中,只有 Cat 和 Dog 会列在暴露的过滤器中。

在 Drupal 7 中,我可以通过 theme.module 中的 hook_form_alter 使用 URL arg(2) 来获取术语名称。我找不到任何关于如何在 Drupal 8 中执行此操作的文档。

这是我目前的发现:

function myTheme_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-article-tags-block-1') {

    $term = arg(2);
    //Need D8 code to load term, find it's children and alter the select box to show those children

  }
}

如果这不是实现我目标的方法,我愿意接受其他选择。提前谢谢你。

hook_form_alter 仍然有效,尽管 arg() 在 Drupal 8 中被删除了。

我不清楚 arg() 的一般替代品是什么。下面的代码使用两种技术来获取分类术语 id。

您可能想在开发过程中关闭视图中的缓存。

function myTheme_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-article-tags-block-1') {

    // initial page load
    $parameters = \Drupal::routeMatch()->getRawParameters();
    $this_term_id = $parameters->get('taxonomy_term');

    // ajax refresh via apply button
    if (!isset($this_term_id)) {
      $this_term_id = $_REQUEST['view_args'];
    }

    // get children of $this_term_id
    $tree = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree('tags', $parent = $this_term_id, $max_depth = NULL, $load_entities = FALSE);

    // get rid of all options except default
    $all_option = $form['term_node_tid_depth']['#options']['All'];
    unset($form['term_node_tid_depth']['#options']);
    $form['term_node_tid_depth']['#options']['All'] = $all_option;

    // add child terms
    foreach ($tree as $term) {
      $option = new stdClass();
      $option->option[$term->tid]=$term->name;
      $form['term_node_tid_depth']['#options'][] = $option;
    }
  } 

}