14

I wanted to retrieve taxonomy terms from a certain vocabulary in Drupal 8.

Apparently I can still do it using taxonomy_get_tree but it's deprecated.

I now have to use TermStorageInterface::loadTree

I am trying to access this function from a Block but I don't understand how to instantiate the TermStorageInterface class.

I tried accessing the function directly but it's not a static function :

TermStorageInterface::loadTree('categories')

I tried instantiating the class but it told me Cannot instantiate interface Drupal\taxonomy\TermStorageInterface

$test = new TermStorageInterface();

I don't understand how this class works and how I can access taxonomy links. I think I'm missing a big part of understanding how Drupal works.

10 Answers 10

37

Replacing a deprecated function is in most cases trivial. Just look at it. There you can see this:

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

If you are looking for a function that was already removed, search for it on Change records for Drupal core page. Pretty much every function that was removed should have more or less (usually more) detailed instructions on how to do it in Drupal 8 instead.

The storage class is an entity storage handler, that you get through the entity manager. In general, 99% of the classes in D8 are not meant to be created yourself, but as a service, or entity handler, plugin.

For example:

$vid = 'vocabulary_name';
$terms =\Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
foreach ($terms as $term) {
 $term_data[] = array(
  'id' => $term->tid,
  'name' => $term->name
 );
}
  • Great, thank you. Although I don't understand where you found that line of code? – Romain Braun Jan 13 '15 at 23:13
  • As I said, that is copied straigt from taxonomy_get_tree(). A deprecated function means there is a new way to do something, but the old function still has to work. – Berdir Jan 13 '15 at 23:44
  • Oh ok. Awesome. I see it now. Thank you very much for your help! – Romain Braun Jan 13 '15 at 23:46
  • Now its not working, I have changed the deprecated function to entityTypeManager, but after getStorage i am not getting loadTree. – Bhanu Prakash Ryaga Apr 28 '16 at 15:48
  • 2
    @usethe23 Implement what? This is just about replacing a deprecated function call with the new approach. It doesn't do anything that it didn't already before. You probably need to create a new question and describe what you want to do. – Berdir Dec 19 '16 at 18:37
8

This is what I use to create a list of tags:

  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;
  • I searched like half an hour for this... it's so complicated and doesnt make sense... and what if I want just the URL alias of the taxonomy term, how do I get that? – Raf A. Dec 6 '17 at 14:41
  • 1
    Hi Raf. I decided to post this, because I also had a hard time to get to such a simple task as this. To just get the alias: $url = Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $term->id()]); – Stef Van Looveren Dec 11 '17 at 8:54
5

The error you are getting is because you are trying to create an instance of an interface, which is not something PHP allows. PHP interfaces describe the methods classes should implement for specific cases, but they cannot be used to create an object, for example with new InterfaceName().

Now that taxonomy_get_tree() has been removed, and the entity manager service has been deprecated, you need to use the following code.

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

There is not need to use \Drupal::getContainer() since \Drupal exposes a helper method to get the entity type manager service.

3

Load using machine name of the vocabulary (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() is now deprecated so this worked for me

$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 is deprecated because is got split into 11 classes - drupal.org/node/2337191 - so use \Drupal::entityTypeManager instead and you should be good. – ognockocaten Apr 12 '16 at 20:52
  • Anytime you have to loadMultiple and loop until you get the specific one you want, I call that shitty code fwiw – AlxVallejo Jan 23 '18 at 19:43
2

I've just wrote a function, feel free to edit and use :) I needed the id of the term, but you can return whatever you want.

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);}
    }
}
  • I might be wrong, but this appears not to be entirely right. $query->condition after $query->execute() has no effect. Also if the first term is not the right one, the foreach will return null rather than checking the next term. (For your use case, you might be able to use taxonomy_term_load_multiple_by_name instead?) – Neograph734 Sep 5 '17 at 22:09
  • Ops, yes sorry I copied old code sorry, I edit it – Czeglédi Dávid Sep 6 '17 at 7:15
  • Well and yes, other way is right, as you said, for that better to use that. – Czeglédi Dávid Sep 6 '17 at 7:20
1

If you need term entity, you can use 'loadByProperties()'.

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

Here is the D8 example how to access taxonomy terms based on the vocabulary machine name:

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

To load the whole entities, use: loadTree('categories', 0, NULL, TRUE).

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);
-2

You can see full description here https://drupaltreasure.blogspot.com/2017/04/drupal-8-get-list-of-all-voacbs.html

  • 1
    Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. – mpdonadio Jun 23 '18 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.