PHPackages                             arraypress/wp-register-columns - 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-columns

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

arraypress/wp-register-columns
==============================

Lightweight library for registering custom columns in WordPress admin tables.

18PHP

Since Nov 25Pushed 5mo ago1 watchersCompare

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

READMEChangelogDependenciesVersions (1)Used By (0)

WordPress Register Columns
==========================

[](#wordpress-register-columns)

A lightweight library for registering custom columns in WordPress admin tables. This library provides a clean, simple API for adding display-only columns to posts, users, taxonomies, comments, and media without the bloat of inline editing or complex UI components.

Features
--------

[](#features)

- **Simple API**: Register custom columns with minimal code
- **Column Positioning**: Position columns before or after existing columns
- **Sortable Columns**: Support for text and numeric sorting
- **Display Callbacks**: Full control over column content rendering
- **Permission Callbacks**: Control column visibility based on user capabilities
- **Width Control**: Set custom column widths
- **Multiple Post Types**: Register same columns across multiple post types or taxonomies
- **Lightweight**: No AJAX, no inline editing, just clean display functionality

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

[](#requirements)

- PHP 7.4 or higher
- WordPress 5.0 or higher

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

[](#installation)

Install via Composer:

```
composer require arraypress/wp-register-columns
```

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

[](#basic-usage)

### Post Columns

[](#post-columns)

Register custom columns for posts or custom post types:

```
register_post_columns( 'post', [
    'views' => [
        'label'            => __( 'Views', 'textdomain' ),
        'meta_key'         => 'post_views',
        'sortable'         => true,
        'numeric'          => true,
        'position'         => 'after:title',
        'display_callback' => function( $value, $post_id ) {
            return number_format_i18n( (int) $value );
        },
        'width' => '80px'
    ]
] );
```

### Multiple Post Types

[](#multiple-post-types)

Register the same columns across multiple post types:

```
register_post_columns( [ 'post', 'page', 'custom_post_type' ], [
    'status' => [
        'label'            => __( 'Status', 'textdomain' ),
        'meta_key'         => 'custom_status',
        'position'         => 'before:date',
        'display_callback' => function( $value, $post_id ) {
            return ucfirst( $value );
        }
    ]
] );
```

### User Columns

[](#user-columns)

Register custom columns for users:

```
register_user_columns( [
    'points' => [
        'label'            => __( 'Points', 'textdomain' ),
        'meta_key'         => 'user_points',
        'sortable'         => true,
        'numeric'          => true,
        'position'         => 'after:email',
        'display_callback' => function( $value, $user_id ) {
            return number_format_i18n( (int) $value );
        }
    ]
] );
```

### Taxonomy Columns

[](#taxonomy-columns)

Register custom columns for taxonomies:

```
register_taxonomy_columns( [ 'category', 'post_tag' ], [
    'color' => [
        'label'            => __( 'Color', 'textdomain' ),
        'meta_key'         => 'term_color',
        'position'         => 'after:name',
        'display_callback' => function( $value, $term_id ) {
            if ( empty( $value ) ) {
                return '—';
            }
            return sprintf(
                '',
                esc_attr( $value )
            );
        }
    ]
] );
```

### Comment Columns

[](#comment-columns)

Register custom columns for comments:

```
register_comment_columns( [
    'rating' => [
        'label'            => __( 'Rating', 'textdomain' ),
        'meta_key'         => 'comment_rating',
        'sortable'         => true,
        'numeric'          => true,
        'position'         => 'after:author',
        'display_callback' => function( $value, $comment_id ) {
            return str_repeat( '★', (int) $value );
        }
    ]
] );
```

### Media Columns

[](#media-columns)

Register custom columns for media library:

```
register_media_columns( [
    'dimensions' => [
        'label'            => __( 'Dimensions', 'textdomain' ),
        'position'         => 'after:title',
        'display_callback' => function( $attachment_id ) {
            $meta = wp_get_attachment_metadata( $attachment_id );
            if ( empty( $meta['width'] ) || empty( $meta['height'] ) ) {
                return '—';
            }
            return sprintf( '%d × %d', $meta['width'], $meta['height'] );
        },
        'width' => '100px'
    ]
] );
```

Column Configuration Options
----------------------------

[](#column-configuration-options)

Each column accepts the following configuration options:

OptionTypeDescription`label`stringColumn header label`meta_key`stringMeta key to retrieve value from`position`stringColumn position (e.g., 'after:title', 'before:date')`sortable`boolWhether the column is sortable`numeric`boolWhether to sort numerically`sortby`stringCustom orderby parameter for sorting`display_callback`callableFunction to render column content`permission_callback`callableFunction to check if user can see column`width`stringCSS width value (e.g., '100px', '10%')Display Callbacks
-----------------

[](#display-callbacks)

Display callbacks receive different parameters based on the table type:

### With Meta Key

[](#with-meta-key)

```
'display_callback' => function( $value, $object_id ) {
    // $value is the meta value
    // $object_id is the post/user/term/comment ID
    return esc_html( $value );
}
```

### Without Meta Key

[](#without-meta-key)

```
'display_callback' => function( $object_id ) {
    // $object_id is the post/user/term/comment ID
    // Retrieve any data you need
    return 'Custom output';
}
```

Advanced Sorting
----------------

[](#advanced-sorting)

### Sort by Meta Key

[](#sort-by-meta-key)

```
'meta_key'  => 'views_count',
'sortable'  => true,
'numeric'   => true
```

### Sort by Custom Field

[](#sort-by-custom-field)

```
'sortby'    => 'meta_value_datetime',
'sortable'  => true
```

### Sort by Post Property

[](#sort-by-post-property)

```
'sortby'    => 'comment_count',
'sortable'  => true,
'numeric'   => true
```

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

[](#permission-control)

Control column visibility based on user capabilities:

```
register_post_columns( 'post', [
    'internal_notes' => [
        'label'               => __( 'Internal Notes', 'textdomain' ),
        'meta_key'            => 'internal_notes',
        'position'            => 'after:title',
        'permission_callback' => function() {
            return current_user_can( 'edit_others_posts' );
        }
    ]
] );
```

Removing Existing Columns
-------------------------

[](#removing-existing-columns)

Remove unwanted default columns:

```
register_post_columns( 'post', [
    'custom_column' => [
        'label'    => __( 'Custom', 'textdomain' ),
        'position' => 'after:title'
    ]
], [ 'tags', 'comments' ] ); // Remove tags and comments columns
```

Examples
--------

[](#examples)

### Featured Image Column

[](#featured-image-column)

```
register_post_columns( 'post', [
    'thumbnail' => [
        'label'            => '',
        'position'         => 'before:title',
        'display_callback' => function( $post_id ) {
            $thumbnail_id = get_post_thumbnail_id( $post_id );
            if ( ! $thumbnail_id ) {
                return '—';
            }
            return wp_get_attachment_image( $thumbnail_id, [ 50, 50 ] );
        },
        'width' => '60px'
    ]
] );
```

### Word Count Column

[](#word-count-column)

```
register_post_columns( 'post', [
    'word_count' => [
        'label'            => __( 'Words', 'textdomain' ),
        'sortable'         => true,
        'numeric'          => true,
        'position'         => 'after:title',
        'display_callback' => function( $post_id ) {
            $content = get_post_field( 'post_content', $post_id );
            $count   = str_word_count( strip_tags( $content ) );
            return number_format_i18n( $count );
        }
    ]
] );
```

### Last Login Column (Users)

[](#last-login-column-users)

```
register_user_columns( [
    'last_login' => [
        'label'            => __( 'Last Login', 'textdomain' ),
        'meta_key'         => 'last_login',
        'sortable'         => true,
        'position'         => 'after:role',
        'display_callback' => function( $value, $user_id ) {
            if ( empty( $value ) ) {
                return '—';
            }
            return human_time_diff( (int) $value ) . ' ago';
        }
    ]
] );
```

Best Practices
--------------

[](#best-practices)

1. **Use Permission Callbacks**: Always check capabilities when displaying sensitive data
2. **Escape Output**: Use appropriate escaping functions in display callbacks
3. **Handle Empty Values**: Always check for empty values in display callbacks
4. **Use Width Sparingly**: Only set width when necessary
5. **Performance**: For expensive operations in display callbacks, consider caching

Comparison with Original Library
--------------------------------

[](#comparison-with-original-library)

This library is a complete rewrite focused on simplicity:

**Removed:**

- ❌ AJAX inline editing
- ❌ Metadata update/delete callbacks
- ❌ Sanitize callbacks
- ❌ Factory pattern complexity
- ❌ Built-in display helpers

**Kept:**

- ✅ Clean column registration
- ✅ Positioning system
- ✅ Sortable columns
- ✅ Display callbacks
- ✅ Permission callbacks
- ✅ Width control

**Result:** ~80% less code with clearer, more maintainable architecture.

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-columns)
- [Issue Tracker](https://github.com/arraypress/wp-register-columns/issues)

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance48

Moderate activity, may be stable

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity13

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 (24 commits)")

### Embed Badge

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

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

###  Alternatives

[antoineaugusti/easyphpcharts

A PHP class for chartjs.org charts.

252.8k](/packages/antoineaugusti-easyphpcharts)

PHPackages © 2026

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