How to save a node with multiple taxonomy terms

I did some quick research on how to save taxonomy attached to your node. In my case I needed it in a page where I create 3 dummy nodes. This post explains how you can approach attaching several taxonomy terms (from different vocabulary) while calling node_save blow up jumpers. You could avoid using this function and work with the taxonomy instead, but I prefer the node way.

Trying out some taxonomy functions

I first had one taxonomy vocabulary attached to the node-type. After a quick search, this is what I came up with:

  1. global $user;
  2. foreach($dummies as $dummy) {
  3.   $node = new StdClass();
  4.   $node->format = 1;
  5.   $node->language = ‘en’;
  6.   $node->uid = $user->uid;
  7.   $node->type = ’slideshow’;
  8.   $node->title = $dummy[‘title’];
  9.   $node->body = ‘A little explanation on this slideshow.’;
  10.   // my custom fields
  11.   $node->num_slides = $dummy[‘num_slides’];
  12.   // save the node
  13.   node_save($node);
  14.   // Sets taxonomy relation terms
  15.   $term = taxonomy_get_term_by_name($dummy[‘language_tag’]);
  16.   taxonomy_node_save($node, $term);
  17.   $term2 = taxonomy_get_term_by_name($dummy[‘region’]);
  18.   taxonomy_node_save($node, $term2);
  19. }

This did not work, the second had overwritten the first taxonomy association. Looking in the code of taxonomy_node_save, I noticed that it is possible to use the term parameter as array, as one single array of a term or a term object. As the function taxonomy_get_term_by_name returns an array of terms, also if you expect it to be just one.
Trying this:

  1. $term = taxonomy_get_term_by_name($dummy[‘language_tag’]);
  2. $term2 = taxonomy_get_term_by_name($dummy[‘regions’]);
  3. // this will overwrite the previous
  4. taxonomy_node_save($node, array($term[0],$term2[0]));
  5. // this will give duplicate entries
  6. // taxonomy_node_save($node, array($term,$term2));

That said, looking even closer at the code in taxonomy_node_save, It is clear that (if not using the tag attribute of term, the only thing that is being done there is a simple database query. More precisely, insert into term node table.
The easy sollution is to perform this action yourself inflatable waterslides. Easier and faster. The only bad argument you can say about this, is that if the taxonomy functions code changes, you are screwed :) .
The code for this:

  1. $term = taxonomy_get_term_by_name($dummy[‘language_tag’]);
  2. $term2 = taxonomy_get_term_by_name($dummy[‘regions’]);
  3. //taxonomy_node_save($node, array($term,$term2));
  4. db_query(‘INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)’, $node->nid, $node->vid, $term[0]->tid);
  5. db_query(‘INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)’, $node->nid, $node->vid, $term2[0]->tid);

The way to go

This did the job and if I looked at the edit for that created “slideshow”, the vocabulary was prefilled nicely. The both of them this time. I was still not satisfied because my first thought was to save this through the node object directly. I decided to google some more. After a while a came upon this page.

  1. $term = taxonomy_get_term_by_name($dummy[‘language_tag’]);
  2. $term2 = taxonomy_get_term_by_name($dummy[‘regions’]);
  3. $node->taxonomy = array($term[0]->tid, $term2[0]->tid);
  4. node_save($node);

And that is! Easy enough.

This entry was posted on Sunday, September 21st, 2008 at 3:45 pm and is filed under Drupal. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

2 Responses to “How to save a node with multiple taxonomy terms”

  1. akahn Says:

    What if you are trying to assign an arbitrary string as a free-tagging term (in other words, using a term that hasn’t been created yet)? How do you assign that in the $node->taxonomy = line?

  2. italia-live Says:

    does this code work with tags?