获取分类条款


17

我想从Drupal 8中的某个词汇表检索分类术语。

显然,我仍然可以使用它,taxonomy_get_tree但已弃用。

我现在必须使用TermStorageInterface :: loadTree

我正在尝试从a访问此函数,Block但我不了解如何实例化TermStorageInterface该类。

我尝试直接访问该函数,但这不是静态函数:

TermStorageInterface::loadTree('categories')

我尝试实例化课程,但它告诉了我 Cannot instantiate interface Drupal\taxonomy\TermStorageInterface

$test = new TermStorageInterface();

我不了解此类的工作方式以及如何访问分类链接。我想我缺少了解Drupal的工作原理的很大一部分。

Answers:


38

在大多数情况下,替换不推荐使用的功能很简单。看看吧。在这里您可以看到:

\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, $parent, $max_depth, $load_entities);

如果要查找已被删除的功能,请在Drupal核心页面的更改记录中搜索它。在Drupal 8中,几乎所有被删除的功能都应或多或少(通常是更多)具有详细的说明。

存储类是一个通过实体管理器获取的实体存储处理程序。通常,D8中99%的类不是要自己创建的,而是要作为服务或实体处理程序的插件来创建的。

例如:

$vid = 'vocabulary_name';
$terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
foreach ($terms as $term) {
 $term_data[] = array(
  'id' => $term->tid,
  'name' => $term->name
 );
}

太好了谢谢。虽然我不明白您在哪里找到那行代码?
罗曼·布劳恩

如我所说,这是从taxonomy_get_tree()复制的。不推荐使用的功能意味着有一种新的方式可以执行某些操作,但是旧功能仍然必须起作用。
贝尔迪尔

哦好的。太棒了 我现在看到了。非常感谢您的帮助!
罗曼·布劳恩

现在它不起作用,我将不推荐使用的功能更改为entityTypeManager,但是在getStorage之后,我没有得到loadTree。
Bhanu Prakash Ryaga

2
@ usethe23实施什么?这只是用新方法替换不推荐使用的函数调用。它没有做任何以前没有做过的事情。您可能需要创建一个新问题并描述您想做什么。
贝尔迪尔

9

这是我用来创建标签列表的方法:

  use Drupal\taxonomy\Entity\Term;      
  use Drupal\Core\Link;
  use Drupal\Core\Url;

  $vocabulary_name = 'YOUR_VOCABULARY_NAME'; //name of your vocabulary
  $query = \Drupal::entityQuery('taxonomy_term');
  $query->condition('vid', $vocabulary_name);
  $query->sort('weight');
  $tids = $query->execute();
  $terms = Term::loadMultiple($tids);
  $output = '<ul>';
  foreach($terms as $term) {
      $name = $term->getName();;
      $url = Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $term->id()]);
      $link = Link::fromTextAndUrl($name, $url);
      $link = $link->toRenderable();
      $output .='<li>'.render($link).'</li>';
  }
  $output .= '</ul>';
  print $output;

我为此花了半个小时的时间进行搜索...它是如此复杂且没有意义...如果我只想要分类法术语的URL别名该怎么办?
Raf A.

1
嗨Raf。我决定发布此内容,因为我也很难完成这样的简单任务。只是得到别名:$ url = Url :: fromRoute('entity.taxonomy_term.canonical',['taxonomy_term'=> $ term-> id()]);
Stef Van Looveren

5

您得到的错误是因为您试图创建接口实例,而PHP不允许这样做。PHP接口描述了类在特定情况下应实现的方法,但不能用于创建对象,例如使用new InterfaceName()

现在taxonomy_get_tree()已将其删除,并且不赞成使用实体管理器服务,您需要使用以下代码。

$terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, $parent, $max_depth, $load_entities);

\Drupal::getContainer()由于\Drupal公开了一个帮助程序方法来获取实体类型管理器服务,因此无需使用。


3

使用词汇表的机器名称(vid)进行加载:

  $vid = 'name_of_your_vocabulary';
  $terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
  foreach ($terms as $term) {
   $term_data[] = array(
    "id" => $term->tid,
    "name" => $term->name
   );
   dpm($term_data);
  }

2

\ Drupal :: entityManager()现在已弃用,因此这对我有用

$vids = Vocabulary::loadMultiple();
foreach ($vids as $vid) {
  if ($vid->label() == 'YourVocab') {
    $container = \Drupal::getContainer();
    $terms = $container->get('entity.manager')->getStorage('taxonomy_term')->loadTree($vid->id());
    if (!empty($terms)) {
      foreach($terms as $term) {
        dsm($term->name);
      }
    }
    break;
  }
}

1
不推荐使用EntityManager,因为它被划分为11个类-drupal.org/node/2337191-因此请改用\ Drupal :: entityTypeManager,您应该会很好。
ognockocaten

每当您必须loadMultiple并循环执行,直到获得所需的特定代码时,我都称其为糟糕的代码
AlxVallejo

2

我刚刚编写了一个函数,随时可以编辑和使用:)我需要该术语的ID,但是您可以返回所需的任何值。

function checkTaxonomyTerm($vocab_name, $term_name){
    $query = \Drupal::entityQuery('taxonomy_term');
    $query->condition('vid', $vocab_name);
    $tids = $query->execute();
    $terms = Term::loadMultiple($tids);
    foreach($terms as $term) {
        $name = $term->getName();
        if($name == $term_name) {
            print_r($term->id());
            if (is_null($term->id())) {
                return null;
            }
            else{
                return array(true, $term->id());
            }
        }
        else {return addTaxonomyTerm($term->getVocabularyId(), $name);}
    }
}

我可能是错的,但这似乎并不完全正确。$query->condition之后$query->execute()没有效果。同样,如果第一项不是正确的项,则foreach将返回null而不是检查下一项。(对于您的用例,您也许可以改用taxonomy_term_load_multiple_by_name?)
Neograph734'9

行动,是的,对不起我复制旧的代码对不起,我编辑它
Czeglédi戴维

是的,是的,正如您所说,其他方法是正确的,以便更好地使用它。
CzeglédiDAVID

1

这是D8示例,如何基于词汇机器名称访问分类术语:

$terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadTree('categories');
foreach ($terms as $term) {
  //$value = $term->get('field_example')->getValue();
  var_dump($term);
}

要加载整个实体,请使用:loadTree('categories', 0, NULL, TRUE)


1

如果需要术语实体,则可以使用“ loadByProperties()”。

$vid = 'vocabulary_name';
/** @var \Drupal\taxonomy\Entity\Term[] $terms */
$terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties(['vid' => $vid]);

这是正确的答案。谢谢。
Stef Van Looveren

0
$vid = 'MACHINE_NAME_OF_VACABULARY';
$parent_tid = 0;//parent id
$depth = 2; //depth upto which level you want 
$load_entities = FALSE;
$tree = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid, $parent_tid, $depth, $load_entities);

foreach ($tree as $term) {
     $treeNames[] = array(
      'name' => $term->name
     );
}
dump($treeNames);

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.