Skip to content

Drupal Taxonomy — Vocabularies, Terms and Hierarchical Classification

DodaTech Updated 2026-06-27 9 min read

In this tutorial, you'll learn Drupal's taxonomy system including creating vocabularies, managing hierarchical and flat terms, attaching taxonomy to content types, using taxonomy in Views for filtering, and best practices for content categorization.

What You'll Learn

  • What taxonomy is and the difference between vocabularies and terms
  • Creating vocabularies and configuring their settings
  • Adding terms individually and via bulk upload
  • Building hierarchical term structures with parent/child relationships
  • Attaching taxonomy reference fields to content types
  • Integrating taxonomy with Views for content filtering and listing
  • Configuring term pages, path aliases, and display

Why It Matters

Taxonomy is Drupal's built-in classification system that lets you organize and relate content in meaningful ways. Unlike simple tags in other CMS platforms, Drupal taxonomy supports hierarchical structures, custom fields on terms, and deep integration with Views, creating a powerful information architecture tool. Proper taxonomy design directly improves content findability and site navigation.

Real-World Use

A recipe website uses hierarchical taxonomy: Cuisine (Italian > Tuscan, Sicilian; Thai > Northern, Southern), Dietary (Vegetarian, Vegan, Gluten-Free, Keto), Meal Type (Breakfast, Lunch, Dinner, Dessert), and Difficulty (Easy, Medium, Hard). Editors assign multiple taxonomy terms per recipe. Views display recipe lists filtered by cuisine with dietary option toggles. The taxonomy terms have custom fields for images and descriptions.

Learning Path

flowchart LR
  A[Fields System] --> B[Taxonomy]
  B --> C[Entity System]
  C --> D[Views]
  D --> E[Media]
  E --> F[Revisions]

What is Taxonomy

In Drupal, taxonomy provides a way to classify content. There are two key concepts:

  • Vocabulary: A set of categories (like "Cuisine", "Tags", "Departments")
  • Term: An individual category within a vocabulary (like "Italian", "Thai", "Dessert")

Think of a vocabulary as a bucket and terms as the items in that bucket. Each vocabulary can have its own settings for hierarchy, field attachments, and display.

Creating a Vocabulary

Navigate to Structure > Taxonomy > Add vocabulary (or /admin/structure/taxonomy/add).

Basic Settings

  • Name: Human-readable name, e.g., "Article Categories"
  • Description: Explain the vocabulary's purpose
  • Machine name: Auto-generated from name, e.g., article_categories

Vocabulary Settings

  • Hierarchical: Enable to allow parent/child relationships between terms. Disable for flat, tag-like vocabularies.
  • Tags: Enable tag-style input on content forms. Editors can type new terms directly without leaving the content form.

Example: Creating a "Department" Vocabulary

Name: Department
Machine name: department
Description: 'Departments within the organization'
Hierarchical: true
Tags: false

Adding Terms

Manual Term Creation

Navigate to Structure > Taxonomy > List terms for your vocabulary > Add term.

Term fields include:

  • Name: The term text displayed to users
  • Description: Optional description rich text
  • Parent: For hierarchical vocabularies, select the parent term
  • Weight: Controls sort order in term listings
  • URL alias: Optional custom path (requires Pathauto module)
# Add a term using Drush
drush php:eval "
  $term = \Drupal\taxonomy\Entity\Term::create([
    'name' => 'Engineering',
    'vid' => 'department',
    'parent' => 0,
  ]);
  $term->save();
  echo 'Term created with ID: ' . $term->id();
"

Bulk Term Upload

For adding many terms at once, use the taxonomy_csv module or custom CSV import:

<?php

use Drupal\taxonomy\Entity\Term;

function import_terms_from_csv($csv_file, $vocabulary_id) {
  $rows = array_map('str_getcsv', file($csv_file));
  $header = array_shift($rows);

  foreach ($rows as $row) {
    $term = Term::create([
      'name' => $row[0],
      'vid' => $vocabulary_id,
      'description' => $row[1] ?? '',
      'parent' => $row[2] ?? 0,
    ]);
    $term->save();
  }
}

Term Hierarchy

When a vocabulary is hierarchical, terms can have parent/child relationships. This creates a tree structure.

Example: Geography Vocabulary

