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.
Daniel Sipos
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.
Comments
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
In reply to where does the .install file go? by Kabenla Armah (not verified)
Hey there,
Hey there,
You put the .install file in the module folder of the module for which the file is used.
D
In reply to where does the .install file go? by Kabenla Armah (not verified)
Hey there,
Hey there,
You put the .install file in the module folder of the module for which the file is used.
D
Thanks!
I was looking exactly for this, thanks for this clear and thorough tutorial!
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 ;).
In reply to You'd better add 'See more' feature as a comment by petu (not verified)
Hey there,
Hey there,
I'm not interested in that behaviour at all. It's added there I think by the ShareThis module and I will try to remove it :)
Thanks!
D
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
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!
Terms inside terms
Great example! How can you add a two level of terms? like: Vocabulary > Term > Term
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?
In reply to adding additional terms to vocabulary during module update by tc (not verified)
this does add terms, not replace terms
Now I just need to learn how to test if the term already exist so it does not get added twice.
Add new comment