Drupal 8 - Taxonomie-Menü mit Hierarchie

7

Ich habe eine Weile gesucht und konnte nichts im Zusammenhang mit Drupal 8 finden. Es gibt Module wie das Taxonomie-Menü, aber leider nicht für Drupal 8, das entsprechend funktioniert.

Gibt es bereits eine Lösung, um ein Menü aus den Taxonomiebegriffen für Drupal 8 ohne individuelle Entwicklung (PHP usw.) zusammenzustellen?

Außerdem habe ich festgestellt, dass ich beim Erstellen eines Taxonomiebegriffs und beim Erstellen einer Referenz aus einem Inhalt keine Übersicht über den mit dem Begriff verknüpften Inhalt erhalte.

Hoffe, mein Punkt ist klar.

Sam
quelle
Es gibt noch nichts, nein - D8 ist noch in der Beta, nicht vergessen
Clive
Das Taxonomie-Menü hat jetzt eine D8-Version.
Akrosman
@Clive die Jungs bei taxonomy_menu könnten eine gute Hilfe gebrauchen! :)
Alex

Antworten:

5

Ich brauchte das Gleiche. Leider gibt es noch nichts dafür, so dass ich vorerst etwas schaffen musste. Es ist nicht schön, aber es funktioniert, also ist es mir egal.

/**
 * Returns renderable array of taxonomy terms from Categories vocabulary in
 * hierarchical structure ready to be rendered as html list.
 *
 * @param int $parent
 *   The ID of the parent taxonomy term.
 *
 * @param int $max_depth
 *   The max depth up to which to look up children.
 *
 * @param string $route_name
 *   The name of the route to be used for link generation.
 *   Taxonomy term(ID) will be provided as route parameter.
 *
 * @return array
 */
function mymodule_categories_tree($parent = 0, $max_depth = NULL, $route_name = 'mymodule.category.view') {
  // Load terms
  $tree = \Drupal::entityManager()->getStorage('taxonomy_term')->loadTree('categories', $parent, $max_depth);

  // Make sure there are terms to work with.
  if (empty($tree)) {
    return [];
  }

  // Sort tree by depth so we can easily find out the deepest level
  uasort($tree, function($a, $b) {
    // Change objects to array
    return \Drupal\Component\Utility\SortArray::sortByKeyInt((array) $a, (array) $b, 'depth');
  });

  // Get the value of the deepest term
  $deepest = end($tree);
  $deepest = $deepest->depth;

  // Create a structured array
  $list = [
    $parent => [
      'items' => [],
      'depth' => -1
    ]
  ];
  foreach ($tree AS $term) {
    $list[$term->tid] = (array) $term;
  }

  // See if we're on a node page and if so open the menu
  // on the proper position.
  $node = \Drupal::request()->attributes->get('node');
  if ($node) {
    $categories = $node->get('categories')->getValue();
    // Go through each category to find out the least deep one.
    // That one will be the one we'll open.
    $open_category = $parent;
    foreach ($categories AS $target) {
      $tid = $target['target_id'];
      if ($list[$tid]['depth'] > $list[$open_category]['depth']) {
        $open_category = $tid;
      }
    }
  } else {
    // See if we're on a term page and set the corresponding item
    // as active so we don't have to rely on JS.
    $term = \Drupal::request()->attributes->get('taxonomy_term');
    if ($term) {
      $open_term = $term->id();
    }
  }

  for ($i = $deepest; $i >= 0; $i--) {
    foreach ($list AS $term) {
      if ($term['depth'] == $i) {
        $item = [
          '#type' => 'link',
          '#weight' => $term['weight'],
          '#title' => $term['name'],
          '#url' => Url::fromRoute($route_name, ['taxonomy_term' => $term['tid']]),
          '#options' => [
            'set_active_class' => TRUE
          ]
        ];
        // If we're on a node page and this category was chosen
        // as active, set the link's class.
        if (isset($open_category) && $open_category == $term['tid']) {
          $item['#attributes']['class'][] = 'active';
        }
        // If we're on term page, set the link's class to 'active'
        // and if this item is a parent, open it.
        if (isset($open_term) && $open_term == $term['tid']) {
          $item['#attributes']['class'][] = 'active';
          if (!empty($term['items'])) {
            $item['#wrapper_attributes']['class'][] = 'open';
          }
        }
        // If this item has children
        if (!empty($term['items'])) {
          $item['items'] = $term['items'];
          $item['#wrapper_attributes']['class'][] = 'parent';
          $item['#prefix'] = '<span></span>';
          // If any of the child items has 'active' class,
          // or is also a parent and has 'open' class
          // add the 'open' class to this wrapper too.
          foreach ($item['items'] AS $child) {
            if (
              isset($child['#attributes']['class']) && in_array('active', $child['#attributes']['class'])
              || isset($child['#wrapper_attributes']['class']) && in_array('open', $child['#wrapper_attributes']['class'])
            ) {
              $item['#wrapper_attributes']['class'][] = 'open';
              break;
            }
          }
        }
        foreach ($term['parents'] AS $pid) {
          $list[$pid]['items'][$term['tid']] = $item;
        }
        unset($list[$term['tid']]);
      }
    }
  }

  return [
    '#theme' => 'item_list',
    '#items' => $list[$parent]['items'],
    '#attributes' => [
      'class' => ['categories-tree']
    ],
    '#attached' => [
      'library' => [
        'mymodule/categories_tree'
      ]
    ]
  ];
}

quelle
Da ich mehr Module benötige, die in Drupal 8 nicht verfügbar sind, habe ich mich für Drupal 7 entschieden.
Sam
1

Ich habe eine SEHR grobe und fehlerreiche Version von taxonomy_menu erstellt, um ein vorhandenes übergeordnetes Menü für die anzuhängenden Begriffe festzulegen. Sie können auch eine maximale Tiefe definieren.

Ich hoffe, eines Tages wird jemand dies überprüfen und alles magisch machen.

Alex
quelle