PHPackages                             arraypress/wp-register-term-fields - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. arraypress/wp-register-term-fields

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

arraypress/wp-register-term-fields
==================================

Lightweight library for registering custom fields on WordPress taxonomy term screens.

115PHP

Since Feb 23Pushed 2mo agoCompare

[ Source](https://github.com/arraypress/wp-register-term-fields)[ Packagist](https://packagist.org/packages/arraypress/wp-register-term-fields)[ RSS](/packages/arraypress-wp-register-term-fields/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

WordPress Register Term Fields
==============================

[](#wordpress-register-term-fields)

A lightweight library for registering custom fields on WordPress taxonomy term add/edit screens. This library provides a clean, simple API for adding common field types to any taxonomy without JavaScript dependencies or complex configuration.

Features
--------

[](#features)

- **Simple API**: Register custom term fields with minimal code
- **Multiple Field Types**: Text, textarea, number, select, checkbox, URL, and email
- **Automatic Saving**: Fields are automatically saved to term meta
- **Smart Sanitization**: Each field type has appropriate default sanitization
- **Dynamic Options**: Select fields support callable options for dynamic data
- **Multiple Taxonomies**: Register the same fields across multiple taxonomies
- **Permission Control**: Control field visibility based on user capabilities
- **No JavaScript**: Pure PHP implementation with WordPress-native markup
- **Lightweight**: Single class, minimal footprint

Requirements
------------

[](#requirements)

- PHP 7.4 or higher
- WordPress 5.0 or higher

Installation
------------

[](#installation)

Install via Composer:

```
composer require arraypress/wp-register-term-fields
```

Basic Usage
-----------

[](#basic-usage)

### Simple Text Field

[](#simple-text-field)

```
register_term_fields( 'category', [
    'subtitle' => [
        'label'       => __( 'Subtitle', 'textdomain' ),
        'type'        => 'text',
        'description' => __( 'A subtitle displayed below the category name.', 'textdomain' ),
    ],
] );
```

### Multiple Fields

[](#multiple-fields)

```
register_term_fields( 'category', [
    'subtitle' => [
        'label'       => __( 'Subtitle', 'textdomain' ),
        'type'        => 'text',
        'placeholder' => __( 'Enter a subtitle...', 'textdomain' ),
    ],
    'color' => [
        'label'       => __( 'Color', 'textdomain' ),
        'type'        => 'text',
        'placeholder' => '#000000',
        'description' => __( 'Hex color code for this category.', 'textdomain' ),
    ],
    'featured' => [
        'label' => __( 'Featured Category', 'textdomain' ),
        'type'  => 'checkbox',
    ],
] );
```

### Multiple Taxonomies

[](#multiple-taxonomies)

Register the same fields across multiple taxonomies:

```
register_term_fields( [ 'category', 'post_tag' ], [
    'icon' => [
        'label'       => __( 'Icon Class', 'textdomain' ),
        'type'        => 'text',
        'placeholder' => 'dashicons-star-filled',
    ],
] );
```

### Select Field with Dynamic Options

[](#select-field-with-dynamic-options)

```
register_term_fields( 'download_category', [
    'tax_class' => [
        'label'       => __( 'Tax Class', 'textdomain' ),
        'type'        => 'select',
        'description' => __( 'Products in this category will use this tax class.', 'textdomain' ),
        'options'     => function() {
            // Fetch options dynamically
            $classes = get_tax_classes();
            $options = [ '' => __( '— Use Default —', 'textdomain' ) ];

            foreach ( $classes as $class ) {
                $options[ $class->id ] = $class->name;
            }

            return $options;
        },
    ],
] );
```

Field Types
-----------

[](#field-types)

### Text

[](#text)

Standard single-line text input.

```
'field_name' => [
    'label'       => __( 'Field Label', 'textdomain' ),
    'type'        => 'text',
    'placeholder' => __( 'Placeholder text...', 'textdomain' ),
    'default'     => '',
]
```

### Textarea

[](#textarea)

Multi-line text input.

```
'description' => [
    'label'       => __( 'Description', 'textdomain' ),
    'type'        => 'textarea',
    'rows'        => 5,
    'placeholder' => __( 'Enter a description...', 'textdomain' ),
]
```

### Number

[](#number)

Numeric input with optional constraints.

```
'display_order' => [
    'label'   => __( 'Display Order', 'textdomain' ),
    'type'    => 'number',
    'min'     => 0,
    'max'     => 100,
    'step'    => 1,
    'default' => 0,
]
```

For decimal values, set a decimal step:

```
'price_modifier' => [
    'label' => __( 'Price Modifier', 'textdomain' ),
    'type'  => 'number',
    'min'   => 0,
    'max'   => 1,
    'step'  => 0.01,
]
```

### Select

[](#select)

Dropdown selection with static or dynamic options.

```
// Static options
'layout' => [
    'label'   => __( 'Layout', 'textdomain' ),
    'type'    => 'select',
    'default' => 'grid',
    'options' => [
        'grid' => __( 'Grid', 'textdomain' ),
        'list' => __( 'List', 'textdomain' ),
        'card' => __( 'Cards', 'textdomain' ),
    ],
]

// Dynamic options via callback
'parent_category' => [
    'label'   => __( 'Parent Category', 'textdomain' ),
    'type'    => 'select',
    'options' => function() {
        $categories = get_categories( [ 'hide_empty' => false ] );
        $options    = [ '' => __( '— None —', 'textdomain' ) ];

        foreach ( $categories as $cat ) {
            $options[ $cat->term_id ] = $cat->name;
        }

        return $options;
    },
]
```

### Checkbox

[](#checkbox)

Boolean toggle field.

```
'featured' => [
    'label'   => __( 'Featured Category', 'textdomain' ),
    'type'    => 'checkbox',
    'default' => 0,
]
```

### URL

[](#url)

Text input with URL validation.

```
'website' => [
    'label'       => __( 'Website', 'textdomain' ),
    'type'        => 'url',
    'placeholder' => 'https://example.com',
]
```

### Email

[](#email)

Text input with email validation.

```
'contact_email' => [
    'label'       => __( 'Contact Email', 'textdomain' ),
    'type'        => 'email',
    'placeholder' => 'contact@example.com',
]
```

Field Configuration Options
---------------------------

[](#field-configuration-options)

Each field accepts the following configuration options:

OptionTypeDefaultDescription`label`string`''`Field label text`type`string`'text'`Field type`description`string`''`Help text displayed below the field`default`mixed`''`Default value for new terms`placeholder`string`''`Placeholder text for text inputs`options`array|callable`[]`Options for select fields`min`int|float`null`Minimum value for number fields`max`int|float`null`Maximum value for number fields`step`int|float`null`Step increment for number fields`rows`int`5`Number of rows for textarea fields`sanitize_callback`callable`null`Custom sanitization function`capability`string`'manage_categories'`Required capability to view/edit the fieldRetrieving Field Values
-----------------------

[](#retrieving-field-values)

### Standard Method

[](#standard-method)

Use WordPress's built-in function:

```
$value = get_term_meta( $term_id, 'color', true );
```

### With Default Fallback

[](#with-default-fallback)

Use the helper function to automatically fall back to registered defaults:

```
$value = get_term_field_value( $term_id, 'color', 'category' );
```

### Get All Registered Fields

[](#get-all-registered-fields)

```
$fields = get_term_fields( 'category' );

foreach ( $fields as $meta_key => $config ) {
    echo $config['label'] . ': ' . get_term_meta( $term_id, $meta_key, true );
}
```

### Get Field Configuration

[](#get-field-configuration)

```
$config = get_term_field_config( 'category', 'color' );

if ( $config ) {
    echo 'Label: ' . $config['label'];
    echo 'Type: ' . $config['type'];
}
```

Custom Sanitization
-------------------

[](#custom-sanitization)

Override the default sanitization for any field:

```
register_term_fields( 'category', [
    'custom_data' => [
        'label'             => __( 'Custom Data', 'textdomain' ),
        'type'              => 'textarea',
        'sanitize_callback' => function( $value ) {
            // Custom sanitization logic
            $value = strip_tags( $value, '' );
            return wp_kses_post( $value );
        },
    ],
] );
```

Permission Control
------------------

[](#permission-control)

Control field visibility based on user capabilities:

```
register_term_fields( 'category', [
    'internal_notes' => [
        'label'       => __( 'Internal Notes', 'textdomain' ),
        'type'        => 'textarea',
        'capability'  => 'manage_options', // Only administrators
        'description' => __( 'Notes visible only to administrators.', 'textdomain' ),
    ],
] );
```

Complete Example
----------------

[](#complete-example)

```
// Register fields for product categories
register_term_fields( 'product_cat', [
    // Basic information
    'subtitle' => [
        'label'       => __( 'Subtitle', 'textdomain' ),
        'type'        => 'text',
        'placeholder' => __( 'Brief tagline for this category', 'textdomain' ),
    ],

    // Display settings
    'display_order' => [
        'label'       => __( 'Display Order', 'textdomain' ),
        'type'        => 'number',
        'min'         => 0,
        'max'         => 999,
        'default'     => 0,
        'description' => __( 'Lower numbers display first.', 'textdomain' ),
    ],

    'layout' => [
        'label'   => __( 'Archive Layout', 'textdomain' ),
        'type'    => 'select',
        'default' => 'grid',
        'options' => [
            'grid'    => __( 'Grid', 'textdomain' ),
            'list'    => __( 'List', 'textdomain' ),
            'masonry' => __( 'Masonry', 'textdomain' ),
        ],
    ],

    // Flags
    'featured' => [
        'label'       => __( 'Featured Category', 'textdomain' ),
        'type'        => 'checkbox',
        'description' => __( 'Show this category on the homepage.', 'textdomain' ),
    ],

    'hide_empty' => [
        'label'       => __( 'Hide When Empty', 'textdomain' ),
        'type'        => 'checkbox',
        'default'     => 1,
        'description' => __( 'Hide this category if it has no products.', 'textdomain' ),
    ],

    // External link
    'external_url' => [
        'label'       => __( 'External URL', 'textdomain' ),
        'type'        => 'url',
        'placeholder' => 'https://example.com',
        'description' => __( 'Link to external category page instead of archive.', 'textdomain' ),
    ],
] );

// Use in a template
$term_id       = get_queried_object_id();
$subtitle      = get_term_meta( $term_id, 'subtitle', true );
$display_order = get_term_field_value( $term_id, 'display_order', 'product_cat' );
$layout        = get_term_field_value( $term_id, 'layout', 'product_cat' );
$is_featured   = get_term_meta( $term_id, 'featured', true );
```

Integration with Register Columns
---------------------------------

[](#integration-with-register-columns)

This library pairs well with [wp-register-columns](https://github.com/arraypress/wp-register-columns) to display term field values in admin list tables:

```
// Register the field
register_term_fields( 'category', [
    'color' => [
        'label' => __( 'Color', 'textdomain' ),
        'type'  => 'text',
    ],
] );

// Display in list table
register_taxonomy_columns( 'category', [
    'color' => [
        'label'            => __( 'Color', 'textdomain' ),
        'meta_key'         => 'color',
        'display_callback' => function( $value, $term_id ) {
            if ( empty( $value ) ) {
                return '—';
            }
            return sprintf(
                '',
                esc_attr( $value )
            );
        },
    ],
] );
```

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

License
-------

[](#license)

GPL-2.0-or-later

Author
------

[](#author)

David Sherlock - [ArrayPress](https://arraypress.com/)

Support
-------

[](#support)

- [Documentation](https://github.com/arraypress/wp-register-term-fields)
- [Issue Tracker](https://github.com/arraypress/wp-register-term-fields/issues)

###  Health Score

21

—

LowBetter than 19% of packages

Maintenance56

Moderate activity, may be stable

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/cd6eb8aff0903d87eb674d1ba3c5f3653899c0d7661504eb0deb7798ed86b643?d=identicon)[arraypress](/maintainers/arraypress)

---

Top Contributors

[![arraypress](https://avatars.githubusercontent.com/u/22668877?v=4)](https://github.com/arraypress "arraypress (5 commits)")

### Embed Badge

![Health badge](/badges/arraypress-wp-register-term-fields/health.svg)

```
[![Health](https://phpackages.com/badges/arraypress-wp-register-term-fields/health.svg)](https://phpackages.com/packages/arraypress-wp-register-term-fields)
```

###  Alternatives

[ipinfo/ipinfo

The official PHP library for IPinfo, the most reliable, accurate, and in-depth source of IP address data available anywhere. We process terabytes of data to produce our custom IP geolocation, company, carrier and IP type data sets. Visit our developer docs at https://ipinfo.io/developers.

2891.2M11](/packages/ipinfo-ipinfo)[craftcms/plugin-installer

Craft CMS Plugin Installer

283.3M4](/packages/craftcms-plugin-installer)[typo3/cms-recordlist

TYPO3 CMS Recordlist - Lists database records in the TYPO3 backend module (Web&gt;List).

178.0M48](/packages/typo3-cms-recordlist)[broadway/uuid-generator

UUID generator for broadway/broadway.

202.1M11](/packages/broadway-uuid-generator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