Geography
├── North America
│   ├── United States
│   │   ├── New York
│   │   ├── California
│   │   └── Texas
│   └── Canada
│       ├── Ontario
│       └── British Columbia
├── Europe
│   ├── United Kingdom
│   ├── France
│   └── Germany
└── Asia
    ├── Japan
    ├── China
    └── India

Setting Parents

When adding or editing a term, use the Parent selection to set its parent:

  • Top-level terms: Select <root>
  • Child terms: Select the parent term

Using Hierarchy in Views

Hierarchical vocabularies allow drill-down navigation:

  • List all terms "under" North America (including United States, New York, etc.)
  • Show breadcrumb showing current term's ancestry

Taxonomy Field on Content Types

To associate taxonomy with content, add an Entity Reference field pointing to taxonomy terms.

Add the Field

  1. Navigate to Structure > Content types > Manage fields > Add field
  2. Select "Taxonomy term" under Reference or "Entity reference"
  3. Configure:
    • Label: "Categories"
    • Machine name: field_categories
    • Reference type: Taxonomy term
    • Vocabulary: Select the vocabulary
    • Widget: Autocomplete, Select list, or Checkboxes

Widget Settings

# Configuration for tag-style input
Field: field_tags
Widget: Autocomplete (tag style)
Settings:
  match_operator: CONTAINS
  size: 60
  placeholder: 'Start typing to add tags'
# Configuration for select list with hierarchy
Field: field_category
Widget: Select list
Settings:
  size: 1  # single select; use multiple for unlimited
  placeholder: '- Select a category -'

Views Integration

Taxonomy integrates deeply with Views for powerful content filtering.

Taxonomy Term View

Views can filter content by taxonomy terms:

# View configuration for filtering by term
Filter criteria:
  - field_tags_target_id:
      id: field_tags_target_id
      table: node__field_tags
      field: field_tags_target_id
      relationship: none
      operator: '='
      value:
        - 42  # Term ID

Exposed Filters

Create user-facing taxonomy filters:

# Exposed filter by taxonomy
Filter criteria:
  - field_tags_target_id:
      exposed: true
      expose:
        label: 'Filter by category'
        operator: 'or'
        multiple: true

Taxonomy Term Views

Display content associated with a specific term:

  1. Create a new View of type "Taxonomy term"
  2. Add fields from the related content
  3. Contextual filter automatically passes the current term ID
# Contextual filter for taxonomy term view
Contextual filters:
  - tid:
      id: tid
      table: taxonomy_term_data
      field: tid
      title: 'Posts in %1'
      default_argument_type: taxonomy_tid
      specifier: 'tid'

Taxonomy Term Page

Each taxonomy term automatically has a page at /taxonomy/term/{tid}. This page can be overridden by a View:

  1. Go to Structure > Views
  2. Find the "Taxonomy term" View
  3. Configure the Page display
  4. Set path to /taxonomy/term/%

Term Display

Configuring Term Fields

Taxonomy terms can have custom fields, just like nodes:

  1. Navigate to Structure > Taxonomy > Manage fields for your vocabulary
  2. Add fields (e.g., Term image, Description, Color code, Icon)
  3. Configure form display and view display
# Adding an image field to a taxonomy vocabulary
Field: field_term_image
Type: Image
Widget: Image upload
Formatter: Image with image style
Usage: Display term image on term page and in Views

Term Page Template

Override term page theming with Twig:

