PHPackages                             devuri/cpt-meta-box - 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. devuri/cpt-meta-box

ActiveLibrary

devuri/cpt-meta-box
===================

Simple Implementation for custom meta boxes and fields

v0.5.3(1y ago)210.5k↓100%MITPHPPHP ^7.4 || ^8.0

Since Mar 27Pushed 1y ago1 watchersCompare

[ Source](https://github.com/devuri/cpt-meta-box)[ Packagist](https://packagist.org/packages/devuri/cpt-meta-box)[ Docs](https://github.com/devuri/cpt-meta)[ RSS](/packages/devuri-cpt-meta-box/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (10)Versions (21)Used By (0)

cpt-meta
========

[](#cpt-meta)

The **`cpt-meta`** library simplifies the creation, management, and rendering of custom post types, meta boxes, and fields in WordPress. Its modular design makes it easier to build structured content management solutions by providing intuitive APIs for defining and sanitizing metadata, registering post types, generating custom fields, and interacting with WordPress hooks and REST endpoints.

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

[](#installation)

Install via Composer:

```
composer require devuri/cpt-meta-box
```

Once installed, ensure that your plugin or theme autoloads dependencies:

```
require_once __DIR__ . '/vendor/autoload.php';
```

Simplified Example
------------------

[](#simplified-example)

Below is a snippet of how a baisc plugin might set everything up:

```
use Urisoft\PostMeta\Settings;

/**
 * Plugin Name:       Vehicle Management
 * Plugin URI:        https://example.com/plugins
 * Description:       An example plugin using the `cpt-meta` library to manage vehicles in WordPress.
 * Version:           1.0
 * Requires at least: 4.0
 * Requires PHP:      7.4
 * Author:            Your Name
 * Author URI:        https://example.com
 * Text Domain:       wp-vehicle-management
 * License:           GPLv2
 * License URI:       http://www.gnu.org/licenses/gpl-2.0.txt
 */

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

// Autoload `cpt-meta` library
require_once plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';

// Define settings fields
class VehicleSettings extends Settings
{
    public function settings()
    {
        $this->input('Vehicle Name');
        $this->textarea('Description');
        $this->select('Type', [
            'car'        => 'Car',
            'truck'      => 'Truck',
            'motorcycle' => 'Motorcycle',
            'selected'   => $this->getMeta('type'),
        ]);
        $this->input('Top Speed (mph)', ['type' => 'number']);
    }
}

// Create the meta box
createMeta(new VehicleSettings('vehicle'), [
    'name' => 'Vehicle Details',
]);
```

> When you visit **Vehicles &gt; Add New** in the admin area, you’ll see a “Vehicle Details” meta box. Any data entered into these fields will automatically save to the post’s metadata. check out the full sample plugin code here:

Key Features
------------

[](#key-features)

- **Custom Post Types**
    Easily register and configure custom post types using the `PostType` class.
- **Meta Boxes and Fields**
    Define and manage meta boxes via the `MetaBox` class, and create custom field definitions with the `Settings` class.
- **Form Rendering**
    Leverage the `Form` class to generate input fields, textareas, selects, color pickers, and more—complete with zebra striping, table-based layouts, and built-in sanitization hooks.
- **Metadata Handling**
    Retrieve and manage metadata with the `Data` class, which provides easy methods to fetch post meta, create lists of posts, and fetch additional information (like featured image IDs).
- **REST API Integration**
    The `PostType` class can register custom REST endpoints for retrieving or manipulating data. Extend WordPress’s REST API easily.
- **Admin Columns**
    Manage custom columns in the WordPress admin, making them sortable or adding additional information in list tables.
- **Modular &amp; Extensible**
    Built around interfaces, traits, and abstract classes to ensure maximum flexibility. You can override default behaviors or hook into key extension points.

Example: Vehicle Management
---------------------------

[](#example-vehicle-management)

Below is a basic walkthrough on how you might use this library to manage a “Vehicle” custom post type and its metadata.

### 1. Register a Custom Post Type

[](#1-register-a-custom-post-type)

First, create a `PostType` instance and register it:

```
use Urisoft\PostMeta\PostType;

// Create and configure a custom post type: "Vehicle"
$vehiclePostType = new PostType(
    'vehicle',       // post type slug
    'Vehicle',       // singular name
    'Vehicles',      // plural name
    [
        'menu_icon' => 'dashicons-car',
        'supports'  => ['title', 'thumbnail'],
    ]
);

// Register the post type with WordPress
$vehiclePostType->register();
```

This will make a new post type called “Vehicle” in the WordPress admin menu with a car dashicon and support for `title` and `thumbnail`.

### 2. Define Metadata Fields in a Settings Class

[](#2-define-metadata-fields-in-a-settings-class)

Next, create a subclass of `Settings` to define the custom fields (e.g., name, description, type, speed):

```
use Urisoft\PostMeta\Settings;

class VehicleSettings extends Settings
{
    /**
     * Override the settings() method to define your form fields.
     */
    public function settings(): void
    {
        // Simple text input
        $this->input('Vehicle Name', [
            'placeholder' => 'Enter the vehicle name',
        ]);

        // Textarea
        $this->textarea('Description');

        // Select dropdown (car, truck, motorcycle)
        $this->select('Type', [
            'car'        => 'Car',
            'truck'      => 'Truck',
            'motorcycle' => 'Motorcycle',
            'selected'   => $this->getMeta('type'), // set currently saved value as selected
        ]);

        // Number input
        $this->input('Top Speed (mph)', [
            'type'        => 'number',
            'placeholder' => 'Enter top speed in mph',
        ]);

        // Color field
        $this->input('Available Colors', [
            'type'        => 'color',
            'placeholder' => 'Choose a color',
        ]);
    }
}
```

Within these methods (`input`, `textarea`, `select`), the library handles rendering, sanitization, and labeling. You can further tailor data sanitization by overriding methods like `data()` or hooking into form submission processes.

### 3. Attach the Settings to a Meta Box

[](#3-attach-the-settings-to-a-meta-box)

Create a `MetaBox` instance, passing in your `VehicleSettings` object and any config options, then register it:

```
use Urisoft\PostMeta\MetaBox;

// Instantiate VehicleSettings for the "vehicle" post type
$vehicleSettings = new VehicleSettings('vehicle');

// Create a MetaBox for these settings
$vehicleMetaBox = new MetaBox($vehicleSettings, [
    'name'  => 'Vehicle Details', // The meta box title in the WP admin
    'zebra' => true,              // Zebra striping for table rows
]);

// Register the meta box so it appears in the edit screen
$vehicleMetaBox->register();
```

When editing a “Vehicle” post, you’ll now see a “Vehicle Details” meta box containing all defined fields.

### 4. Retrieving Metadata

[](#4-retrieving-metadata)

With the `Data` class, you can retrieve post data in one place:

```
use Urisoft\PostMeta\Data;

// Initialize a Data instance for "vehicle" post type
$vehicleData = Data::init('vehicle');

// Retrieve meta for a specific Vehicle post (ID=100)
$info = $vehicleData->meta(100);

// Access custom fields
echo 'Vehicle Name: ' . esc_html($info['vehicle_name']);
echo 'Top Speed: ' . esc_html($info['top_speed']) . ' mph';
```

Additionally, you can fetch a list of vehicles, generate edit links, or retrieve featured image IDs.

Advanced Usage
--------------

[](#advanced-usage)

### 1. Custom REST Endpoints

[](#1-custom-rest-endpoints)

If you’d like to expose a custom endpoint, the `PostType` class offers a helper method:

```
$vehiclePostType->addCustomRestEndpoint('/custom-details', function ($request) {
    // Do something with $request...
    return ['message' => 'Custom endpoint data!'];
}, 'GET');
```

Your custom endpoint will be available at `/{post_type}/v1/custom-details`.

### 2. Admin Columns

[](#2-admin-columns)

Add or modify admin columns for your post type:

```
$vehiclePostType->addAdminColumns(
    function ($columns) {
        $columns['type']  = 'Type';
        $columns['speed'] = 'Top Speed';
        return $columns;
    },
    function ($column, $post_id) {
        switch ($column) {
            case 'type':
                echo esc_html(get_post_meta($post_id, 'type', true));
                break;
            case 'speed':
                echo intval(get_post_meta($post_id, 'top_speed', true)) . ' mph';
                break;
        }
    }
);

// Make the "Top Speed" column sortable:
$vehiclePostType->addSortableColumns(['speed' => 'top_speed']);
```

### 3. Bulk Registration &amp; Autosave

[](#3-bulk-registration--autosave)

If you maintain multiple custom post types, you can bulk-register them. Or you can rely on the built-in autosave mechanism (by default, `MetaBox` hooks into `save_post_{$post_type}`).

### 4. Extensible Form Rendering

[](#4-extensible-form-rendering)

All fields are generated by the `Form` class, which you can override or extend for specialized needs (e.g., custom JavaScript fields, advanced validation, etc.).
Common methods include `input`, `textarea`, `select`, `editor`, and more.

Below are two examples demonstrating how to use the `urisoft/postmeta` package in a plugin context. Both examples register a custom post type called “Vehicle” and create a meta box for managing vehicle data in the WordPress admin.

---

Example 1: Step-by-Step Setup with PostType and MetaBox
-------------------------------------------------------

[](#example-1-step-by-step-setup-with-posttype-and-metabox)

 Click to expand code```
/**
 * Plugin Name: Vehicle Management
 */

use Urisoft\PostMeta\PostType;
use Urisoft\PostMeta\Settings;
use Urisoft\PostMeta\MetaBox;

// 1. Register the post type
$vehicle = new PostType('vehicle', 'Vehicle', 'Vehicles', [
    'menu_icon' => 'dashicons-car',
    'supports'  => ['title', 'thumbnail'],
]);
$vehicle->register();

// 2. Define settings fields
class VehicleSettings extends Settings
{
    public function settings()
    {
        $this->input('Vehicle Name');
        $this->textarea('Description');
        $this->select('Type', [
            'car'        => 'Car',
            'truck'      => 'Truck',
            'motorcycle' => 'Motorcycle',
            'selected'   => $this->getMeta('type'),
        ]);
        $this->input('Top Speed (mph)', ['type' => 'number']);
    }
}

// 3. Create a meta box for those settings
(new MetaBox(new VehicleSettings('vehicle'), [
    'name'  => 'Vehicle Details',
    'zebra' => true,
]))->register();
```

When you visit **Vehicles &gt; Add New** in the admin area, you’ll see a “Vehicle Details” meta box. Any data entered into these fields will automatically save to the post’s metadata.

Example 2: Helper Function (`createMeta`)
-----------------------------------------

[](#example-2-helper-function-createmeta)

 Click to expand code```
/**
 * Plugin Name: Vehicle Management
 */

use Urisoft\PostMeta\Settings;

// Define settings fields
class VehicleSettings extends Settings
{
    public function settings()
    {
        $this->input('Vehicle Name');
        $this->textarea('Description');
        $this->select('Type', [
            'car'        => 'Car',
            'truck'      => 'Truck',
            'motorcycle' => 'Motorcycle',
            'selected'   => $this->getMeta('type'),
        ]);
        $this->input('Top Speed (mph)', ['type' => 'number']);
    }
}

// Create the meta box
createMeta(new VehicleSettings('vehicle'), [
    'name' => 'Vehicle Details',
]);
```

> **Note**: The `createMeta` function will skip registering the “vehicle” post type if it already exists. If that’s the case, you only get the meta box for the existing post type.

Both approaches result in a “Vehicle Details” meta box when editing the “Vehicle” custom post type in your WordPress admin. Choose whichever method best suits your workflow.

Additional Tips
---------------

[](#additional-tips)

- **Naming Conventions**:
    By default, meta data may be stored in meta keys like `"{post_type}_cpm"` or a hashed field. Check your code or the `Settings` subclass to see how it’s configured.
- **Sanitization &amp; Validation**:
    Each field can be sanitized in the `data()` method of your `Settings` subclass. For advanced or non-textual fields (e.g., HTML fields, numeric ranges), override or extend the library’s defaults.
- **Compatibility**:
    The library requires at least PHP 7.4+ and a WordPress environment (version 4.0 or higher is recommended).
- **Documentation**:
    Inline PHPDoc comments are provided throughout the source code. You can also refer to WordPress’s official developer references for functions like `get_posts()`, `register_post_type()`, `wp_editor()`, etc.

The **`cpt-meta`** library offers a streamlined, powerful set of tools for building and maintaining custom post types in WordPress. By combining classes like `PostType`, `MetaBox`, `Settings`, `Form`, and `Data`, developers can organize complex metadata workflows with minimal boilerplate. Whether you’re setting up a single custom post type or crafting a fully-fledged content management system, `cpt-meta` aims to simplify the entire process—so you can focus on building great features.

For more advanced details on WordPress custom post types and metadata, refer to:

- [WordPress Custom Post Type](https://developer.wordpress.org/plugins/post-types/)
- [WordPress Custom Meta Boxes](https://developer.wordpress.org/plugins/metadata/custom-meta-boxes/)
- [WordPress REST API](https://developer.wordpress.org/rest-api/)

###  Health Score

37

—

LowBetter than 84% of packages

Maintenance45

Moderate activity, may be stable

Popularity25

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 93.3% 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.

###  Release Activity

Cadence

Every ~77 days

Total

19

Last Release

434d ago

PHP version history (4 changes)0.0.1PHP ^7.1

v0.3.0PHP ^7.1 || ^8.1

v0.4.1PHP ^7.1 || ^7.4 || ^8.0 || ^8.1

v0.5.0PHP ^7.4 || ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/8fd19f958b007ec6588d0a5ca2fe78e107edd652f286b836d36b5d1781d573a5?d=identicon)[devuri](/maintainers/devuri)

---

Top Contributors

[![devuri](https://avatars.githubusercontent.com/u/4777400?v=4)](https://github.com/devuri "devuri (126 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (9 commits)")

---

Tags

wordpresswordpress-developmentwordpress-plugin

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/devuri-cpt-meta-box/health.svg)

```
[![Health](https://phpackages.com/badges/devuri-cpt-meta-box/health.svg)](https://phpackages.com/packages/devuri-cpt-meta-box)
```

PHPackages © 2026

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