I’ll build this as a complete advanced WordPress taxonomy file for your rx-theme, focused on a medical “Disease Type” taxonomy: registration, labels, REST support, rewrite rules, admin columns, term meta, schema helpers, breadcrumbs/title helpers, and safe fallbacks.
Below is an advanced complete inc/taxonomies/disease-type.php file for your rx-theme. It creates a powerful hierarchical taxonomy named Disease Type for medical content. WordPress supports custom taxonomies through register_taxonomy(), including REST/Gutenberg support with show_in_rest, rewrite rules, and admin UI settings. Term metadata can be stored and retrieved with functions like get_term_meta(), and taxonomy admin columns can be customized with dynamic taxonomy column hooks.
Create this file:
<?php
/**
* Disease Type Taxonomy
*
* File: inc/taxonomies/disease-type.php
*
* @package RxTheme
* @version 1.0.0
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'Rx_Theme_Disease_Type_Taxonomy' ) ) :
final class Rx_Theme_Disease_Type_Taxonomy {
/**
* Taxonomy slug.
*/
const TAXONOMY = 'disease_type';
/**
* Main post type fallback.
*
* Change this if your main disease post type has another slug.
*/
const DEFAULT_POST_TYPE = 'post';
/**
* Meta keys.
*/
const META_ICON = '_rx_disease_type_icon';
const META_COLOR = '_rx_disease_type_color';
const META_SEO_TITLE = '_rx_disease_type_seo_title';
const META_SEO_DESCRIPTION = '_rx_disease_type_seo_description';
const META_INTRO = '_rx_disease_type_intro';
const META_PRIORITY = '_rx_disease_type_priority';
const META_SCHEMA_NAME = '_rx_disease_type_schema_name';
const META_SCHEMA_DESC = '_rx_disease_type_schema_description';
const META_FEATURED_IMAGE_ID = '_rx_disease_type_featured_image_id';
/**
* Boot hooks.
*/
public static function init() {
add_action( 'init', array( __CLASS__, 'register_taxonomy' ), 5 );
add_action( self::TAXONOMY . '_add_form_fields', array( __CLASS__, 'add_term_fields' ) );
add_action( self::TAXONOMY . '_edit_form_fields', array( __CLASS__, 'edit_term_fields' ), 10, 2 );
add_action( 'created_' . self::TAXONOMY, array( __CLASS__, 'save_term_meta' ) );
add_action( 'edited_' . self::TAXONOMY, array( __CLASS__, 'save_term_meta' ) );
add_filter( 'manage_edit-' . self::TAXONOMY . '_columns', array( __CLASS__, 'admin_columns' ) );
add_filter( 'manage_' . self::TAXONOMY . '_custom_column', array( __CLASS__, 'admin_column_content' ), 10, 3 );
add_filter( 'manage_edit-' . self::TAXONOMY . '_sortable_columns', array( __CLASS__, 'sortable_columns' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'admin_assets' ) );
add_filter( 'term_link', array( __CLASS__, 'filter_term_link' ), 10, 3 );
add_action( 'pre_get_posts', array( __CLASS__, 'taxonomy_archive_query' ) );
add_filter( 'document_title_parts', array( __CLASS__, 'document_title_parts' ) );
add_action( 'wp_head', array( __CLASS__, 'output_taxonomy_seo_meta' ), 2 );
add_action( 'wp_head', array( __CLASS__, 'output_taxonomy_schema' ), 30 );
add_action( 'rest_api_init', array( __CLASS__, 'register_rest_meta' ) );
}
/**
* Register Disease Type taxonomy.
*/
public static function register_taxonomy() {
$post_types = self::get_supported_post_types();
$labels = array(
'name' => _x( 'Disease Types', 'taxonomy general name', 'rx-theme' ),
'singular_name' => _x( 'Disease Type', 'taxonomy singular name', 'rx-theme' ),
'search_items' => __( 'Search Disease Types', 'rx-theme' ),
'popular_items' => __( 'Popular Disease Types', 'rx-theme' ),
'all_items' => __( 'All Disease Types', 'rx-theme' ),
'parent_item' => __( 'Parent Disease Type', 'rx-theme' ),
'parent_item_colon' => __( 'Parent Disease Type:', 'rx-theme' ),
'edit_item' => __( 'Edit Disease Type', 'rx-theme' ),
'view_item' => __( 'View Disease Type', 'rx-theme' ),
'update_item' => __( 'Update Disease Type', 'rx-theme' ),
'add_new_item' => __( 'Add New Disease Type', 'rx-theme' ),
'new_item_name' => __( 'New Disease Type Name', 'rx-theme' ),
'separate_items_with_commas' => __( 'Separate disease types with commas', 'rx-theme' ),
'add_or_remove_items' => __( 'Add or remove disease types', 'rx-theme' ),
'choose_from_most_used' => __( 'Choose from the most used disease types', 'rx-theme' ),
'not_found' => __( 'No disease types found.', 'rx-theme' ),
'no_terms' => __( 'No disease types', 'rx-theme' ),
'filter_by_item' => __( 'Filter by disease type', 'rx-theme' ),
'items_list_navigation' => __( 'Disease types list navigation', 'rx-theme' ),
'items_list' => __( 'Disease types list', 'rx-theme' ),
'back_to_items' => __( 'Back to disease types', 'rx-theme' ),
'menu_name' => __( 'Disease Types', 'rx-theme' ),
);
$args = array(
'labels' => $labels,
'description' => __( 'Classifies diseases by medical type, body system, severity, origin, pathology, or clinical group.', 'rx-theme' ),
'public' => true,
'publicly_queryable' => true,
'hierarchical' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'show_in_quick_edit' => true,
'show_admin_column' => true,
'show_in_rest' => true,
'rest_base' => 'disease-types',
'rest_namespace' => 'wp/v2',
'rest_controller_class' => 'WP_REST_Terms_Controller',
'query_var' => self::TAXONOMY,
'rewrite' => array(
'slug' => 'disease-type',
'with_front' => false,
'hierarchical' => true,
'ep_mask' => EP_NONE,
),
'capabilities' => array(
'manage_terms' => 'manage_categories',
'edit_terms' => 'manage_categories',
'delete_terms' => 'manage_categories',
'assign_terms' => 'edit_posts',
),
'default_term' => array(
'name' => __( 'General Disease', 'rx-theme' ),
'slug' => 'general-disease',
'description' => __( 'General disease classification.', 'rx-theme' ),
),
'sort' => true,
'meta_box_cb' => 'post_categories_meta_box',
);
register_taxonomy( self::TAXONOMY, $post_types, $args );
}
/**
* Supported post types.
*/
public static function get_supported_post_types() {
$post_types = array( self::DEFAULT_POST_TYPE );
if ( post_type_exists( 'disease' ) ) {
$post_types[] = 'disease';
}
if ( post_type_exists( 'conditions' ) ) {
$post_types[] = 'conditions';
}
if ( post_type_exists( 'medical_article' ) ) {
$post_types[] = 'medical_article';
}
if ( post_type_exists( 'health_article' ) ) {
$post_types[] = 'health_article';
}
/**
* Filter supported post types.
*/
return apply_filters( 'rx_theme_disease_type_post_types', array_unique( $post_types ) );
}
/**
* Register REST-visible term meta.
*/
public static function register_rest_meta() {
$meta_fields = array(
self::META_ICON => array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_COLOR => array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_hex_color',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_SEO_TITLE => array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_SEO_DESCRIPTION => array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_textarea_field',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_INTRO => array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'wp_kses_post',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_PRIORITY => array(
'type' => 'integer',
'single' => true,
'sanitize_callback' => 'absint',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_SCHEMA_NAME => array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_SCHEMA_DESC => array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_textarea_field',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
self::META_FEATURED_IMAGE_ID => array(
'type' => 'integer',
'single' => true,
'sanitize_callback' => 'absint',
'auth_callback' => array( __CLASS__, 'rest_meta_auth' ),
'show_in_rest' => true,
),
);
foreach ( $meta_fields as $key => $args ) {
register_term_meta( self::TAXONOMY, $key, $args );
}
}
/**
* REST meta permission.
*/
public static function rest_meta_auth() {
return current_user_can( 'manage_categories' );
}
/**
* Add screen fields.
*/
public static function add_term_fields() {
wp_nonce_field( 'rx_disease_type_meta_save', 'rx_disease_type_meta_nonce' );
?>
<div class="form-field rx-term-field">
<label for="rx_disease_type_icon"><?php esc_html_e( 'Icon Class / Emoji', 'rx-theme' ); ?></label>
<input type="text" name="rx_disease_type_icon" id="rx_disease_type_icon" value="" placeholder="🫀 or dashicons-heart">
<p><?php esc_html_e( 'Example: 🫀, 🧠, dashicons-heart, dashicons-plus-alt.', 'rx-theme' ); ?></p>
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_color"><?php esc_html_e( 'Color', 'rx-theme' ); ?></label>
<input type="text" name="rx_disease_type_color" id="rx_disease_type_color" value="#0ea5e9" class="rx-color-field">
<p><?php esc_html_e( 'Used for badges, cards, archive heading, and frontend styling.', 'rx-theme' ); ?></p>
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_seo_title"><?php esc_html_e( 'SEO Title', 'rx-theme' ); ?></label>
<input type="text" name="rx_disease_type_seo_title" id="rx_disease_type_seo_title" value="">
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_seo_description"><?php esc_html_e( 'SEO Description', 'rx-theme' ); ?></label>
<textarea name="rx_disease_type_seo_description" id="rx_disease_type_seo_description" rows="4"></textarea>
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_intro"><?php esc_html_e( 'Archive Intro Text', 'rx-theme' ); ?></label>
<textarea name="rx_disease_type_intro" id="rx_disease_type_intro" rows="5"></textarea>
<p><?php esc_html_e( 'Shown above disease type archive content.', 'rx-theme' ); ?></p>
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_priority"><?php esc_html_e( 'Priority', 'rx-theme' ); ?></label>
<input type="number" name="rx_disease_type_priority" id="rx_disease_type_priority" value="10" min="0" step="1">
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_schema_name"><?php esc_html_e( 'Schema Name', 'rx-theme' ); ?></label>
<input type="text" name="rx_disease_type_schema_name" id="rx_disease_type_schema_name" value="">
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_schema_description"><?php esc_html_e( 'Schema Description', 'rx-theme' ); ?></label>
<textarea name="rx_disease_type_schema_description" id="rx_disease_type_schema_description" rows="4"></textarea>
</div>
<div class="form-field rx-term-field">
<label for="rx_disease_type_featured_image_id"><?php esc_html_e( 'Featured Image ID', 'rx-theme' ); ?></label>
<input type="number" name="rx_disease_type_featured_image_id" id="rx_disease_type_featured_image_id" value="" min="0" step="1">
<p><?php esc_html_e( 'Enter WordPress media attachment ID.', 'rx-theme' ); ?></p>
</div>
<?php
}
/**
* Edit screen fields.
*/
public static function edit_term_fields( $term ) {
$icon = self::get_meta( $term->term_id, self::META_ICON );
$color = self::get_meta( $term->term_id, self::META_COLOR );
$seo_title = self::get_meta( $term->term_id, self::META_SEO_TITLE );
$seo_desc = self::get_meta( $term->term_id, self::META_SEO_DESCRIPTION );
$intro = self::get_meta( $term->term_id, self::META_INTRO );
$priority = self::get_meta( $term->term_id, self::META_PRIORITY );
$schema_name = self::get_meta( $term->term_id, self::META_SCHEMA_NAME );
$schema_desc = self::get_meta( $term->term_id, self::META_SCHEMA_DESC );
$image_id = self::get_meta( $term->term_id, self::META_FEATURED_IMAGE_ID );
wp_nonce_field( 'rx_disease_type_meta_save', 'rx_disease_type_meta_nonce' );
?>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_icon"><?php esc_html_e( 'Icon Class / Emoji', 'rx-theme' ); ?></label>
</th>
<td>
<input type="text" name="rx_disease_type_icon" id="rx_disease_type_icon" value="<?php echo esc_attr( $icon ); ?>">
<p class="description"><?php esc_html_e( 'Example: 🫀, 🧠, dashicons-heart, dashicons-plus-alt.', 'rx-theme' ); ?></p>
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_color"><?php esc_html_e( 'Color', 'rx-theme' ); ?></label>
</th>
<td>
<input type="text" name="rx_disease_type_color" id="rx_disease_type_color" class="rx-color-field" value="<?php echo esc_attr( $color ? $color : '#0ea5e9' ); ?>">
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_seo_title"><?php esc_html_e( 'SEO Title', 'rx-theme' ); ?></label>
</th>
<td>
<input type="text" name="rx_disease_type_seo_title" id="rx_disease_type_seo_title" value="<?php echo esc_attr( $seo_title ); ?>" class="regular-text">
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_seo_description"><?php esc_html_e( 'SEO Description', 'rx-theme' ); ?></label>
</th>
<td>
<textarea name="rx_disease_type_seo_description" id="rx_disease_type_seo_description" rows="4" class="large-text"><?php echo esc_textarea( $seo_desc ); ?></textarea>
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_intro"><?php esc_html_e( 'Archive Intro Text', 'rx-theme' ); ?></label>
</th>
<td>
<textarea name="rx_disease_type_intro" id="rx_disease_type_intro" rows="6" class="large-text"><?php echo esc_textarea( $intro ); ?></textarea>
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_priority"><?php esc_html_e( 'Priority', 'rx-theme' ); ?></label>
</th>
<td>
<input type="number" name="rx_disease_type_priority" id="rx_disease_type_priority" value="<?php echo esc_attr( $priority ? $priority : 10 ); ?>" min="0" step="1">
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_schema_name"><?php esc_html_e( 'Schema Name', 'rx-theme' ); ?></label>
</th>
<td>
<input type="text" name="rx_disease_type_schema_name" id="rx_disease_type_schema_name" value="<?php echo esc_attr( $schema_name ); ?>" class="regular-text">
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_schema_description"><?php esc_html_e( 'Schema Description', 'rx-theme' ); ?></label>
</th>
<td>
<textarea name="rx_disease_type_schema_description" id="rx_disease_type_schema_description" rows="4" class="large-text"><?php echo esc_textarea( $schema_desc ); ?></textarea>
</td>
</tr>
<tr class="form-field rx-term-field">
<th scope="row">
<label for="rx_disease_type_featured_image_id"><?php esc_html_e( 'Featured Image ID', 'rx-theme' ); ?></label>
</th>
<td>
<input type="number" name="rx_disease_type_featured_image_id" id="rx_disease_type_featured_image_id" value="<?php echo esc_attr( absint( $image_id ) ); ?>" min="0" step="1">
<?php
if ( $image_id ) {
echo '<div class="rx-term-image-preview" style="margin-top:10px;">';
echo wp_get_attachment_image( absint( $image_id ), 'thumbnail' );
echo '</div>';
}
?>
</td>
</tr>
<?php
}
/**
* Save term meta.
*/
public static function save_term_meta( $term_id ) {
if ( ! isset( $_POST['rx_disease_type_meta_nonce'] ) ) {
return;
}
$nonce = sanitize_text_field( wp_unslash( $_POST['rx_disease_type_meta_nonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'rx_disease_type_meta_save' ) ) {
return;
}
if ( ! current_user_can( 'manage_categories' ) ) {
return;
}
$fields = array(
self::META_ICON => array( 'field' => 'rx_disease_type_icon', 'sanitize' => 'sanitize_text_field' ),
self::META_COLOR => array( 'field' => 'rx_disease_type_color', 'sanitize' => 'sanitize_hex_color' ),
self::META_SEO_TITLE => array( 'field' => 'rx_disease_type_seo_title', 'sanitize' => 'sanitize_text_field' ),
self::META_SEO_DESCRIPTION => array( 'field' => 'rx_disease_type_seo_description', 'sanitize' => 'sanitize_textarea_field' ),
self::META_INTRO => array( 'field' => 'rx_disease_type_intro', 'sanitize' => 'wp_kses_post' ),
self::META_PRIORITY => array( 'field' => 'rx_disease_type_priority', 'sanitize' => 'absint' ),
self::META_SCHEMA_NAME => array( 'field' => 'rx_disease_type_schema_name', 'sanitize' => 'sanitize_text_field' ),
self::META_SCHEMA_DESC => array( 'field' => 'rx_disease_type_schema_description', 'sanitize' => 'sanitize_textarea_field' ),
self::META_FEATURED_IMAGE_ID => array( 'field' => 'rx_disease_type_featured_image_id', 'sanitize' => 'absint' ),
);
foreach ( $fields as $meta_key => $data ) {
$field = $data['field'];
if ( ! isset( $_POST[ $field ] ) ) {
continue;
}
$value = wp_unslash( $_POST[ $field ] );
if ( is_callable( $data['sanitize'] ) ) {
$value = call_user_func( $data['sanitize'], $value );
}
if ( self::META_COLOR === $meta_key && empty( $value ) ) {
$value = '#0ea5e9';
}
update_term_meta( $term_id, $meta_key, $value );
}
}
/**
* Get safe term meta.
*/
public static function get_meta( $term_id, $key, $default = '' ) {
$value = get_term_meta( absint( $term_id ), $key, true );
if ( '' === $value || null === $value ) {
return $default;
}
return $value;
}
/**
* Admin columns.
*/
public static function admin_columns( $columns ) {
$new_columns = array();
if ( isset( $columns['cb'] ) ) {
$new_columns['cb'] = $columns['cb'];
}
$new_columns['rx_icon'] = __( 'Icon', 'rx-theme' );
$new_columns['name'] = __( 'Name', 'rx-theme' );
$new_columns['rx_color'] = __( 'Color', 'rx-theme' );
$new_columns['rx_priority'] = __( 'Priority', 'rx-theme' );
$new_columns['rx_image'] = __( 'Image', 'rx-theme' );
$new_columns['slug'] = __( 'Slug', 'rx-theme' );
$new_columns['posts'] = __( 'Count', 'rx-theme' );
return $new_columns;
}
/**
* Admin column content.
*/
public static function admin_column_content( $content, $column_name, $term_id ) {
switch ( $column_name ) {
case 'rx_icon':
$icon = self::get_meta( $term_id, self::META_ICON );
if ( $icon ) {
$content = '<span style="font-size:22px;">' . esc_html( $icon ) . '</span>';
} else {
$content = '—';
}
break;
case 'rx_color':
$color = self::get_meta( $term_id, self::META_COLOR, '#0ea5e9' );
$content = '<span style="display:inline-block;width:22px;height:22px;border-radius:50%;background:' . esc_attr( $color ) . ';border:1px solid #ddd;vertical-align:middle;"></span> ';
$content .= '<code>' . esc_html( $color ) . '</code>';
break;
case 'rx_priority':
$content = absint( self::get_meta( $term_id, self::META_PRIORITY, 10 ) );
break;
case 'rx_image':
$image_id = absint( self::get_meta( $term_id, self::META_FEATURED_IMAGE_ID ) );
if ( $image_id ) {
$content = wp_get_attachment_image( $image_id, array( 48, 48 ) );
} else {
$content = '—';
}
break;
}
return $content;
}
/**
* Sortable columns.
*/
public static function sortable_columns( $columns ) {
$columns['rx_priority'] = 'rx_priority';
return $columns;
}
/**
* Admin assets.
*/
public static function admin_assets( $hook ) {
$screen = get_current_screen();
if ( ! $screen || self::TAXONOMY !== $screen->taxonomy ) {
return;
}
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'wp-color-picker' );
$inline = "
jQuery(document).ready(function($){
$('.rx-color-field').wpColorPicker();
});
";
wp_add_inline_script( 'wp-color-picker', $inline );
}
/**
* Optional term link filter.
*/
public static function filter_term_link( $url, $term, $taxonomy ) {
if ( self::TAXONOMY !== $taxonomy ) {
return $url;
}
return $url;
}
/**
* Improve taxonomy archive query.
*/
public static function taxonomy_archive_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( $query->is_tax( self::TAXONOMY ) ) {
$query->set( 'posts_per_page', absint( apply_filters( 'rx_disease_type_archive_posts_per_page', 12 ) ) );
$query->set( 'ignore_sticky_posts', true );
}
}
/**
* Custom document title.
*/
public static function document_title_parts( $title ) {
if ( ! is_tax( self::TAXONOMY ) ) {
return $title;
}
$term = get_queried_object();
if ( ! $term || is_wp_error( $term ) ) {
return $title;
}
$seo_title = self::get_meta( $term->term_id, self::META_SEO_TITLE );
if ( $seo_title ) {
$title['title'] = $seo_title;
}
return $title;
}
/**
* Output taxonomy SEO meta.
*/
public static function output_taxonomy_seo_meta() {
if ( ! is_tax( self::TAXONOMY ) ) {
return;
}
$term = get_queried_object();
if ( ! $term || is_wp_error( $term ) ) {
return;
}
$description = self::get_meta( $term->term_id, self::META_SEO_DESCRIPTION );
if ( ! $description ) {
$description = term_description( $term->term_id, self::TAXONOMY );
$description = wp_strip_all_tags( $description );
}
if ( $description ) {
echo "\n" . '<meta name="description" content="' . esc_attr( wp_trim_words( $description, 28, '' ) ) . '">' . "\n";
}
$color = self::get_meta( $term->term_id, self::META_COLOR, '#0ea5e9' );
echo '<meta name="theme-color" content="' . esc_attr( $color ) . '">' . "\n";
}
/**
* Output MedicalWebPage schema for taxonomy archive.
*/
public static function output_taxonomy_schema() {
if ( ! is_tax( self::TAXONOMY ) ) {
return;
}
$term = get_queried_object();
if ( ! $term || is_wp_error( $term ) ) {
return;
}
$name = self::get_meta( $term->term_id, self::META_SCHEMA_NAME );
if ( ! $name ) {
$name = single_term_title( '', false );
}
$description = self::get_meta( $term->term_id, self::META_SCHEMA_DESC );
if ( ! $description ) {
$description = self::get_meta( $term->term_id, self::META_SEO_DESCRIPTION );
}
if ( ! $description ) {
$description = wp_strip_all_tags( term_description( $term->term_id, self::TAXONOMY ) );
}
$image_id = absint( self::get_meta( $term->term_id, self::META_FEATURED_IMAGE_ID ) );
$image_url = $image_id ? wp_get_attachment_image_url( $image_id, 'full' ) : '';
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'MedicalWebPage',
'name' => wp_strip_all_tags( $name ),
'description' => wp_strip_all_tags( $description ),
'url' => get_term_link( $term ),
'isPartOf' => array(
'@type' => 'WebSite',
'name' => get_bloginfo( 'name' ),
'url' => home_url( '/' ),
),
'about' => array(
'@type' => 'MedicalCondition',
'name' => wp_strip_all_tags( $term->name ),
),
);
if ( $image_url ) {
$schema['image'] = esc_url_raw( $image_url );
}
echo "\n" . '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>' . "\n";
}
/**
* Get all disease types.
*/
public static function get_terms( $args = array() ) {
$defaults = array(
'taxonomy' => self::TAXONOMY,
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
);
return get_terms( wp_parse_args( $args, $defaults ) );
}
/**
* Get top-level disease types.
*/
public static function get_top_level_terms() {
return self::get_terms(
array(
'parent' => 0,
)
);
}
/**
* Render disease type badge.
*/
public static function render_badge( $term_id, $echo = true ) {
$term = get_term( absint( $term_id ), self::TAXONOMY );
if ( ! $term || is_wp_error( $term ) ) {
return '';
}
$color = self::get_meta( $term->term_id, self::META_COLOR, '#0ea5e9' );
$icon = self::get_meta( $term->term_id, self::META_ICON );
$html = '<a class="rx-disease-type-badge" href="' . esc_url( get_term_link( $term ) ) . '" style="--rx-disease-type-color:' . esc_attr( $color ) . ';">';
$html .= $icon ? '<span class="rx-disease-type-badge__icon">' . esc_html( $icon ) . '</span>' : '';
$html .= '<span class="rx-disease-type-badge__name">' . esc_html( $term->name ) . '</span>';
$html .= '</a>';
if ( $echo ) {
echo wp_kses_post( $html );
}
return $html;
}
/**
* Render badges for current post.
*/
public static function render_post_badges( $post_id = 0, $echo = true ) {
$post_id = $post_id ? absint( $post_id ) : get_the_ID();
if ( ! $post_id ) {
return '';
}
$terms = get_the_terms( $post_id, self::TAXONOMY );
if ( empty( $terms ) || is_wp_error( $terms ) ) {
return '';
}
$html = '<div class="rx-disease-type-badges">';
foreach ( $terms as $term ) {
$html .= self::render_badge( $term->term_id, false );
}
$html .= '</div>';
if ( $echo ) {
echo wp_kses_post( $html );
}
return $html;
}
/**
* Render archive intro.
*/
public static function render_archive_intro( $echo = true ) {
if ( ! is_tax( self::TAXONOMY ) ) {
return '';
}
$term = get_queried_object();
if ( ! $term || is_wp_error( $term ) ) {
return '';
}
$intro = self::get_meta( $term->term_id, self::META_INTRO );
if ( ! $intro ) {
$intro = term_description( $term->term_id, self::TAXONOMY );
}
if ( ! $intro ) {
return '';
}
$html = '<div class="rx-disease-type-archive-intro">';
$html .= wpautop( wp_kses_post( $intro ) );
$html .= '</div>';
if ( $echo ) {
echo wp_kses_post( $html );
}
return $html;
}
/**
* Render disease type card grid.
*/
public static function render_term_grid( $args = array(), $echo = true ) {
$defaults = array(
'parent' => 0,
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
);
$args = wp_parse_args( $args, $defaults );
$terms = self::get_terms( $args );
if ( empty( $terms ) || is_wp_error( $terms ) ) {
return '';
}
$html = '<div class="rx-disease-type-grid">';
foreach ( $terms as $term ) {
$color = self::get_meta( $term->term_id, self::META_COLOR, '#0ea5e9' );
$icon = self::get_meta( $term->term_id, self::META_ICON );
$image_id = absint( self::get_meta( $term->term_id, self::META_FEATURED_IMAGE_ID ) );
$intro = self::get_meta( $term->term_id, self::META_INTRO );
if ( ! $intro ) {
$intro = $term->description;
}
$html .= '<article class="rx-disease-type-card" style="--rx-disease-type-color:' . esc_attr( $color ) . ';">';
$html .= '<a href="' . esc_url( get_term_link( $term ) ) . '" class="rx-disease-type-card__link">';
if ( $image_id ) {
$html .= '<div class="rx-disease-type-card__image">';
$html .= wp_get_attachment_image( $image_id, 'medium' );
$html .= '</div>';
}
$html .= '<div class="rx-disease-type-card__body">';
if ( $icon ) {
$html .= '<div class="rx-disease-type-card__icon">' . esc_html( $icon ) . '</div>';
}
$html .= '<h3 class="rx-disease-type-card__title">' . esc_html( $term->name ) . '</h3>';
if ( $intro ) {
$html .= '<p class="rx-disease-type-card__text">' . esc_html( wp_trim_words( wp_strip_all_tags( $intro ), 22 ) ) . '</p>';
}
$html .= '<span class="rx-disease-type-card__count">';
$html .= sprintf(
esc_html( _n( '%s article', '%s articles', absint( $term->count ), 'rx-theme' ) ),
number_format_i18n( absint( $term->count ) )
);
$html .= '</span>';
$html .= '</div>';
$html .= '</a>';
$html .= '</article>';
}
$html .= '</div>';
if ( $echo ) {
echo wp_kses_post( $html );
}
return $html;
}
/**
* Breadcrumb data for a disease type.
*/
public static function get_term_breadcrumbs( $term_id ) {
$term = get_term( absint( $term_id ), self::TAXONOMY );
if ( ! $term || is_wp_error( $term ) ) {
return array();
}
$breadcrumbs = array();
$ancestors = array_reverse( get_ancestors( $term->term_id, self::TAXONOMY ) );
foreach ( $ancestors as $ancestor_id ) {
$ancestor = get_term( $ancestor_id, self::TAXONOMY );
if ( $ancestor && ! is_wp_error( $ancestor ) ) {
$breadcrumbs[] = array(
'name' => $ancestor->name,
'url' => get_term_link( $ancestor ),
);
}
}
$breadcrumbs[] = array(
'name' => $term->name,
'url' => get_term_link( $term ),
);
return $breadcrumbs;
}
/**
* Render breadcrumb HTML.
*/
public static function render_breadcrumbs( $term_id = 0, $echo = true ) {
if ( ! $term_id && is_tax( self::TAXONOMY ) ) {
$term = get_queried_object();
$term_id = $term && ! is_wp_error( $term ) ? $term->term_id : 0;
}
if ( ! $term_id ) {
return '';
}
$items = self::get_term_breadcrumbs( $term_id );
if ( empty( $items ) ) {
return '';
}
$html = '<nav class="rx-disease-type-breadcrumbs" aria-label="' . esc_attr__( 'Disease type breadcrumbs', 'rx-theme' ) . '">';
$html .= '<a href="' . esc_url( home_url( '/' ) ) . '">' . esc_html__( 'Home', 'rx-theme' ) . '</a>';
foreach ( $items as $item ) {
$html .= ' <span aria-hidden="true">›</span> ';
$html .= '<a href="' . esc_url( $item['url'] ) . '">' . esc_html( $item['name'] ) . '</a>';
}
$html .= '</nav>';
if ( $echo ) {
echo wp_kses_post( $html );
}
return $html;
}
/**
* Body class helper.
*/
public static function body_class( $classes ) {
if ( is_tax( self::TAXONOMY ) ) {
$classes[] = 'rx-disease-type-archive';
}
return $classes;
}
}
Rx_Theme_Disease_Type_Taxonomy::init();
endif;
if ( ! function_exists( 'rx_disease_type_badges' ) ) {
/**
* Template helper: show disease type badges for post.
*/
function rx_disease_type_badges( $post_id = 0, $echo = true ) {
return Rx_Theme_Disease_Type_Taxonomy::render_post_badges( $post_id, $echo );
}
}
if ( ! function_exists( 'rx_disease_type_grid' ) ) {
/**
* Template helper: show disease type grid.
*/
function rx_disease_type_grid( $args = array(), $echo = true ) {
return Rx_Theme_Disease_Type_Taxonomy::render_term_grid( $args, $echo );
}
}
if ( ! function_exists( 'rx_disease_type_archive_intro' ) ) {
/**
* Template helper: show archive intro.
*/
function rx_disease_type_archive_intro( $echo = true ) {
return Rx_Theme_Disease_Type_Taxonomy::render_archive_intro( $echo );
}
}
if ( ! function_exists( 'rx_disease_type_breadcrumbs' ) ) {
/**
* Template helper: show disease type breadcrumbs.
*/
function rx_disease_type_breadcrumbs( $term_id = 0, $echo = true ) {
return Rx_Theme_Disease_Type_Taxonomy::render_breadcrumbs( $term_id, $echo );
}
}
add_filter( 'body_class', array( 'Rx_Theme_Disease_Type_Taxonomy', 'body_class' ) );
Now include it in your theme functions.php:
/**
* Load RX taxonomy files.
*/
$rx_taxonomy_files = array(
get_template_directory() . '/inc/taxonomies/disease-type.php',
);
foreach ( $rx_taxonomy_files as $rx_taxonomy_file ) {
if ( file_exists( $rx_taxonomy_file ) ) {
require_once $rx_taxonomy_file;
}
}
Optional CSS for style.css:
.rx-disease-type-badges {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 12px 0;
}
.rx-disease-type-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border-radius: 999px;
background: color-mix(in srgb, var(--rx-disease-type-color, #0ea5e9) 12%, white);
color: var(--rx-disease-type-color, #0ea5e9);
border: 1px solid color-mix(in srgb, var(--rx-disease-type-color, #0ea5e9) 35%, white);
font-size: 14px;
font-weight: 600;
text-decoration: none;
}
.rx-disease-type-badge:hover {
background: var(--rx-disease-type-color, #0ea5e9);
color: #fff;
}
.rx-disease-type-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
margin: 32px 0;
}
.rx-disease-type-card {
border: 1px solid #e5e7eb;
border-radius: 18px;
overflow: hidden;
background: #fff;
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.06);
transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.rx-disease-type-card:hover {
transform: translateY(-4px);
box-shadow: 0 16px 45px rgba(15, 23, 42, 0.1);
}
.rx-disease-type-card__link {
display: block;
color: inherit;
text-decoration: none;
}
.rx-disease-type-card__image img {
display: block;
width: 100%;
height: 180px;
object-fit: cover;
}
.rx-disease-type-card__body {
padding: 20px;
border-top: 4px solid var(--rx-disease-type-color, #0ea5e9);
}
.rx-disease-type-card__icon {
font-size: 34px;
line-height: 1;
margin-bottom: 12px;
}
.rx-disease-type-card__title {
margin: 0 0 10px;
font-size: 20px;
line-height: 1.3;
}
.rx-disease-type-card__text {
margin: 0 0 14px;
color: #475569;
font-size: 15px;
line-height: 1.7;
}
.rx-disease-type-card__count {
display: inline-flex;
font-size: 13px;
font-weight: 700;
color: var(--rx-disease-type-color, #0ea5e9);
}
.rx-disease-type-archive-intro {
margin: 24px 0;
padding: 24px;
border-left: 5px solid #0ea5e9;
background: #f8fafc;
border-radius: 14px;
}
.rx-disease-type-breadcrumbs {
margin: 16px 0;
font-size: 14px;
color: #64748b;
}
.rx-disease-type-breadcrumbs a {
color: #0f172a;
text-decoration: none;
}
.rx-disease-type-breadcrumbs a:hover {
color: #0ea5e9;
}
Use in template files:
<?php rx_disease_type_badges(); ?>
For a disease type grid:
<?php rx_disease_type_grid(); ?>
For taxonomy archive intro:
<?php rx_disease_type_archive_intro(); ?>
For breadcrumbs:
<?php rx_disease_type_breadcrumbs(); ?>
After adding this file, go to WordPress Dashboard → Settings → Permalinks → Save Changes once to refresh rewrite rules.