{# templates/taxonomy-term.html.twig #}
<article class="term">
  <h1>{{ term.name.value }}</h1>

  {% if term.field_term_image.value %}
    <div class="term-image">
      {{ content.field_term_image }}
    </div>
  {% endif %}

  <div class="term-description">
    {{ content.description }}
  </div>
</article>

Term Path Aliases

With the Pathauto module, taxonomy terms can have clean URL aliases:

# Pathauto pattern for taxonomy terms
Pattern: /[vocabulary:machine-name]/[term:name]
Example: /department/engineering
         /geography/north-america/united-states/new-york

Configure at Configuration > URL aliases > Patterns.

REST Export of Taxonomy

Taxonomy terms can be exposed via REST API:

# Fetch taxonomy terms via REST
curl https://example.com/taxonomy/term/42?_format=json
{
  "tid": [{ "value": 42 }],
  "name": [{ "value": "Engineering" }],
  "vid": [{ "target_id": "department" }],
  "description": [{ "value": "Engineering department employees" }],
  "parent": [{ "target_id": 0 }],
  "path": [{ "alias": "/department/engineering" }]
}

Common Mistakes

  1. Creating multiple flat vocabularies when a hierarchical one would be better: Instead of "Technology" and "Technology > Web Development" as separate vocabularies, create one hierarchical "Technology" vocabulary.
  2. Not using taxonomy for structured data that could be categorized: When you find yourself creating similar content repeatedly, ask if taxonomy would provide better organization and filtering.
  3. Creating deep hierarchies that confuse editors: More than three levels of hierarchy becomes hard to navigate in admin forms. Limit to three levels for usability.
  4. Not adding fields to taxonomy terms: Terms are entities that can have images, descriptions, colors, and other metadata. Use this to display rich category pages.
  5. Allowing duplicate terms with tag-style widgets: When using tag-style input, train editors to search before creating new terms. Use the "Tags" vocabulary setting with caution in large teams.

Practice Questions

  1. What is the difference between a vocabulary and a term in Drupal taxonomy?
  2. How would you set up taxonomy for a blog with categories (hierarchical: Technology > Web Development > PHP, Technology > Mobile > iOS) and tags (flat, non-hierarchical)?
  3. How do you display all content associated with a taxonomy term, including child terms in hierarchical vocabularies?
  4. Challenge: Build a complete taxonomy system for a news website with the following requirements: Sections (hierarchical: News > Local, National, World; Opinion > Editorials, Columns), Topics (flat: Health, Education, Environment, Technology, Sports), and Tags (flat, tag-style input with unlimited term creation). Each Section term needs an image field and description. Create Views for section landing pages showing the latest 10 articles in that section and its subsections. Configure Pathauto patterns for clean URLs.

FAQ

What is the difference between taxonomy and content types?

Content types define the structure of individual content items (what fields they have). Taxonomy provides categorization and classification. They work together: a content type has a taxonomy reference field that links it to one or more taxonomy terms.

Can a term belong to multiple vocabularies?

No, each taxonomy term belongs to exactly one vocabulary. If you need similar terms in different contexts, create separate vocabularies. For example, 'Python' could be in both a 'Programming Languages' vocabulary and a 'Course Subjects' vocabulary.

How do I create a tag cloud from taxonomy terms?

Use the Views module to create a tag cloud. Create a View showing taxonomy terms, use the 'Weight' as the sorting mechanism, and style it as an HTML list. Add CSS to vary font size based on term weight or content count.

What is the maximum number of terms I can have?

Drupal can handle millions of taxonomy terms without performance issues, provided the database is properly indexed. For very large vocabularies (50,000+ terms), use autocomplete widgets instead of select lists to avoid page load issues.

Can I import taxonomy terms from a CSV file?

Yes. Use the contributed taxonomy_csv module for direct CSV import, or write a custom Drush command using the entity API: Drupal\\taxonomy\\Entity\\Term::create() within a loop reading CSV rows.

Mini Project

Goal: Build a complete taxonomy-driven content architecture for a job board.

  1. Create three vocabularies:
    • Industry: Hierarchical (Technology > Software, Hardware; Healthcare > Medical, Dental; Finance > Banking, Insurance)
    • Job Type: Flat (Full-Time, Part-Time, Contract, Freelance, Internship)
    • Skills: Tag-style (flat, unlimited, auto-create: PHP, Python, JavaScript, Project Management, Design)
  2. Add fields to Industry terms:
    • Industry Icon (Image)
    • Industry Description (Text formatted)
  3. Create a Job Posting content type with taxonomy reference fields:
    • field_industry (single select from Industry vocabulary)
    • field_job_type (single select from Job Type vocabulary)
    • field_skills (multiple tags from Skills vocabulary)
  4. Create a View: "Jobs by Industry" showing each Industry term with a count of jobs
  5. Create a View: "Jobs page" with exposed filters for Industry, Job Type, and Skills
  6. Configure Pathauto patterns: /jobs/{field_industry}/{node:title}

What's Next

Taxonomy is part of Drupal's powerful entity system. Dive deeper into the entity system to understand how content entities, config entities, and the entity API work together. Then build dynamic listings with the Views module.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro