Independent Editorial DeskWordPress Releases, Builds, and Operations
Back to Archive
Implementation Notes

WordPress Custom Taxonomy Example: Register Topic Tags for Structured Content

A production-ready custom taxonomy plugin example with REST support, rewrite rules, capability choices, testing steps, and SEO notes.

Published

April 17, 2026

Reading Time

4 min read

Updated

April 17, 2026

Abstract taxonomy tree diagram for organizing WordPress content relationships.
Build PatternImplementation Notes

Implementation Notes

Extension points, code paths, and implementation choices that should survive contact with production.

Best For

WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.

Primary Topics

Implementation Notes

Editorial Focus

Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on April 17, 2026.

Full Report

Last reviewed: April 17, 2026

Searches for a WordPress custom taxonomy example usually come from the same practical problem: the default categories and tags are not structured enough for the content model. A site may need product types, documentation topics, vulnerability classes, locations, industries, or editorial themes that should be queryable, visible in the editor, and stable across theme changes.

This guide shows how to register a custom taxonomy in a small plugin, attach it to posts, expose it to the block editor, and avoid the common mistakes that make taxonomy work painful later. The example is intentionally production-oriented, not only a minimal snippet for functions.php.

Who this guide is for

This article is for WordPress developers, agencies, SEO teams, and site owners who need a cleaner information architecture. If visitors, editors, or API consumers need a second classification layer beyond categories, a custom taxonomy is usually the correct tool.

When to create a custom taxonomy

Create a taxonomy when the relationship is reusable across many posts and should be used for filtering, archives, editor workflows, or REST API responses. Do not create a taxonomy just because one page needs a visual label. A taxonomy becomes part of the site’s content model, so it should describe a real editorial or product dimension.

  • Use categories for broad editorial sections.
  • Use tags for loose, general labeling.
  • Use a custom taxonomy when the labels have a specific business meaning.

Plugin example: register a topic taxonomy

The example below creates a non-hierarchical taxonomy called topic_tag for normal blog posts. It appears in the editor, adds an admin column, supports REST API usage, and uses a public archive slug of /topic/example-term/.

<?php
/**
 * Plugin Name: VulnWP Topic Taxonomy
 * Description: Registers a topic taxonomy for structured editorial tagging.
 * Version: 1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

add_action( 'init', 'vulnwp_register_topic_taxonomy' );

function vulnwp_register_topic_taxonomy() {
	$labels = array(
		'name'                       => __( 'Topics', 'vulnwp-topic-taxonomy' ),
		'singular_name'              => __( 'Topic', 'vulnwp-topic-taxonomy' ),
		'search_items'               => __( 'Search Topics', 'vulnwp-topic-taxonomy' ),
		'popular_items'              => __( 'Popular Topics', 'vulnwp-topic-taxonomy' ),
		'all_items'                  => __( 'All Topics', 'vulnwp-topic-taxonomy' ),
		'edit_item'                  => __( 'Edit Topic', 'vulnwp-topic-taxonomy' ),
		'update_item'                => __( 'Update Topic', 'vulnwp-topic-taxonomy' ),
		'add_new_item'               => __( 'Add New Topic', 'vulnwp-topic-taxonomy' ),
		'new_item_name'              => __( 'New Topic Name', 'vulnwp-topic-taxonomy' ),
		'separate_items_with_commas' => __( 'Separate topics with commas', 'vulnwp-topic-taxonomy' ),
		'add_or_remove_items'        => __( 'Add or remove topics', 'vulnwp-topic-taxonomy' ),
		'choose_from_most_used'      => __( 'Choose from the most used topics', 'vulnwp-topic-taxonomy' ),
		'not_found'                  => __( 'No topics found.', 'vulnwp-topic-taxonomy' ),
		'menu_name'                  => __( 'Topics', 'vulnwp-topic-taxonomy' ),
	);

	register_taxonomy(
		'topic_tag',
		array( 'post' ),
		array(
			'labels'             => $labels,
			'description'        => __( 'Structured topic labels for editorial content.', 'vulnwp-topic-taxonomy' ),
			'public'             => true,
			'publicly_queryable' => true,
			'hierarchical'       => false,
			'show_ui'            => true,
			'show_admin_column'  => true,
			'show_in_rest'       => true,
			'rewrite'            => array(
				'slug'       => 'topic',
				'with_front' => false,
			),
			'capabilities'       => array(
				'manage_terms' => 'manage_categories',
				'edit_terms'   => 'manage_categories',
				'delete_terms' => 'manage_categories',
				'assign_terms' => 'edit_posts',
			),
		)
	);
}

register_activation_hook(
	__FILE__,
	function () {
		vulnwp_register_topic_taxonomy();
		flush_rewrite_rules();
	}
);

register_deactivation_hook(
	__FILE__,
	function () {
		flush_rewrite_rules();
	}
);

Why this should be a plugin

A taxonomy describes content, not theme presentation. If the active theme changes, the terms should still exist, the editor should still display them, and API consumers should not lose the field. That is why a custom taxonomy usually belongs in a plugin or must-use plugin, not in functions.php.

Important arguments explained

register_taxonomy() should run on the init hook. WordPress also documents that the taxonomy key must stay short and use safe lowercase characters. Treat that key as permanent because changing it later can break stored term relationships, REST consumers, templates, and archive URLs.

  • show_in_rest makes the taxonomy available to the block editor and REST API clients.
  • show_admin_column helps editors audit term usage from the post list screen.
  • hierarchical controls whether it behaves like categories or tags.
  • rewrite controls archive URLs and should be chosen before launch.
  • capabilities separates who can manage terms from who can assign them.

Hierarchical or non-hierarchical?

Use hierarchical => true when terms need parent-child structure, such as industries, regions, departments, or product families. Use hierarchical => false when terms behave like tags, such as techniques, frameworks, or vulnerability names.

Do not choose hierarchy only because it looks organized in the admin UI. Parent-child taxonomies create URL, migration, and editorial governance decisions. If editors cannot explain the tree rules, a flat taxonomy is safer.

How to test after activation

  1. Activate the plugin on a staging site first.
  2. Open the post editor and confirm the Topics panel appears.
  3. Add two or three terms and save a post.
  4. Open the post list and confirm the admin column appears.
  5. Visit a term archive URL such as /topic/security/.
  6. Check the REST API response for the taxonomy relationship.
curl -s https://example.com/wp-json/wp/v2/taxonomies/topic_tag | jq
curl -s 'https://example.com/wp-json/wp/v2/posts?per_page=1&_fields=id,topic_tag' | jq

Common mistakes

  • Putting taxonomy registration in the theme. The content model disappears when the theme is changed or disabled.
  • Changing the taxonomy key after launch. The key is stored throughout WordPress data and integrations.
  • Forgetting show_in_rest. Editors may not see the taxonomy correctly in the block editor.
  • Skipping rewrite flushing on activation. Archive URLs may return 404 until permalink rules are refreshed.
  • Creating too many overlapping taxonomies. Editorial teams need clear rules, not more dropdowns.

SEO and information architecture notes

Custom taxonomy archives can help discovery when they represent meaningful topic clusters. They can also create thin, duplicate, or low-value archive pages if every one-off label becomes public. Before exposing archives to search engines, decide which terms deserve indexable landing pages and which should remain internal organization tools.

If the taxonomy is only for internal editorial workflow, set public or publicly_queryable accordingly and avoid creating public archives. If the taxonomy should rank, write useful term descriptions, link related articles, and avoid empty archives.

Related reading

This pairs well with our custom post type example. A CPT defines the content object; a taxonomy defines how those objects are grouped and discovered.

References and further reading

Popular Guides

Popular WordPress guides to read next.

These articles connect recurring production concerns: implementation details, updates, troubleshooting, recovery paths, and operational cleanup.

Continue Reading

More from the archive.

Diagnostic dashboard scene representing a WordPress Site Health review before major updates.
01Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Site Health Check Before Major Updates: What to Review First

A pre-update WordPress Site Health checklist covering loopbacks, connectivity, debug settings, and environment readiness.

Structured data and route review scene representing permalink validation after a WordPress migration.
02Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Permalink Checklist After Migration: Catch URL Problems Early

A post-migration WordPress permalink checklist for checking rewrite rules, post URLs, archives, and redirect noise.

Technical media workspace representing image preparation and optimization before upload to WordPress.
03Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Image Optimization Checklist: What to Fix Before Upload

A practical WordPress image optimization checklist covering dimensions, compression, formats, and Media settings before upload.