I need to create a taxonomy with an entry for every living language in the world (nearly 7,000, using ISO 639-3 codes: http://en.wikipedia.org/wiki/List_of_ISO_639-3_codes). Note that the ISO 639-3 code is stored as a custom field.

In light of this: what is the easiest way to create this list directly via MySQL using a PHP (or other) script?

I have attempted to directly create entries by inserting values directly into MySQL:

INSERT INTO taxonomy_term_data (vid, name, description, format) VALUES (2,"Ghotuo","<p><em>Africa</em></p>","filtered_html");

INSERT INTO field_data_field_iso_639_3 (entity_type, bundle, entity_id, revision_id, language, delta, field_iso_639_3_value) VALUES ("taxonomy_term", "language", 3, 3, "und", 0, "aaa");

INSERT INTO url_alias (source, alias, language) VALUES ("taxonomy/term/3", "language/ghotuo", "und");

I am obviously missing something, because this entry is not seen by Drupal in the "Languages" taxonomy.

I have looked at this question but am unsure how to set this up as a stand-alone PHP script (not incorporated into the site itself).

Any ideas how to programmatically create this taxonomy? TIA.

  • 2
    You could just dump the data in a CSV and let Taxonomy CSV import/export do the heavy lifting for you... – Clive Feb 18 '13 at 18:12
  • Clive, thank you! This looks like it will do exactly what I need. – cyboreal Feb 18 '13 at 20:12

Myself still learning how to properly write modules, I managed to come up with the following code for saving the terms into separate table named MODULENAME_data. It may not be perfect - but it apparently worked. I'm open to downvoting, but even more to suggestions on how to improve it.

// Make the table name a constant for easier coding
// We will store it's vid as system variable after we have created it
define("MODULENAME_VOCAB_MACHINE_NAME", "iso_639_3_codes_data");

function MODULENAME_enable(){
  // Create the vocabulary.
  $vocab = array(
    'name' => 'Vocabulary name',
    'machine_name' => MODULENAME_VOCAB_MACHINE_NAME,
    'description' => t('Vocabulary of iso 639-3 language codes'),
    'module' => 'taxonomy',
    'hierarchy' => 0,
    'module' => 'MODULENAME',
  taxonomy_vocabulary_save( (object) $vocab);

  // Now that we've created the vocabulary, let's store its vid as a system variable
  $vocab = taxonomy_vocabulary_machine_name_load(MODULENAME_VOCAB_MACHINE_NAME);
  $vid = $vocab->vid;
  variable_set('MODULENAME_vocab_id', $vid);

  // Create custom field.
  $field = array(
    'field_name' => 'field_custom_field',
    'type' => 'text',
    'label' => t('Symbol') // where is that used? I dunno, but API says so ;-)

  // Create field instance on the vocab
  $instance = array(
    'field_name' => 'field_custom_field',
    'entity_type' => 'taxonomy_term',
    'label' => t('Custom field'),
    'description' => t('Description'),
    'required' => true,
    'widget' => array(
      'type' => 'text_textfield',

  // Here you would include an include file that provides row data
  // (probably an array) and then iterate over it to populate table
  // such as

      // Save terms.
      foreach ($items as $item) {
        taxonomy_term_save((object) array(
          'name' => $item[0],
          'vid' => $vid, 
          'field_custom_field' => array(
            LANGUAGE_NONE => array(
              0 => array(
                'value' => $item[1] ,


function MODULENAME_disable(){
  // Some system cleanup.

  // Delete vocabulary. This deletes terms and field references too.

  // Delete variable from system.

Word of comment:

  1. I'm still not sure whether the hook_disable() would be supposed to do what I put into it, but my understanding is that once a module is disabled, the features installed by it would be supposed to be unavailable too. I'm unsure about the field references - not only do they remain in the system in my code, but once we re-enable the module, the references will not be restored due to new IDs.

  2. I'm also not sure how one would make the vocabulary i18n-savvy, meaning - when you would like to install the vocabulary along with translations - vocabularies provide several i18n modes and I'm not in the knowledge how to support them programatically.

This is something I would love to learn from someone.

| improve this answer | |
  • 1
    You probably shouldn't call taxonomy_vocabulary_machine_name_load() to know actual vid, it must be available right after taxonomy_vocabulary_save(). – volocuga Oct 30 '13 at 13:50
  • The deletions you're doing in hook_disable() should be done in hook_uninstall() instead. – Sam Wilson Dec 10 '14 at 0:48

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.