Profile picture for user admin
Daniel Sipos
02 Sep 2013

In this article I will show you how to programmatically create new taxonomy vocabularies and terms to go with them. Say the module you are building has some functionality that relies on the Drupal core Taxonomy module. Obviously you can’t expect people to create their own vocabularies to work with your module so upon enabling it these should already be there.

A taxonomy vocabulary in Drupal (just like a term inside it) is an object that needs to be defined and persisted to the database. In this tutorial we will programmatically define such a vocabulary and save it to the database. Then we will define a term to go in it and save it as well.

When doing custom Drupal development we use many times hooks to tap into the normal Drupal functionalities and add our own stuff. Hooks are basically functions that get called at various times by either Drupal core or other modules. However, since we need to define and save our vocabulary only once, we will need to find the right hook to perform this action. Meet hook_install().

This hook gets called only once in the lifetime of your module - upon enabling the first time (or after you uninstalled the module). Another thing you should know about this hook is that you have to implement it in an .install file - not the .module file like most other hooks.

OK, so now that we have our .install file created an opened up, let’s implement hook_install():

/**
 * Implements hook_install().
 */
function my_module_install() {
}

Inside this function we’ll put all the code that defines and persists our vocabulary and taxonomy term. And since it gets called only once, we can be sure they will be added only once. So first, let’s declare our vocabulary object and save it to the database:

 $new_vocab = (object) array(
   'name' => 'My custom vocabulary',
   'description' => 'This vocabulary has a special purpose',
   'machine_name' => 'my_custom_vocab',
 );  
taxonomy_vocabulary_save($new_vocab);

This is it. When this code runs, the vocabulary with that title and description gets added to the database. There are some more options you can specify in the object that I encourage you to explore on the taxonomy_vocabulary_save() function API page. But now that we have the vocabulary set, let’s create a taxonomy term and add it to the newly created vocabulary. Below the code from above but still inside the hook_install() implementation, add the following:

$vocab = taxonomy_vocabulary_machine_name_load('my_custom_vocab');
  
$term1 = (object) array(
 'name' => 'Term 1',
 'description' => 'This is term 1',
 'vid' => $vocab->vid,
);

taxonomy_term_save($term1);

So what happens here? First, we need to retrieve the vocabulary we just created as we need its id. We basically then have the whole object in $vocab. Next, we define the term and specify some basic options, the most important being the id of the vocabulary we want to add it to - which we can find in the vid property of $vocab. Then we just save the term with the taxonomy_term_save() function that I again encourage you to check out for more information about the options you have.

And this is it. You can save the file and when you enable the newly created module the vocabulary and taxonomy term should be created. What happens if you disable the module you ask? Nothing, they will remain in the database. What happens if you re-enable the module you ask? Again nothing. So what do you do if you want to have the vocabulary removed when someone doesn't want to use the module anymore?

You have 2 choices. You either use hook_uninstall() and have the vocabulary removed when the module is being uninstalled, or you use hook_disable() and have it removed when the module is being disabled. It’s up to you but the first option is recommended as it will make sure people do not lose the vocabulary terms and their associations from a simple module disable. They would have to properly uninstall the module for this to happen. So how to do this in practice? Below the function you wrote previously (and still in the .install file) you can write something like this:

/**
 * Implements hook_uninstall().
 */
function my_module_uninstall() {
  $vocab = taxonomy_vocabulary_machine_name_load('my_custom_vocab');
  taxonomy_vocabulary_delete($vocab->vid);
}

This hook gets called whenever you uninstall this module and it finds your vocabulary and deletes it. So what will you have in the end? Someone enables your module for the first time and the vocabulary gets created. Then the module gets disabled but the vocabulary stays in the database. Now if the module gets re-enabled nothing will happen to the vocabulary but if it gets uninstalled, it will be deleted. Simple!

I hope this helps you somewhat with your Drupal 7 module development.

Profile picture for user admin

Daniel Sipos

CEO @ Web Omelette

Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.

Contact us

Comments

Kabenla Armah 26 Dec 2013 18:09

where does the .install file go?

I am really new to drupal development and I really appreciate your tutorial. My question is where should I put the .install file that I create. Is it in a module of its own, or should I put it in another modules folder

Thanks
Kabenla Armah

Dan 10 Jan 2014 07:50

Thanks!

I was looking exactly for this, thanks for this clear and thorough tutorial!

petu 23 Sep 2014 06:15

You'd better add 'See more' feature as a comment

Thanks for the manual!

It's better add
"// See more at: http://www.webomelette.com/taxonomy-vocabulary-term-programatically-drupal-7#sthash.dBcQsA1u.dpuf"

instead of

"- See more at: http://www.webomelette.com/taxonomy-vocabulary-term-programatically-drupal-7#sthash.dBcQsA1u.dpuf"

In first case no need to remove the addition ;).

Arun 29 Oct 2014 07:53

FieldException

FieldException: Attempt to create an instance of a field field_my_custom_vocab that doesn't exist or is currently inactive. in field_create_instance()
I'm getting this error. Please help

Tyler 25 Jul 2016 14:19

Awesome tut

Hey man, thanks for posting this, much appreciated, I actually was able to implement the same code in a module file in a hook_presave function to programmatically create taxonomy when saving content. Cheers!

Ivan 18 Nov 2016 01:59

Terms inside terms

Great example! How can you add a two level of terms? like: Vocabulary > Term > Term

tc 27 Jan 2020 20:52

adding additional terms to vocabulary during module update

If, when updating this module, I need to add or delete terms for a vocabulary. How would I go about doing that?

Add new comment